Александр1, мне казалось, что даже если превысить, то АЦП должно было вывести максимальное свое значение.
Прошу прощения за неточность, сразу как то не доглядел.
АЦП выводит мне это значение при подаче абсолютно любого значения поданного на его вход, даже если 0. То есть число в районе 2700, и периодически плавает плюс минус несколько единиц.
Приведу код, возможно у кого будет время и желание глянуть:
CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#define ENABLE_BIT_DEFINITIONS
#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)
unsigned char i,cnt,y;
long int DataADC;
volatile int Voltage = 0x00;
// Настройка на работу от внешнего кварца в 4 МГц
void ClockExt4MHz()
{
OSC.XOSCCTRL = 0x4B;
OSC.CTRL = 0x08;
while((OSC.STATUS & 0x08) == 0);
OSC_PLLCTRL = 0xC1;
OSC_CTRL = OSC_CTRL | 0x10;
while((OSC_STATUS & 0x10) == 0 );
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_XOSC_gc;
OSC_CTRL = OSC_CTRL & 0xFE;
}
// UART для связи на 9600 bod для 4 МГц
void StartUsartD1()
{
USARTD1_CTRLC= USART_CHSIZE0_bm | USART_CHSIZE1_bm;
USARTD1_BAUDCTRLB = 0;
USARTD1_BAUDCTRLA = 0x19;
USARTD1_CTRLB = USART_TXEN_bm | USART_RXEN_bm;
USARTD1_CTRLA=USART_RXCINTLVL0_bm;
PORTD_OUTSET = PIN7_bm;
PORTD_DIRSET = PIN7_bm;
PORTD_OUTCLR = PIN6_bm;
PORTD_DIRCLR = PIN6_bm;
}
// Функция получения данных
char getChar1(void)
{
while(1){
char buffer1;
buffer1=USARTD1_DATA;
if ((USARTD1_STATUS & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm))==0)
return buffer1;
}
}
// Функция передачи данных
void sendChar1(char d1)
{
while( !(USARTD1_STATUS & USART_DREIF_bm) );
USARTD1_DATA = d1;
while( !(USARTD1_STATUS & USART_TXCIF_bm) );
}
// Прерывание по получению данных с UART
ISR(USARTD1_RXC_vect)
{
PORTA.OUTTGL =0x20;
DataADC = ADCA.CH0RES;
cnt = getChar1();
if (cnt != 0) {
if (cnt == 0x4F)
{
sendChar1(HI(DataADC));
sendChar1(LO(DataADC));
}
else for (i=0;i<5;i++) sendChar1(0x55);
}
cnt = 0;
}
// Функция инициализации АЦП
void ADC_init()
{
ADCA.CAL=0xff; // Значение для калибровки АЦП
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; // 12 бит дескретизация
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | 0x02; // Опорное напряжение 1 В.
ADCA.PRESCALER =ADC_PRESCALER_DIV512_gc; // Переферийная частота работы АЦП
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; // CH0 настроен на внешний нессимметричный вход
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc; // Настраиваем как положительный вывод порта для АЦП
ADCA.CTRLA = ADC_ENABLE_bm; // Активирую АЦП
ADCA.CTRLB|=(1<<3); // старт автоматического преобразования АЦП
}
// Функция инициализации ЦАП
void DAC_init()
{
DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc;
DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_SINGLE_gc;
PORTB.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc;
DACB.CTRLA = DAC_CH0EN_bm | DAC_ENABLE_bm;
}
// Функция выдачи напряжения с ЦАП
void DACB_out(int Voltage)
{
DACB.CH0DATA = Voltage;
while (!DACB.STATUS & DAC_CH0DRE_bm);
}
int main(void)
{
ClockExt4MHz();
PORTA.DIR = 0x20;
PORTC.DIR = 0x02;
StartUsartD1();
ADC_init();
DAC_init();
DACB_out(Voltage);
PORTD.PIN4CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_FALLING_gc;
sei();
PMIC.CTRL|=PMIC_HILVLEN_bm|PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm;
while (1)
{
asm("NOP");
}
}
По задумке должен получать значение АЦП по UART. Напряжение выставляю с помощью ЦАПа.
Еще заметил, что при изменении регистра
ADCA.PRESCALER =ADC_PRESCALER_DIV512_gc; почему то изменяется получаемое значение с АЦП, то есть изменил скорость преобразование, и значение АЦП изменилось где то на 200 единиц при том же напряжении.
Или же буду рад хотя бы рабочему примеру работы с АЦП для этого контроллера.