程序代码: /* 程序功能:用单片机内部AD实现外部电压转换为数字信号 作者:朱波 时间:2012年1月14日 AD工作流程:1.配置引脚为不带上拉电阻的输入 2.进行ADC多工选择寄存器(ADMUX)的设置(参考电压的选择和输入通道、增益的选择) 3.进行ADC控制和状态寄存器A(ADCSRA) 的设置(使能AD) 4.进行ADC控制和状态寄存器A(ADCSRA) 的设置(启动AD) 5.进行查询设置(转换完成后跳出循环) 6.进行ADC数据寄存器(ADCL、ADCH)的设置 7.返回AD转换结果 完整程序源代码下载:http://www.51hei.com/f/hdjz.rar 滑动窗口均值滤波函数应用的注意事项: Aver_Voltage(mega16_ad())函数的应用和 #define ADC_BUFF_SIZE_BIT_COUNT 5 #define ADC_BUFF_SIZE (1<<ADC_BUFF_SIZE_BIT_COUNT) 当我们定义ADC_BUFF_SIZE_BIT_COUNT为5的时候,ADC_BUFF_SIZE的值就相当于2的 5次方,也就是第一句话的值越大求得平均值范围就越大 */ #include<iom16v.h> #include<macros.h> #define uchar unsigned char #define uint unsigned int #define ADC_BUFF_SIZE_BIT_COUNT 6 #define ADC_BUFF_SIZE (1<<ADC_BUFF_SIZE_BIT_COUNT) uint Aver_Volt; const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(uint ms) { uint i,j; for(i=0;i<ms;i++) { for(j=0;j<1141;j++); } } void show(uchar j,uchar k) { DDRA|=BIT(3); DDRA|=BIT(4); DDRB=0XFF; PORTA|=BIT(3); PORTB=table[j]; PORTA&=~BIT(3); PORTB=0XFF; PORTB&=~BIT(k); PORTA|=BIT(4); PORTA&=~BIT(4); delay(1); } uint mega16_ad() { uint addata; DDRA&=~BIT(PA7);//设置PA0为输入 PORTA&=~BIT(PA7);//无上拉电阻的输入 ADMUX=0x47;//ADC多工选择寄存器0100 0000 //解释:ADC0单端输入参考电压选择为AVCC、AREF引脚外加滤波电容 ADCSRA=0X80;//1000 0000使能AD ADCSRA|=BIT(ADSC); //启动AD while(!(ADCSRA&(BIT(ADIF))));//查询 addata=ADCL; addata=addata+ADCH*256; return addata; } unsigned int Aver_Voltage(unsigned int Curr_Volt) { static unsigned int Arr_Voltage[ADC_BUFF_SIZE];//定义滤波数组 static unsigned char s_cBufferCounter=0;//定义元素指针并赋初值 unsigned int s_dTotal=0;//总数,平均电压 unsigned char n; Arr_Voltage[s_cBufferCounter]=Curr_Volt;//将A/D采样值加入到数组中 for(n=0;n<ADC_BUFF_SIZE;n++)//计算数组中元素的总和 { s_dTotal+=Arr_Voltage[n]; } Aver_Volt=s_dTotal>>ADC_BUFF_SIZE_BIT_COUNT;//用移位的方式做除法,计算平均值 s_cBufferCounter++; if(s_cBufferCounter==ADC_BUFF_SIZE) s_cBufferCounter=0; return Aver_Volt; } void main() { uint ada,i,ad[4]; while(1) { //ada=mega16_ad(); Aver_Voltage(mega16_ad()); for(i=0;i<4;i++) { ad[3-i]=Aver_Volt%10; Aver_Volt=Aver_Volt/10; } for(i=0;i<4;i++) { show(ad[i],i); delay(2); } } }