最近使用了一下AVR的ADC自动触发,以前使用的是自由运行,设置比较简单,没有什么需要注意的地方,做个东西对时序要求比较严格,采样的时间要准
于是乎用了avr的自动触发,使用了定时器1的溢出作为触发源,一开始以为和自由运行一样,只要把源改为定时器1的溢出就可以了,后来发现不是这样的,
ADC始终只完成一次转换,如果触发源改为自由运行,则可以不断的进行转换,仔细看看数据手册,原来有需要注意的地方:
要实现一次触发,必须满足下列条件:
1、ADC使能
2、ADC自动运行位使能
3、触发源必须产生一次上升沿
而我之前一直忽略的是第三个条件,所以ADC程序必须在采集一次之后清掉触发标志,以便下一个上升沿的产生。
下面为一段测试程序
#include <avr/io.h>
#include <avr/interrupt.h>
void timer1_init(void)
{
DDRB |= (1<<DDB1)|(1<<DDB2);
TCCR1A = (2<<COM1A0)|(2<<COM1B0)|(1<<WGM11);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);
ICR1 = (12000>>1); //定时器1快速PWM模式
OCR1A = (12000>>2);
OCR1B = 0;
TIMSK1 = 0;
return;
}
void adc_init(void)
{
ADMUX = 0x0;
ADCSRA = (1<<ADEN)|(1<<ADATE)|(1<<ADIF)|(3<<ADPS0);
ADCSRB = 0x6; //定时器1溢出触发ADC
ADCSRA |= (1<<ADIE)|(1<<ADSC);
return;
}
int main(void)
{
timer1_init();
adc_init();
sei();
while (1){
__asm volatile("nop");
}
return(0);
}
ISR(ADC_vect)
{
TIFR1 |= (1<<TOV1); //这是关键的,清零标志
}
上面程序在AVR studio4.18上仿真通过,记得选择AVR simulator 2,不带2的仿真也只完成一次转换,具体原因不明。