Страница 1 из 2

АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 14:10:42
st_silver
Делаю импульсный источник питания с индикацией напряжения на нагрузке. Решил систему управления собрать на Atmega8, ШИМ уже настроил всё работает замечательно! Уперся как баран в работу АЦП, дадашит перечитал раз двести не получается понять почему не выводит вольтаж на LCD.
Ниже код:

Код: Выделить всё

#include <mega8.h>
#include <stdio.h>
#include <delay.h>
#include <lcd.h>

#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm

#define ADC_VREF_TYPE 0xC0

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

unsigned int n;
char lcd_buffer[33];

void main(void)
{
PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0xFF;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: Int., cap. on AREF
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x86;

// LCD module initialization
lcd_init(16);

while (1)
      {
       n=read_adc(ADCW);
       sprintf(lcd_buffer,"V=%i",n);
       lcd_clear();
       lcd_puts(lcd_buffer);       
       delay_ms(50);
      };
}

По идее функция read_adc и вытаскивает результат преобразования, если флаг ADIF полнят...
на ножке AREF кондёр на 1 мкФ, входной сигнал идёт на ножку ADC0.
Протеус уперто показывает на LCD "V=0" независимо от того какое напряжение на входе!.. уже второй день пытаюсь разобраться, может подскажите где я ошибаюсь!

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 14:45:14
phenomen
Функция read_adc(х) считивает значение с входа АЦП номер х, в вашем случае read_adc(0) (для компилятора CVAvr)!

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 14:49:43
st_silver
То есть, чтобы записать значение приходящее на нулевую ножку, необходимо указать n=read_adc(0);?

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 14:52:31
phenomen
Да, именно так

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 14:54:45
st_silver
Хм, странно, все равно выдает "V=0" на LCD...

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:08:05
phenomen
А пины AVCC и AREF подтянуты к + питания?

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:11:27
st_silver
А зачем, там же в режиме указано, внутренний опорник и кондёр на AREF

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:25:06
phenomen
AVCC, помоему, в любом случае должен бить запитан.

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:28:46
st_silver
не, все равно не работает! Блин кусок кода работающего было бы вообще замечательно, но никто блин на LCD не делает, по крайней мере я в инете не видел!

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:37:47
phenomen
У меня работает, правда с кондером результаты плохие (никогда не пробывал), но вот во втором случае все ок.
Использую PROTEUS 7.7 и CVAvr 2.04.8b
ADC.rar
Для ADC #define ADC_VREF_TYPE 0xC0
Для ADC1 #define ADC_VREF_TYPE 0x00
(88.76 КБ) 298 скачиваний

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 15:51:49
st_silver
О все заработало, спасибо большое! Я так понял это схемка от внешнего опорника?

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 16:03:35
phenomen
Именно так.
ЗЫ в даташите к меге8 пишет
AVCC must not differ more than ±0.3V from VCC

И по твоей схеме
Internal reference voltages of nominally 2.56V or AVCC are provided On-chip. The voltage reference
may be externally decoupled at the AREF pin by a capacitor for better noise performance.

Тоесть, касаясь первой схемы (ADC), работало верно, хотя я не уверен в правильности схемотехники :roll:

Re: АЦП Atmega8 вопрос!

Добавлено: Пт дек 17, 2010 16:44:32
st_silver
Ну я уже решил с внешним сделать, там шаг будет больше на каждую единицу)

Re: АЦП Atmega8 вопрос!

Добавлено: Сб янв 08, 2011 01:05:35
КАО
МяяУ! Здравствуйте всем. Чтобы не создавать новую тему, задам свой вопрос здесь. Как вывести
вольтаж с дробной частью?

Re: АЦП Atmega8 вопрос!

Добавлено: Сб янв 08, 2011 01:15:05
phenomen
по простой формуле: ("опорное напряжение"/(2^"количество разрядов"))*"показания АЦП" в переменную типа float используя printf или свои функции для получения "форматированых" результатов.

Пример:
Опорное напряжение - 5В
МК Атмега8, разрядность - 10
Показания АЦП - 315
Результат: (5/1024)*315=1,5380859375 Вольта

Вместо ("опорное напряжение"/(2^"количество разрядов")) задать константу типа

Код: Выделить всё

#define ADCMULT 0,0048828125
для тех же 5В и 10 разрядов

Re: АЦП Atmega8 вопрос!

Добавлено: Сб янв 08, 2011 13:08:19
КАО
Ещё вопрос. напишите, пожалуйста кусок кода, в котором дробное значение выводится на экран ЖКИ. :)

Re: АЦП Atmega8 вопрос!

Добавлено: Вс янв 09, 2011 14:03:25
phenomen

Код: Выделить всё

char lcd_buffer[33];
float ADCVAL;
...
       ADCVAL=read_adc(0);     
       ADCVAL=ADCVAL*ADCMULT;
       sprintf(lcd_buffer,"V=%d,%d",(int)ADCVAL,(int)(ADCVAL*100)%100);
       lcd_clear();
       lcd_puts(lcd_buffer);
       delay_ms(50);


В протеусе

Код: Выделить всё

sprintf(lcd_buffer,"V=%f",ADCVAL);
не восприняло, вышел из ситуации таким способом :)

Re: АЦП Atmega8 вопрос!

Добавлено: Вс янв 09, 2011 19:51:09
КАО

Код: Выделить всё

sprintf(lcd_buffer,"V=%f",ADCVAL);


также не получилось :( Спасибо за код!

Re: АЦП Atmega8 вопрос!

Добавлено: Вс янв 23, 2011 17:25:12
phenomen
Прошу прощения, нужно исправить:
phenomen писал(а):char lcd_buffer[33];
float ADCVAL;
...
       ADCVAL=read_adc(0);
       ADCVAL=ADCVAL*ADCMULT;
       sprintf(lcd_buffer,"V=%d,%02d",(int)ADCVAL,(int)(ADCVAL*100)%100);
       lcd_clear();
       lcd_puts(lcd_buffer);
       delay_ms(50);

Re: АЦП Atmega8 вопрос!

Добавлено: Пн янв 24, 2011 21:49:56
КАО

Код: Выделить всё

sprintf(lcd_buffer,"V=%d,%02d",(int)ADCVAL,(int)(ADCVAL*100)%100);


поясните строчку, очень прошу. Больно не пинать. 8)