本帖最后由 海飏之心 于 2013-6-24 13:54 编辑
mega16的AD使用问题
最近要用mega16来做电压采集,但是遇到一个很奇怪的问题,使用手动触发(利用串口中断来触发)的方式来采样,不管AD输入是否变化,转换结果一直是第一次采样的值。但是如果使用自动触发的方式(没有更改SFIO,默认值),采样结果就与AD输入同步变化。代码如下:
手动触发与自动触发
void adc_init()
{
PORTA = 0X00;
DDRA = 0x00; //ADC通道设置为输入口,高阻态
ADMUX |= (1 << REFS0) | (1 << MUX0); //ADC参考电压为AVcc,选择通道ADC1
ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1)| (1 << ADPS0)|(1<<ADIE ); //使能AD转换,ADC时钟128分频,使能中断,串口中断触发用的是这一语句
// ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1)| (1 << ADPS0)|(1<<ADIE )|(1<<ADATE); //自动触发用的是这个语句,并使用默认触发源
}
void transfer()
{
unsigned char data;
ADCSRA |= (1 << ADSC); //开始AD转换
}
int main(void)
{
//DDRA=0x00; //设置PORTA为输入
//PORTA=0xff; //设置为无上拉电阻输入
DDRB=0x00; //设置PORTA为输入
PORTB=0xff; //设置为无上拉电阻输入
DDRC=0xff; //
PORTC=0x00; //
wdt_disable();
uart_init(); //初始化串口
adc_init();//初始化AD
sei(); //开总中断
while(1);
}
ISR(USART_RXC_vect)
{
unsigned char status;
status=UCSRA; //读取接收状态标志位,必须先读,当读了UDR后,UCSRA便自动清零了
status=UDR; //读取USART数据寄存器
if(status=='o')
{
RBI__(PORTC,7);
transfer();//触发采样
}
}
ISR(SIG_ADC)
{
unsigned char data;
RBI__(PORTC,6);
ADCSRA|=(1<<ADIF);
data=ADCH;
while((UCSRA&0x20)==0);
UDR=data;
data=ADCL;
while((UCSRA&0x20)==0);
UDR=data;
} |