Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » STM32 & STM8 » Вопросы » Повышающий преобразователь. stm8s.


Повышающий преобразователь. stm8s.

Сообщений 1 страница 8 из 8

1

http://s3.uploads.ru/t/BVxSw.png
питание от аккумулятора литий-ион. от 2,5 В до 4,2 В. Шим подается на Q6. без драйверов. Прекрасно работает. Еще бы выход осцилом глянуть. Но нема.
Вопрос касабельно выхода преобразователя. Что -там? Вольтметр показывает 5,05 ну и скачет чуть на сотых вольта. Временами и десятые скакнут. Чуть чуть...
ШИМ в лоб.

Код:
  for(;;)
  {
    PIN_PWM = 1;
    asm("NOP");
    PIN_PWM = 0;
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }

Отредактировано RA (2018-05-06 00:35:33)

2

Перевел ШИМ из "в лоб" на таймер. Работает. Мк не дохнет. Буду считать, что на выходе то, что вижу вольтметром... Шучу... Буду мониторить ацп и Analog Watchdog. Аккумулятору будет ограничение... 3,0 - 4,2 вольта... 1мкС выборка.... Целый МегаГерщище. :) ШИМ 1,5Мгц. Иголки не увижу увидел, и заряд разряд ак. будет как на ладони... + время надо... мля...

Отредактировано RA (2018-05-08 01:05:18)

3

Возникли трудности в отладке. Опрашиваю ацп по нескольким каналам. по одному из каналов бред. результат в регистрах ацп один, а забираю другой.  :angry: http://s5.uploads.ru/t/gZVJn.png
где в iar посмотреть как компилятор расположил union?

Отредактировано RA (2018-05-08 15:20:55)

4

Ни к чему мои потуги с union не привели. В регистрах одно значение, забирается другое. Сделал проще. Классически так сказать.

Код:
/*..............................................................................*/
/*..............................................................................*/
/*..............................................................................*/
#pragma vector = ADC1_EOC_vector
/*..............................................................................*/
/*..............................................................................*/
/*..............................................................................*/
__interrupt void ADC1_EOC_handler(void)
{
  if (( ADC_CSR_bit.EOC == 1 ) && ( ADC_CSR_bit.EOCIE == 1 ))//если преобразование завршено и прерывание разрешенно
  {
    ADC_CSR_bit.EOC = 0;
    switch( ADC_CSR_bit.CH )
    {
    case channal_2:
      vdd = ADC_DRH<<8;
      vdd = ADC_DRL;
      vdd = vdd*2;
      ADC_CSR_bit.CH = channal_5;
      break;
      case channal_5:
        vhodnoe = ADC_DRH<<8;
        vhodnoe = ADC_DRL;
        vhodnoe = vhodnoe*2;
        ADC_CSR_bit.CH = channal_6;
        break;
        case channal_6:
          opornoe = ADC_DRH<<8;
          opornoe = ADC_DRL;
          ADC_CSR_bit.CH = channal_2;
          break;
    }
  ADC_CR1_bit.ADON = 1;//запускаю преобразование
  }
}

Ошибочка есть в этом коде. Для тех "шарит" она видна сразу. |=

Отредактировано RA (2018-05-09 21:42:48)

5

Зная опорное( в вольтах ) и имея замер( показания ацп ) опорного, можно получить напряжение питания мк, один канал освобождается. а с учетом аппаратного деления можно хоть float-ми считать.

Код:
Vdd=(1023*1.2)/(float)(read_ad());

Отредактировано RA (2018-05-14 00:14:07)

6

есть вот такое...

Код:
unsigned int read_ad(){
  unsigned int buff=0;
  unsigned int buf0=0;
  unsigned int buf1=0;
  unsigned int buf2=0;
  unsigned int buf3=0;
  unsigned int buf4=0;
  unsigned int buf5=0;
  unsigned int buf6=0;
  unsigned int buf7=0;
  unsigned int buf8=0;
  unsigned int buf9=0;
  buf0 = ADC_DB0RH<<8;
  buf0 = buf0 + ADC_DB0RL;
  buf1 = ADC_DB1RH<<8;
  buf1 = buf1 + ADC_DB1RL;
  buf2 = ADC_DB2RH<<8;
  buf2 = buf2 + ADC_DB2RL;
  buf3 = ADC_DB3RH<<8;
  buf3 = buf3 + ADC_DB3RL;
  buf4 = ADC_DB4RH<<8;
  buf4 = buf4 + ADC_DB4RL;
  buf5 = ADC_DB5RH<<8;
  buf5 = buf5 + ADC_DB5RL;
  buf6 = ADC_DB6RH<<8;
  buf6 = buf6 + ADC_DB6RL;
  buf7 = ADC_DB7RH<<8;
  buf7 = buf7 + ADC_DB7RL;
  buf8 = ADC_DB8RH<<8;
  buf8 = buf8 + ADC_DB8RL;
  buf9 = ADC_DB9RH<<8;
  buf9 = buf9 + ADC_DB9RL;
  buff = (buf0+buf1+buf2+buf3+buf4+buf5+buf6+buf7+buf8+buf9)/10;
  return buff;
}

