2015-08-25 3 views
0

Я пытаюсь прочитать уровень напряжения через ADC0 моего ATmega8, из-за запроса 1-контактной клавиатуры 4x4 Matrix. Проблема заключается в том, что каждый раз, когда я применяю напряжение на АЦП выше GND, Atmega останавливается, чтобы выполнить свою работу. Выходы PWM все еще работают, но связь через i2c невозможна, и ЖК-дисплей прозрачный. Моя проводка проста, AREF & AVCC установлены на 5 В, GND устанавливается на GND, а PC0 - на мой вход. Есть ли что-нибудь, чего я не могу заметить? Спасибо за помощь. Вот мой код:Вход AVR Atmega8 ADC вызывает Crash

void Initialisierung(void) 
{ 
char text [2]; 
lcd_init(); 
cli(); 
//### TWI 
init_twi_slave(SLAVE_ADRESSE);   //TWI als Slave mit Adresse slaveadr starten 
sei(); 
lcd_setcursor(0, 1); 
lcd_string(">Booting..."); 
lcd_setcursor(0, 2); 
    itoa (SLAVE_ADRESSE,text,16); 
lcd_string("I2C Adress=0x"); 
    lcd_string(text); 
    for (int Index=0; Index<85; ++Index) { 
     rxbuffer[Index] = 0x20; 
    } 
    rxbuffer[81]=0xFF; 
    rxbuffer[82]=0xFF; 
    rxbuffer[83]=0xFF; 
    rxbuffer[84]=0xFF; 
} 
//update LCD 
void lcd_update(void){ 
for (int o=1;o<=4; o++) 
for (int i=1; i<=20; i++){ 
    lcd_setcursor(i-1, o); 
    lcd_data(rxbuffer[i+((o-1)*20)]); 
} 
} 

здесь является основной функцией:

int main(void) 
{ 
DDRC &= ~(1 << PC0); 
PORTC &= ~(1 << PC0); 
Initialisierung(); 
DDRB = (1 << DDB1) | (1 << DDB2); 
OCR1A = eeprom_read_word(&brightness); // PWM einstellen, 
OCR1B = eeprom_read_word(&contrast); 
ICR1 = 1000; // TOP-wert 

TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); // 2-Kanal "non-inverting" 
TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS11); 

//Initialize ADC 
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0); 
ADMUX=0x00; 
unsigned int adc_value=0; // Variable to hold ADC result 

char text[2]; 
while(1) 
{ 
    ADCSRA |= (1<<ADSC); // Start conversion 
    while (ADCSRA & (1<<ADSC)); // wait for conversion to complete 
    adc_value = ADCW; //Store ADC value 
    itoa (adc_value,text,16); 
    lcd_setcursor(0,4); 
    lcd_string(text); 
    for (int Index=0; Index<85; ++Index) { 
     txbuffer[Index] = rxbuffer[Index]; 
    } 
    uint16_t brightness_i2c=0; 
    uint16_t contrast_i2c=0; 

    brightness_i2c=(rxbuffer[81]<<8)|(rxbuffer[82]); 
    contrast_i2c=(rxbuffer[83]<<8)|(rxbuffer[84]); 
    if (rxbuffer[0]==1){ 
       lcd_update(); 
     rxbuffer[0]=4; 
    }else if(brightness_i2c!=eeprom_read_word(&brightness) && brightness_i2c!=0xFFFF){ 
    eeprom_write_word(&brightness,brightness_i2c); 
     OCR1A = eeprom_read_word(&brightness); 

    }else if (contrast_i2c!=eeprom_read_word(&contrast) && contrast_i2c!=0xFFFF){ 
     eeprom_write_word(&contrast,contrast_i2c); 
     OCR1B = eeprom_read_word(&contrast); 

    }else{ 
     for (uint8_t i=0; i<50; i++) _delay_ms(10); 
     lcd_setcursor(19, 4); 
     lcd_data(0xFF); 


     for (uint8_t i=0; i<50; i++) _delay_ms(10); 

     lcd_setcursor(19, 4); 
     lcd_data(0x20); 

    } 

} 
} 
+0

Не АЦП на долото ATMEGA 10? Независимо от того, что ваша переменная 'text' достаточно велика для одного символа. Если ADC регистрируется выше 0x0F, вы переполните этот буфер. (Также помните, что для строк C всегда нужен дополнительный символ для конечного \ 0) – theB

+0

Да АЦП 10 бит, но также с отключенным выходом Mega8 сбой – user3321030

+0

В методе инициализации вы также выполняете 'itoa (SLAVE_ADRESSE, текст, 16), 'с небольшим буфером. Отображается ли эта строка на вашем lcd? – theB

ответ

0

я, наконец, получил его:

Я настройки АЦП с прерываниями, но не фрирана:

ADCSRA =(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADIE)| (1<<ADPS0); 

И вызывайте ADC каждый раз в конце моего цикла While:

ADCSRA |= (1<<ADSC); 

Вот код для ISR:

ISR(ADC_vect) 
{ 
char text[5]; 
itoa (ADC,text,16); 
lcd_setcursor(0,4); 
lcd_string(text); 
} 

Спасибо за ваше время;)