0

i am trying to Read an Voltage Level via a ADC0 of my ATmega8, because of querying a 1 Pin 4x4 Matrix Keypad. The Problem is everytime I apply a Voltage to the ADC higher than GND the Atmega is stopping to do his work. The PWM outputs are still working, but communication via i2c is impossible and the LCD is clear. My wiring is simple, AREF & AVCC are set to 5V, GND is set to GND and PC0 is my Input. Is there anything I fail to Notice? Thank You for your help. Here is my Code:

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)]);
}
}

An here is the main function:

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);

    }

} 
}
  • Isn't the ADC on the ATMEGA 10 bit? Regardless your `text` variable is only large enough for a single character. If the ADC registers above 0x0F, then you'll overflow that buffer. (Also remember that C strings always need an extra character for the trailing \0) – theB Aug 25 '15 at 22:38
  • Yes ADC is 10 Bit, but also with disabled output the Mega8 is crashing – user3321030 Aug 25 '15 at 22:43
  • In the initialization method you're also doing `itoa (SLAVE_ADRESSE,text,16);` with a small buffer. Is that string being displayed on your lcd? – theB Aug 25 '15 at 22:48
  • Yes this String is Displayed correctly – user3321030 Aug 25 '15 at 22:58
  • I changed now to ISR, the ADC is working now, but nothing else, it seems that the ISR is blocking everything:`ADMUX = (1< – user3321030 Aug 26 '15 at 10:20

1 Answers1

0

I finally got it:

I setup the ADC with interrupts but not freerunning:

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

And call the ADC everytime at the end of my While loop:

   ADCSRA |= (1<<ADSC);

Here is the Code for the ISR:

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

Thanks for your time ;)