I want to output some adc conversions on cutecom using atmega2560, set 16 bit clock with 64 prescale at 16 Mhz to trigger adc conversion (each takes 13 clock cycles) and that should be around 19000 conversions per second (16M/64=250k and 250k/13=19200), but I get these 512 samples each half a second outputted on cutecom.
#include <util/delay.h>
#include <stdio.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#define BAUD 57600
uint16_t myubbr= (F_CPU/16/BAUD-1);
uint16_t ticks=1;
uint8_t counter=0;
void usart_init( uint16_t ubrr) {
// Set baud rate
UBRR0H = (uint8_t)(ubrr>>8);
UBRR0L = (uint8_t)ubrr;
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); /* Enable RX and TX */
}
void setup_adc(void) {
// enable adc, auto trigger, interrupt enable, prescale=128
ADCSRA = (( 1<<ADEN ) | ( 1<<ADATE ) | ( 1<<ADIE ) | ( 1<<ADPS2 ) | ( 1<<ADPS1 ) | ( 1<<ADPS0 ));
// Timer/Counter 1 Compare Match B
ADCSRB = (( 1<<ADTS2 ) | ( 1<<ADTS0 ));
// ref=AVcc + adc chan
ADMUX = (1 << REFS0) | (1 << ADLAR); //set Voltage reference to Avcc (5v), left adjust converted value, if this is commented we use AREF, last tree are for selecting A7 as input as shown in the table
}
void timer1_init ( uint16_t ticks )
{
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
TIMSK1 = 0;
TCCR1B = ( 1 << WGM12 ) ; // Configure for CTC mode 4 OCR1A=TOP
OCR1B = ticks; // compare value
OCR1A = ticks; // Set CTC TOP value, must be >= OCR1B
// start timer, give it a clock
TCCR1B |= ( 1 << CS10 ) | ( 1 << CS11 ); //no prescaler //(( 1 << CS10 ) | ( 1 << CS12 )) ; // Fcpu/1024, 64us tick @ 16 MHz
}
void set_ADMUX(void){
ADMUX = (1 << REFS0) | (1 << ADLAR);
}
// ADC complete interrupt service routine
ISR(ADC_vect) {
counter=counter+1;
while(UCSR0A&(1<<UDRE0)==0){;}
UDR0 = '\n';
set_ADMUX();
TIFR1 = ( 1<<OCF1B ); // clear Compare Match B Flag
}
//main function
int main(void){
timer1_init (ticks);
usart_init(myubbr);
setup_adc();
//clear interrupt registers
cli();
//enable global interrupts
sei();
//start first rilevation
ADCSRA |= (1 << ADSC);
while(1){
}
}
I have simplified the code for testing by sending the character '\n' on usart0, I do that in the ISR of the ADC conversion interrupt, I was expecting 19000 lines per second but I get way lower amount than that.
I get 512 timestamps like that
.
.
.
[17:35:58:542] ␊
[17:35:58:542] ␊
[17:35:58:542] ␊
[17:35:58:542] ␊
[17:35:58:542] ␊
[17:35:58:542] ␊
[17:35:58:542] ␊
.
.
.
and then another 512 timestmps lke that
.
.
.
[17:35:59:063] ␊
[17:35:59:063] ␊
[17:35:59:063] ␊
[17:35:59:063] ␊
[17:35:59:063] ␊
[17:35:59:063] ␊
[17:35:59:063] ␊
.
.
.