Hi Freaks,
I am using a M128 with ADC on channel 5. I am using the UART for an RS232 connection to my PC. I am trying to see a sampled sine wave on my PC. Sine wave frequency is 100Hz which I have confirmed with an O scope. Amplitude is about 700 mV. Xtal frequency is 8MHz. CLKDIV8 fuse is selected. UART baud rate is 1200 baud.
I am getting the instantaneous voltage values on the hyperterminal but I am getting multiple zeroes between the values. Could this be because of a wrong baud rate? Do I have to average the samples? Here is a part of my code:
I am using a timer to display the ADC values every second on my PC.
#define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((8000000/ (USART_BAUDRATE * 16UL))) - 1) //value to load into UBRR unsigned int a; unsigned int b; volatile unsigned char flag; static int UART_putchar(char c, FILE *stream); static FILE mystdout = FDEV_SETUP_STREAM(UART_putchar, NULL, _FDEV_SETUP_WRITE); void USART0_init() { UCSR0B |= (1 << RXEN0) | (1 << TXEN0); // Turn on the transmission and reception circuitry UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); //Set to 8 bit no parity, 1 stop bit UBRR0L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register UBRR0H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register stdout = &mystdout; //Required for printf init } static int UART_putchar(char c, FILE *stream) { if (c == '\n') UART_putchar('\r', stream); while ((UCSR0A & (1 << UDRE0)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it UDR0 = c; return 0; } char UART_getchar() { while((UCSR0A & (1 << RXC0)) == 0) {}; return UDR0; } void ADC_init() { ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADATE); // Set ADC prescaler to 128 ADMUX = (1 << REFS0) | (1 << MUX2) | (1 << MUX0); // Set ADC reference to AVCC,select channel 5 //using all 10 bit of ADC; so do not left justify the ADC value DIDR0 = (1 << ADC5D); //turn off the digital driver ADCSRA |= (1 << ADEN); // Enable ADC } ISR(TIMER1_COMPA_vect) { PORTD ^= (1 <<PORTD7); flag = 1; } /************MAIN**************/ int main (void) { DDRC = 0x0F; DDRD = 0xC0; DDRB = 0xFF; PORTD = 0x00; PORTB = 0x01; USART0_init(); ADC_init(); timer_init(); for(;;) { _delay_ms(100); ADCSRA |= (1 << ADSC); while((ADCSRA & _BV(ADIF)) != 0); ADC_dummy = ADC; ADC_buffer_dummy = ADC_dummy * 5; a = ADC_buffer_dummy/1000; b = ADC_buffer_dummy(percent)1000; if(flag==1) { printf("#d.#d\n",a,b); //percent sign replaced due to posting bug flag = 0; } } }
So, with the /8 CLKDIV8 fuse, Xtal frequency of 8MHz ,13 cycles/sample and prescalar of 128 I should be getting a sample rate of about 600 sps. This should satisfy Nyquist for a 100Hz signal. I am using a baud rate of 1200 baud to display these samples on my PC. Does this mean I will get 1200 bps which is nearly twice my ADC sampling frequency?
What could be missing? Is it the averaging?
Appreciate your thoughts on this.