|
|
  |
Atmega8: АЦП мереет то чего нет. |
|
|
|
Apr 29 2008, 04:40
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Имеем AtMega8 с подключеными на ADC0,ADC1,ADC2 сигналами. Но измерения мягко говоря странные. ADC0 и ADC2 "близки к нолю", т.е. по сути там делитель "вход" которого "висит" в воздухе. На ADC1 есть напряжение около 3х вольт. Результат измерения получается 4, 805, 800 (ну +-3 от раза к разу). Ну 4 ладно, это 0,018 вольта, 805 тоже понимаю это где-то 3.8В, но от куда 800? Стою осцилографом на этой шожке и ничего не вижу, а измерение есть... В коде измеряем значения следующим образом: Код #include <avr/io.h> #define AD_CNT 3 #define AD_CLC 5 volatile uint16_t ADBuf[AD_CNT][AD_CLC]; volatile uint16_t ADSum[AD_CNT]; volatile uint8_t src=0,ad_calc=0;
void init_adc(void) { uint8_t i,j; for (i=0;i<AD_CNT;i++) { for (j=0;j<AD_CLC;j++) ADBuf[i][j] = 0; ADSum[i] = 0; } ADCH = 0; ADCL = 0; ADMUX = _BV(REFS0); ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADSC); }
int main(void) { PORTC = 0; DDRC = 0;
....
init_adc();
....
while(1) { if (bit_is_clear(ADCSRA,ADSC)) { uint16_t ADres=ADC;
ADSum[src] -= ADBuf[src][ad_calc]; ADBuf[src][ad_calc] = ADres; // Place new value into Buffer ADSum[src] += ADres;
ad_calc++; ad_calc%=AD_CLC; if (!ad_calc) { src++; src%=AD_CNT; ADMUX = _BV(REFS0) | src; } ADCSRA |= _BV(ADSC); } .... } }
|
|
|
|
|
Apr 29 2008, 10:31
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Alexey Belyaev @ Apr 29 2008, 11:11)  Попробуйте мой код, в чужом разбираться лень  Сервис вставьте в цикл, на а инициализацию - в старт-ап. Код #define adcExtPow 6 #define adcEnter 5 #define adcUp 4 #define adcDn 3 #define adcEsc 2
#define ADCoff ADCSR=0
unsigned int adc_values[7]; unsigned char adc_channel; unsigned char adc_ready=0;
void InternalAdcInit(void) { ADCSRA = (1 << ADEN) | //ADC ON, // ADSC not start conversion // ADATE auto trigger disable (1 << ADIF) | // clear conversion flag writing 1 to it // ADIE interrupt disable (1 << ADPS2) | //prescaler =64 (ADPS2=1, ADPS1=1, ADPS0=0) (1 << ADPS1) | // ADPS0 0;
ADMUX = //REFS1 | (1 << REFS0) | // REFerence = AVCC with C on pin Vref (REFS1=0, REFS0=1) // (1 << ADLAR) | // left adjust results - read high byte only 0; }
#define SetAdcChannel(mux) ADMUX = (0xE0 & ADMUX) | (mux) #define StartAdcConversion() ADCSRA |= (1 << ADIF) | (1 << ADSC) #define AdcConversionComplete (!(ADCSRA & (1 << ADSC)))
void InternalAdcService(void) { static char adc_status; char my_adcl;
switch (adc_status) { case 0: InternalAdcInit(); SetAdcChannel(adc_channel = 0); StartAdcConversion(); adc_status = 1; break; case 1: if (AdcConversionComplete) { my_adcl=ADCL; adc_values[adc_channel] = (ADCH<<8) + my_adcl; if (++adc_channel >= COUNT_ELEMENTS(adc_values)) { adc_channel = 0; adc_ready = 1; } SetAdcChannel(adc_channel); StartAdcConversion(); } break; default: adc_status = 0; } } Ой, забыл, у меня Mega32. Даже не знаю, есть ли отличия.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Apr 30 2008, 06:05
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(Tolyaha @ Apr 29 2008, 18:14)  А на AVcc питание подано? Конечно! Цитата(bloodden @ Apr 29 2008, 18:08)  Подтяжка висит. И ещё: там с фузами есть нюанс, только непомню какой и или в м8 или м16. Эм.. А подтяжка не к земле ли? или речь о внутренней? Так ведь DDRC=0 Фьюзов связанных с ACP не обнаружил.
|
|
|
|
|
Apr 30 2008, 20:08
|
Участник

Группа: Новичок
Сообщений: 17
Регистрация: 2-02-07
Пользователь №: 24 993

|
Оказывается, это написано в datasheet. Для ATmega8 с. 62, Table 27. Overriding Signals for Alternate Functions in PC3..PC0. Там везде ноли. Это означает, что входы АЦП по-прежнему контролируются регистрами DDRC, PORTC. Просто к выводам ещё и АЦП подключен. То есть сначала нужно выставить вход без pull-up резистора. P.S. И самому полезно узнать... Посмотрев в первоначальный код, так и стоит PORTC = 0; DDRC = 0; Так что не в том дело
|
|
|
|
|
May 2 2008, 05:57
|

Местный
  
Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947

|
Цитата(Elegorod @ May 1 2008, 00:08)  Это означает, что входы АЦП по-прежнему контролируются регистрами DDRC, PORTC. Просто к выводам ещё и АЦП подключен. Во как.... Не знал... Спасибо за инфу
--------------------
После устранения бага в программе она стала работать....хуже
|
|
|
|
|
May 5 2008, 05:37
|
Частый гость
 
Группа: Свой
Сообщений: 116
Регистрация: 2-03-07
Из: Украина
Пользователь №: 25 826

|
Цитата(Alexey Belyaev @ Apr 30 2008, 15:11)  Близко к тому. А как быть?  кондер на ентот пин и общий повесить ( на ADC2). При этом если нужна скорость - контроллировать постоянную времени RC (задержка фильтра), где R - сопротивление подключаемой измерительной цепи, а C - рекомендуемый кондер, при этом считайте что емкость входа не менее 40 пф.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|