Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Модуль АЦП в pic12f1501

Вт июн 08, 2021 21:38:41

Суть устройства: на вход RA4 (из аналоговых AN3) поступает напряжение, в зависимости от режимов работы, в результате формируется импульс на выходе RA5 либо нет.

Режимы работы:
1) режим нормальной работы: напряжение на входе 9.5 В +делитель 1/7,2, должен формироваться импульс на выходе постоянно
2) режим аварии: напряжение от 13 до 22 В (всего три точки, 13, 17 и 22 В), импульса быть не должно.

По расчетам было забито изначально в функцию чтения АЦП значение для 12 В с делителем, которое равно 320, но на выходе ничего не формировалось вообще.

Со значением 140, которое в коде ниже программа работает но в обратном порядке и формирует импульс при режиме аварии. Может кто знает как инвертировать и в чем может быть проблема? С return и if все возможные перестановки делались, в итоге в двух режимах формировался импульс.

Если ошибка в расчетах, то где можно взять нормальную табличку напряжения, переведенного в значение АЦП?

Код:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>


#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = ON // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)

#define _XTAL_FREQ 16000000

int count = 0;

void mydelay_ms(unsigned int cycles) {
unsigned int i;

for (i = 1; i <= cycles; i++) {
__delay_ms(1);
}
}

unsigned int calc_v(void)
{
int result_adc;
unsigned long result_v;

result_adc = ((ADRESH « 2) | ADRESL);
return result_adc;
}

unsigned char read_adc( unsigned char ch)
{
unsigned int ADC = 0;

switch (ch)
{case 0:ADCON0=0b00000000; // ????? 0
break;
case 1:ADCON0=0b00000100; // ????? 1
break;
case 2:ADCON0=0b00001000; // ????? 2
break;
case 3:ADCON0=0b00001100; // ????? 3
break;
}
__delay_ms(1);
ADRESH = 0;
ADRESL = 0;
ADCON0bits.ADON = 1;
__delay_us(20);
ADCON0bits.GO = 1;
while (ADCON0bits.GO)
{
continue;
}
__delay_us(20);
ADC = calc_v();
if (ADC > 140)
{
return 1;
}
else
return 0;
}


void main(void)
{
OSCCONbits.IRCF = 0x0F; //set OSCCON IRCF bits to select OSC frequency=16Mhz
OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block
LATA = 0x00; // turn all outputs off
OPTION_REGbits.nWPUEN = 1; // all weak pullups are disabled
TRISAbits.TRISA0 = 1; // RA0 = nc (SPDAT)
TRISAbits.TRISA1 = 1; // RA0 = nc (SPCLK)
TRISAbits.TRISA2 = 1; // RA2 = Blue LED
//TRISAbits.TRISA3 = 1; // RA0 = nc (MLCR)
TRISAbits.TRISA4 = 1; // RA4 = nc
TRISAbits.TRISA5 = 0; // RA5 = nc

PORTA = 0;

ANSELA = 0b00010111;
ADCON1 = 0b11110000;
ADCON2 = 0;

while(1)
{
count = read_adc(3);
if (count == 0)
{
PORTA = 0;
mydelay_ms(100);
PORTA = 0x20;
mydelay_ms(25);
PORTA = 0;
}
while(count == 0)
{
PORTA = 0;
count = read_adc(3);
}
}
}
}

Re: Модуль АЦП в pic12f1501

Вт июн 08, 2021 23:24:13

Почему людям так сложно нормально отформатировать отступы?!

Код:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>


#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = ON // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)

#define _XTAL_FREQ 16000000

int count = 0;

void mydelay_ms(unsigned int cycles) {
  unsigned int i;

  for (= 1; i <= cycles; i++) {
    __delay_ms(1);
  }
}

unsigned int calc_v(void) {
  int result_adc;
  unsigned long result_v;

  result_adc = ((ADRESH« 2) | ADRESL);
  return result_adc;
}

