Как измерить напряжение питания PIC через FVR и замер ADC.

Zombie47

✩✩✩✩✩✩✩
20 Апр 2023
13
0
Не знаю много ли тут людей кто программирует на PIC. Мне нужно замерять АЦП на ноге, и плюс замерять замерять FVR. (чтоб узнать напряжение питания МК)
По отдельности получается замерять и то и то.
А вот вместе не получается. Ну естественно я пытаюсь по очереди замерять, конфигурируя.
Микроконтроллер PIC16F1847
Я уже как только не пробовал, но где то косячу. При попытке замера по очереди, один сигнал влияет на другой причем очень сильно.
Напряжение питания МК 5.0в (для теста)
По отдельности например вот так:
FVR 2.048в = ADC 415
мультиметром на ноге RA4 3.950в = ADC 800.

Если ничего не меняю физически но включаю замер по очереди то:
FVR 2.048в = ADC 685
мультиметром на ноге RA4 3.950в = ADC 640.

Код (без лишнего) на данный момент выглядит так:
C:
 unsigned int read_adc (){//функция чтения ацп
  int tmp;
            CHS4_bit=0;  //этими битами выбираю канал. page 143
            CHS3_bit=0;
            CHS2_bit=1;
            CHS1_bit=0;
            CHS0_bit=0;
            /*
            00000 = AN0
            00001 = AN1
            00010 = AN2
            00011 = AN3
            00100 = AN4
            00101 = AN5
            00110 = AN6
            00111 = AN7
            01000 = AN8
            01001 = AN9
            01010 = AN10
            01011 = AN11
            01100 = Reserved. No channel connected.
           
            11100 = Reserved. No channel connected.
            11101 = Temperature Indicator
            11110 = DAC output(1)
            11111 = FVR (Fixed Voltage Reference) Buffer 1 Output(2)
            */

            ADON_bit=1; //включаю ацп
            ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале
           while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
           tmp = (unsigned int)ADRESH << 8; //верхний регистр приводим к инту и сдвигаем влево на 8 бит так как это верхний регистр
           tmp |= ADRESL;//нижний регистр склеиваю
       
            ADON_bit=0; //вырубаю  ацп
           
            CHS4_bit=1;  //этими битами выбираю канал. page 143
            CHS3_bit=1;
            CHS2_bit=1;
            CHS1_bit=0;
            CHS0_bit=0;
  return tmp;
  }

  unsigned int read_fvr (){//функция чтения fvr
  int tmp_fvr;
            ADFVR1_bit=1;
            ADFVR0_bit=0;
            FVREN_bit=1;
            CHS4_bit=1;  //этими битами выбираю канал. page 143
            CHS3_bit=1;
            CHS2_bit=1;
            CHS1_bit=1;
            CHS0_bit=1;

            ADON_bit=1; //запускаю работу ацп
            ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале

           while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
         
           tmp_fvr = (unsigned int)ADRESH << 8; //верхний регистр
           tmp_fvr |= ADRESL;//нижний регистр склеиваю
         
           ADON_bit=0; //вырубаю  ацп
           TRISA4_bit=1;//RA4 на вход
           ANSA4_bit=1;//аналоговый пин
           FVREN_bit=0; //пробую выррубать FVR
           ADFVR1_bit=0; //пробую вырубать буфер FVR
           ADFVR0_bit=0;
    return tmp_fvr;
  }

void main() {
    while (1) {//основной цикл
    adc=read_adc();
    fvr=read_fvr();
      }
}
Ну и вот блок схема ADC моего мк:
1683415311097.png
 

Zombie47

✩✩✩✩✩✩✩
20 Апр 2023
13
0
Умная мысля приходит напосля. К сожалению пока не изложишь вопрос на форуме, мой мозг не структурирует информацию, а вот как изложишь, так нахожу решение.
В общем я точно не понял в чем было дело, но решил не умничать с каждым битом отдельно, а целиком весь регистр настраивал. Предположительно тут последовательность конфигурирования и обязательная задержка.
В общем вот с этим кодом работает как надо:

C:
unsigned int read_adc (){//функция чтения ацп
  int tmp;
           ADCON0=0b00010011; //даташит page 143 ниже описание:
           //7 read as 0
           //6-2bit=00100 (канал для АЦП RA4)
           //1bit=0 (GO/DONE как я понял это что вроде флага, в процессе АЦП или нет )
           //0bit=0 (ADON этот бит запускает работу ацп.)
          
            Delay_ms(1);//обязательна без нее не работает
            ADON_bit=1; //еще раз включаю ацп после задержки
            ADGO_bit=1; //этим битом запускаю замер  ацп на выбранном канале
          
           while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
           tmp = (unsigned int)ADRESH << 8; //верхний регистр приводим к инту и сдвигаем влево на 8 бит так как это верхний регистр
           tmp |= ADRESL;//нижний регистр склеиваю
           ADCON0=0b01111111; //переконфигурирую под замер FVR
          return tmp;
  }
 
  unsigned int read_fvr (){//функция чтения ацп fvr
  int tmp_fvr;
           FVRCON = 0b11000010; //конфигурирую и включаю FVR page 133
          //bit 7 FVREN: 1 = Fixed Voltage Reference is enabled
          //bit 6 FVRRDY: 1 = Fixed Voltage Reference output is ready for use
          //bit 5 TSEN: 0 = Temperature Indicator is disabled
          //bit 4 TSRNG: 0 =VOUT = VDD - 2VT (Low Range)
          //bit 3-2 CDAFVR<1:0>: 00 = Comparator FVR Buffer is off
          //bit 1-0 ADFVR<1:0>: 10 = ADC FVR Buffer Gain is 2x, with output VADFVR = 2x VFVR(4)
            ADCON0=0b01111111; //обязательно еще раз конфигурирую ацп даташит page 143 ниже описание:
           //7 read as 0
           //6-2bit=00100 (канал для АЦП RA4)
           //1bit=0 (GO/DONE как я понял это что вроде флага, в процессе АЦП или нет )
           //0bit=0 (ADON этот бит запускает работу ацп.)

           while (GO_bit){}; // если ацп работает и снимает показания то ниче не делаем  висим тут.
           tmp_fvr = (unsigned int)ADRESH << 8; //верхний регистр
           tmp_fvr |= ADRESL;//нижний регистр склеиваю
           FVRCON = 0b00000000; //выключаю FVR page 133
           ADCON0=0b00010000; //переконфигурирую под ацп даташит page 143 ниже описание:
    return tmp_fvr;
  }
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,415
978
58
Марий-Эл
Умная мысля приходит напосля. К сожалению пока не изложишь вопрос на форуме, мой мозг не структурирует информацию, а вот как изложишь, так нахожу решение.
Эффект утки.
Ставишь перед собой фигурку утки и начинаешь ей рассказывать о чём думаешь как можно подробнее. Постепенно находишь решение.
Я PIC лет 5 назад бросил. Неинтересные они.
 

Zombie47

✩✩✩✩✩✩✩
20 Апр 2023
13
0
@Эдуард Анисимов, ну вот у меня уткой форумы являются, ну или кто то в личке.
Я не могу забросить PIC , все пытаюсь с него перейти, но завязан на проекты)))
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,415
978
58
Марий-Эл
Пока всё не закрыто, пробуйте STM потом будем переходить на GD. То же неплохой вариант.
Как раз с ними переговоры веду о предоставлении более полной информации.
И с Китайского переводить легче. У них построение предложений почти как у нас. И русскоговорящих у них много.