介绍一下这两天学AVR ADC的收获 –帅峰电子科技

好友帅峰的技术文章!点击前往帅峰电子科技淘宝店铺

CPU:Atmega 16

编译环境:CV AVR

实验名称:AVR 10ADC的通道自动切换多路数据缓存。
#include <mega16.h>
#include <delay.h>
#define uchar unsigned char
#define uint  unsigned

uint   ADC_data,SET_ADC, ADC_real_data;

bit    ADC_fIag;  //转换完成标志位

/****LED输出口定义*****/
#define LED1  PORTB.0   //这里的写法是CV AVR编译器的一大特色,很方便吧
#define LED2  PORTB.1
#define LED3  PORTB.2
#define LED4  PORTB.3
#define LED5  PORTB.4

uint ADC_data_store[3]; //AD数据缓存,这里我们把两次不同端口的ADC数据缓存到里面
void time_(uint TT);
/****数据转换子函数****/
uint ADC_conv(uint i)  //这里我们要将实际值放大1000倍计算,目的是不让单片机进行复杂的浮点数运算
{
long x;
uint y;
x=(4600*(long)i)/1023; //输入电压值/1023*adc
y=(uint)x;             //将无符号长整型变量X转化为无符号整型变量Y
return y;              //取Y数据转换返回值
}

interrupt [ADC_INT] void adc_isr(void)
{

ADC_data=ADCL;
ADC_data|=(int)ADCH<<8;    //将ADCH右对齐的低两位左移到高位,并和ADCL相加。
SET_ADC++;                 //完成一次转换自加1
if(SET_ADC==1) ADMUX= 0x40;//选择通道0
if(SET_ADC==3) ADMUX= 0x41;//选择通道1 //如果要通道3加一句就行,记住数据缓冲区也改大一些
if(SET_ADC==4) SET_ADC=0;
ADC_flag=1;                //转换完成标志位

}

void AD_init()//这里大家参考一下技术文档就明白了
{
ADMUX |= (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);//初始化通道0
ACSR =0X80; //关模拟比较器
ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(0<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}

void main(void)
{
PORTB= 0XFF;//给端口写数据
DDRB=0xFF;  //设定为输出使能

PORTA=0X00; //高阻态
DDRA=0X00;  //设定为输入使能

AD_init();
SET_ADC=0;
while(1)
{

if(ADC_flag==1)
{
ADC_flag=0;
ADC_real_data= ADC_conv(ADC_data);//数据转换
ADC_data_store[SET_ADC]=ADC_real_data;//存放到数组里
}

if((ADC_data_store[1]>1000)&&(ADC_data_store[1]<2000)) { LED=0;} //简单测试
if((ADC_data_store[3]>2000)&&(ADC_data_store[3]<3000)) { LED=0;}
//当然可以改写一下就能运用到各种程序里。

//在这里我提醒大家,如果得到需要高精度ADC值,我们可以多次采集,然后取平均值。

}

}