我有这段代码,它需要多个 adc 转换并以串行方式发送它们,如果我在 set_ADMUX() 之后不添加 3 ms 延迟,则 ADC 样本不是通道的正确样本,但我认为这是一个太大的延迟正常情况下,代码如下:
//setup adc
void set_adc(void) {
ADCSRA = (( 1<<ADEN ) | ( 1<<ADATE ) | ( 1<<ADIE ) | (1 << ADSC) ); // enable adc, auto trigger, interrupt enable, start first rilevation
ADCSRB = (( 1<<ADTS2 ) | ( 1<<ADTS0 )); // Timer/Counter 1 Compare Match B
ADMUX = (1 << REFS0) | (1 << ADLAR); //set Voltage reference to Avcc (5v), left adjust converted value, if this is commented we use AREF
}
//timer for adc conversions
uint16_t ticks;
void set_timer1 ( uint16_t ticks )
{
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
TIMSK1 = 0;
TCCR1B = ( 1 << WGM12 ) ; // configure for CTC mode 4 OCR1A=TOP
OCR1A = ticks; // set CTC TOP value
TCCR1B |= ( 1 << CS10 ); // start timer, give it a clock, fcpu/1
}
//set channel for adc
volatile uint8_t i=0;
void set_ADMUX(void){
switch(i){
case 0:
ADMUX = (1 << REFS0) | (1 << ADLAR);
break;
case 1:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX0);
break;
case 2:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX1);
break;
case 3:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX0) | (1 << MUX1);
break;
case 4:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX2);
break;
case 5:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX2) | (1 << MUX0);
break;
case 6:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX2) | (1 << MUX1);
break;
case 7:
ADMUX = (1 << REFS0) | (1 << ADLAR) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0);
break;
}
}
//adc interrupt
uint32_t key=0x55aa;
volatile uint8_t sample_count=0;
volatile uint8_t send_flag=0;
uint8_t buffull_count=0;
ISR(ADC_vect) {
while(channel_buffer[i]!=1){
i++;
if(i>=8){
i=0;
}
}
set_ADMUX();
_delay_ms(3);//<-------------------------------------------------------------
switch(i){
case 0:
if(mode==1){
buffer1[sample_count]=ADCH;
}
channel=1;
//printf("1");
break;
case 1:
if(mode==1){
buffer2[sample_count]=ADCH;
}
channel=2;
//printf("2");
break;
case 2:
if(mode==1){
buffer3[sample_count]=ADCH;
}
channel=3;
//printf("3");
break;
case 3:
if(mode==1){
buffer4[sample_count]=ADCH;
}
channel=4;
//printf("4");
break;
case 4:
if(mode==1){
buffer5[sample_count]=ADCH;
}
channel=5;
//printf("5");
break;
case 5:
if(mode==1){
buffer6[sample_count]=ADCH;
}
channel=6;
//printf("6");
break;
case 6:
if(mode==1){
buffer7[sample_count]=ADCH;
}
channel=7;
//printf("7");
break;
case 7:
if(mode==1){
buffer8[sample_count]=ADCH;
}
channel=8;
//printf("8");
break;
}
if(mode==0){
printf("%d\n", channel);
printf("%d\n", ADCH);
structure.seq++;
}
if(mode==1){sample_count++;}
if(sample_count==BUFFER_SIZE-1){
buffull_count++;
sample_count=0;
if(buffull_count==num_channels){
sample_count=0;
if(mode==1){
send_flag=1;
buffull_count=0;
}
}
}
i++;
TIFR1 = ( 1<<OCF1B ); // clear Compare Match B Flag
}
我思考过一些adc设置问题,或者ISR的错误使用,但找不到确切的原因,较小的延迟不起作用
在被告知后,我将代码缩减为仅涉及 ADC 的内容。
我使用的是atmega 2560,数据表:https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
问题是我的逻辑,如@lxop
等待 ADC 转换完成,然后在读取结果之前更新多路复用器
我将 set_ADMUX 移至 ISR 的末尾,现在一切正常,谢谢大家