程序代碼: /* 程序功能:用單片機內部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.zg4o1577.cn/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); } } }