当我设置每秒19 000个左右时,为什么我在cutecom上读取了0.5/0.4秒写的512个字符?

问题描述 投票:0回答:1

我想使用atmega2560在cutecom上输出一些adc转换,设置16位时钟和64预分频在16 Mhz来触发adc转换(每个需要13个时钟周期),每秒应该大约19000次转换(16M/64=250k和250k/13=19200),但是我在cutecom上每半秒输出512个样本。

#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;
  
  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){
      }
}

我通过输出字符 ' 简化了测试代码 ' 在 usart0 上,我在 ADC 转换中断的 ISR 中执行此操作,我预计每秒 19000 行,但得到的数量远低于该值。

我得到了 512 个这样的时间戳

.
.
.

[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] ␊
.
.
.

然后是另外 512 个时间戳,类似这样


.
.
.

[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] ␊
.
.
.
c timer microcontroller atmega adc
1个回答
0
投票

每秒大约获得 512 个时间戳,每个时间戳 15 个字节,总计每秒 7680 个字节。串口设置为57600波特率,即:每秒57600bits,这对于7680字节来说还不够,算上至少1个起始位和1个停止位。实际吞吐量应该会少一些,为每秒 384 个时间戳。删除设备有可能会用样本输出填充缓冲区,直到填满,然后等待缓冲区传输时出现某个阈值,然后再开始填充它,每 0.4 或 0.5 秒产生相同样本的突发。

© www.soinside.com 2019 - 2024. All rights reserved.