как поизящней забрать сумму 10-ти буферов и разделить на 10? знаю можно с двумя переменными, но это - все не то.

7

Выравнивание результата ацп сделал левым, откинул два младших бита. получил ...

Код:
unsigned int read_ad(){
  unsigned int buff;
  buff = ADC_DB0RH;
  buff = buff+ADC_DB1RH;
  buff = buff+ADC_DB2RH;
  buff = buff+ADC_DB3RH;
  buff = buff+ADC_DB4RH;
  buff = buff+ADC_DB5RH;
  buff = buff+ADC_DB6RH;
  buff = buff+ADC_DB7RH;
  buff = buff+ADC_DB8RH;
  buff = buff+ADC_DB9RH;
  buff = buff/10;
  return buff;
}

пока лучше и быстрее не получилось.
обнаружение подключенного усб и контроль заряда весь ушел прерывание.

Код:
#define Vop 1.2 // ОПОРНОЕ НАПРИЖЕНИЕ ПО 6 КАНАЛУ В ВОЛЬТАХ 
#define channal_2 2    ///выход преобразователя. (при не активном режиме работы ШИМ - входное минус падение на катушке и диоде.)
#define channal_3 3 //переменник. 4,7 кОм.
#define channal_5 5 //входное
#define channal_6 6    /// опорник 
#define max_l 100 // максимальное значение в см.
#define w_ad 255 // разрядность ацп 8бит 255 10бит 1023
#define V_lion_h 4.1
#define V_lion_nom 3.9
/*..............................................................................*/
/*..............................................................................*/
/*..............................................................................*/
#pragma vector = ADC1_EOC_vector
/*..............................................................................*/
/*..............................................................................*/
/*..............................................................................*/
__interrupt void ADC1_EOC_handler(void)
{
  if (( ADC_CSR_bit.EOC == 1 ) && ( ADC_CSR_bit.EOCIE == 1 ))//если преобразование завршено и прерывание разрешенно
  {
    ADC_CR1_bit.ADON = 0;
    switch( ADC_CSR_bit.CH ){
    case channal_2:
      out=(Vdd/w_ad)*(float)(read_ad())*2;
      ADC_CSR_bit.CH = channal_3;
      break;
    case channal_3:
      res = read_ad();
      l=(float)(res)*max_l/w_ad;
      ADC_CSR_bit.CH = channal_5;
      break;
    case channal_5:
      in=(Vdd/w_ad)*(float)(read_ad())*2;
      if( PIN_USB == 1 ){
        if( in < V_lion_nom ){
          led_green = 1;
          led_blue = 0;
          USB_SWITCH = 0;//заряд идет
        } 
        if( in > V_lion_h ){ 
          led_green = 0;
          led_blue = 0;
          USB_SWITCH = 1;//заряд выкл
        }
      }
      if( PIN_USB == 0 ){
        if( in > V_lion_nom ){
          led_green = 0;
          led_blue = 0;
        }
        else{
          led_green = 0;
          led_blue = 1;
        }
      }
      ADC_CSR_bit.CH = channal_6;
      break;
    case channal_6:
      Vdd=(w_ad*Vop)/(float)(read_ad());
      ADC_CSR_bit.CH = channal_2;
      break; 
    }
    ADC_CSR_bit.EOC = 0;
    ADC_CR1_bit.ADON = 1;
    ADC_CR1_bit.ADON = 1;
  }
}

теперь переезд на КАЗ, придется  буферизацию выключать.

Отредактировано RA (2018-05-16 21:37:07)

8

КАЗ это интересно... но на него можно повесить только уход в ожидающий режим, либо полный стоп при разряде аккумулятора ниже 3 вольт.
Горит транзюк шима. Скорее всего драйвера не хватает, а его на питание 3-5В нет доступных. Попробую другой транзюк подобрать, что-то типо IRLML6244. Может он будет нормально открываться закрываться при питании от 3-5В. + попробовать резюк небольшой поставить последовательно с индуктивностью, а на диод забирать с индуктивности. КПД упадет, да и ... с ним.
float-ми считать на нем нет резона, при опросе трех каналов на максимальной частоте ацп, в цикл мэйна не попадаю, естественно после запуска ацп.

Отредактировано RA (Вчера 17:06:28)


Вы здесь » Микроконтроллеры » STM32 & STM8 » Вопросы » Повышающий преобразователь. stm8s.