unsigned char read_adc(unsigned char ch) {
  unsigned int ADC = 0;

  switch (ch) {
  case 0:
    ADCON0 = 0b00000000; // ????? 0
    break;
  case 1:
    ADCON0 = 0b00000100; // ????? 1
    break;
  case 2:
    ADCON0 = 0b00001000; // ????? 2
    break;
  case 3:
    ADCON0 = 0b00001100; // ????? 3
    break;
  }
  __delay_ms(1);
  ADRESH = 0;
  ADRESL = 0;
  ADCON0bits.ADON = 1;
  __delay_us(20);
  ADCON0bits.GO = 1;
  while (ADCON0bits.GO) {
    continue;
  }
  __delay_us(20);
  ADC = calc_v();
  if (ADC > 140) {
    return 1;
  } else
    return 0
;
}

void main(void) {
  OSCCONbits.IRCF = 0x0F; //set OSCCON IRCF bits to select OSC frequency=16Mhz
  OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block
  LATA = 0x00; // turn all outputs off
  OPTION_REGbits.nWPUEN = 1; // all weak pullups are disabled
  TRISAbits.TRISA0 = 1; // RA0 = nc (SPDAT)
  TRISAbits.TRISA1 = 1; // RA0 = nc (SPCLK)
  TRISAbits.TRISA2 = 1; // RA2 = Blue LED
  //TRISAbits.TRISA3 = 1; // RA0 = nc (MLCR)
  TRISAbits.TRISA4 = 1; // RA4 = nc
  TRISAbits.TRISA5 = 0; // RA5 = nc

  PORTA = 0;

  ANSELA = 0b00010111;
  ADCON1 = 0b11110000;
  ADCON2 = 0;

  while (1) {
    count = read_adc(3);
    if (count == 0) {
      PORTA = 0;
      mydelay_ms(100);
      PORTA = 0x20;
      mydelay_ms(25);
      PORTA = 0;
    }
    while (count == 0) {
      PORTA = 0;
      count = read_adc(3);
    }
  }
}
 


Сразу ведь удобнее читать. И лишняя скобка } видна в конце (которую я убрал сразу), ну да с ней бы и не собралось бы вовсе )

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 01:41:51

Bondosha писал(а):1) режим нормальной работы: напряжение на входе 9.5 В +делитель 1/7,2, должен формироваться импульс на выходе постоянно
2) режим аварии: напряжение от 13 до 22 В (всего три точки, 13, 17 и 22 В), импульса быть не должно.
Вы сами поняли, что тут написали ?
Расшифруйте ...

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 06:14:40

Аlex,
режим нормальной работы: на входе 9/7.2 В, на выходе формируем импульс, с периодом 125 мс
режим аварии: на входе 12/7.2 В и выше, на выходе должен быть 0

Теперь понятнее стало?

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 08:06:04

Теперь ...?

Это вообще что?
Код:
result_adc = ((ADRESH« 2) | ADRESL);

Может все таки:
Код:
result_adc = ((ADRESH« 8) | ADRESL);

ЗЫ. И какая кому разница какой делитель у вас в схеме и какие напряжения? Не надо писать мусорную информацию. Достаточно указать код АЦП.
Последний раз редактировалось КРАМ Ср июн 09, 2021 08:10:25, всего редактировалось 1 раз.

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 08:09:00

или даже
Код:

result_adc 
= ((ADRESH << 8) | ADRESL);
 


:)

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 08:31:39

КРАМ, а разве при правостороннем преобразовании результата не читаются как раз 2 бита старших, а не 8?

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 09:18:18

Bondosha, при выравнивании справа, у вас в вернем байте старшие 6 бит равны 0, в младшем байте все 8 на своих местах. Вам надо старший байт сдвинуть на 8 бит не чтобы "выровнять", а чтобы получить 16-битное общее значение.

Re: Модуль АЦП в pic12f1501

Ср июн 09, 2021 10:09:23

NStorm, все равно при 1.6 В и выше на входе (как при обрыве) формирует импульс постоянно

Re: Модуль АЦП в pic12f1501

Чт июн 10, 2021 13:49:41

Все заработало, спасибо всем поучаствовавшим.
Ответить