AVR AD采集转换程序.docx
- 文档编号:6430260
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:16
- 大小:100.34KB
AVR AD采集转换程序.docx
《AVR AD采集转换程序.docx》由会员分享,可在线阅读,更多相关《AVR AD采集转换程序.docx(16页珍藏版)》请在冰豆网上搜索。
AVRAD采集转换程序
AVRAD采集转换程序,带数字滤波
1.//本例使用内部参考电压,ADc0输入,采集的信号通过LED显示。
2.
3.//ICC-AVRapplicationbuilder:
2006-9-311:
42:
36
4.//Target:
M32
5.//Crystal:
7.3728Mhz
6.//2.56v片内基准电压,输入a1:
即adc0
7.//误差为:
连续测量模式。
8.//精度8,输出左对齐ADLAR=1
9.//注意:
参考电压一定要高于被测电压。
10.#include
11.#include
12.//数字滤波
13.#definea0xF4
14.//a=0.95
15.#defineb0x0D
16.//b=1-a=0.05
17.constled_table[16]={0xa0,0xfc,0xc1,0xd0,0x9c,0x92,0x82,0xf8,0x80,0x90,0x88,0x86,0xc7,0xc4,0x83,0x8b};//0~~f
18.typedefunsignedcharuint8;
19.uint8value,value1=0;
20.intx;//最终的值10位
21.volatileuint8i,j=0;
22.
23.//delay
24./***********************************/
25.voidDelay100us(uint8n)
26.{
27. uint8i;
28. for(i=36;n!
=0;n--)
29. while(--i);
30.}
31.
32.voidDelay1s(uint8n)
33.{
34. n=n*10;
35. for(;n!
=0;n--){
36. Delay100us(200);
37. }
38.}
39./******************************/
40.
41.voidport_init(void)
42.{
43.PORTA=0x00; //做adc输入时不可上拉。
44.DDRA=0x00;
45.PORTB=0xFF;
46.DDRB=0xFF;
47.PORTC=0xFF;
48.DDRC=0x00;
49.PORTD=0xFF;
50.DDRD=0x00;
51.}
52.
53.//ADCinitialize
54.//Conversiontime:
225uS
55.voidadc_init(void)
56.{
57.ADCSR=0x00;//disableadc
58.ADMUX=0xC0|(1< 59.ACSR=0x80;//使能adc可用,不用修改 60.ADCSRA=0xA8;//ADC使能,自动触发模式使能,触发源由SFIOR确定,中断使能,分频因子为2 61.SFIOR=0X60;//触发源设置为: 定时器比较匹配 62.} 63. 64.//TIMER0initialize-prescale: 1024 65.//WGM: Normal 66.//desiredvalue: 1Hz 67.//actualvalue: 35.556mSec(-3455.6%) 68.voidtimer0_init(void) 69.{ 70.TCCR0=0x00;//stop 71.TCNT0=0x01;//setcount 72.OCR0=0x02;//setcompare//FF 73.TCCR0=0x0D;//starttimer1024分频CTC比较输出定时时间: 256/(7.3728Mhz/1024)=35.556ms 74.} 75. 76.#pragmainterrupt_handlertimer0_ovf_isr: 10 77.voidtimer0_ovf_isr(void) 78.{ 79.TCNT0=0x01;//reloadcountervalue 80.j++; 81.if(j==0)CLI(); 82.} 83. 84.#pragmainterrupt_handlertimer0_comp_isr: 20 85.voidtimer0_comp_isr(void) 86.{ 87.//compareoccuredTCNT0=OCR0 88.TCNT0=0x01;//reloadcountervalue 89.i++; 90.if(i==0)CLI(); 91.} 92. 93.#pragmainterrupt_handleradc_isr: 15 94.voidadc_isr(void) 95.{ 96.//conversioncomplete,readvalue(int)using... 97.//ADIF硬件清零 98.ADCSRA|=(1< 99.value=ADCH; //Read8lowbitsfirst(important) 100.//value|=(int)ADCH<<8;//read2highbitsandshiftintotopbyt 101.//value=(value*2.56)/1024; 102.//数字滤波 103.value1=(char)(((int)a*value1+(int)b*value)>>8); 104.//value1=(int)(a*value1+b*value); 105.x=0|value1; 106.x=x<<2;//真实的10位值 107.if(((x/100)<16)&&((x/100)>0)) 108. PORTB=led_table[x/100]; 109.elsePORTB=led_table[0]; 110./*/测试 111.j++; 112.if(j==255) 113.{ 114. //TIMSK=0x00; 115. ADCSRA&=~(1< 116. CLI(); 117. PORTB=led_table[0]; 118.} 119.*/ 120.} 121. 122.//callthisroutinetoinitializeallperipherals 123.voidinit_devices(void) 124.{ 125.//stoperrantinterruptsuntilsetup 126.CLI();//disableallinterrupts 127.port_init(); 128.timer0_init(); 129.adc_init(); 130. 131.MCUCR=0x00;//电源管理项 132.GICR=0x00;//boot选项 133.TIMSK=0x03;//timerinterruptsources比较输出 134.SEI();//re-enableinterrupts 135.//allperipheralsarenowinitialized 136.} 137. 138.voidmain(void) 139.{ 140.init_devices(); 141. 142.ADCSRA|=(1< 143.while (1) 144.{ 145. 146.PORTB=led_table[0]; 147. 148.//while((ADCSR&(1< 149. 150.//ADCSRA&=~(1< 151. 152.//Delay1s (1); 153.} 154.} 单片机入门系列—avrAD转换程序 //本例使用内部参考电压,ADc0输入,采集的信号通过LED显示。 //整理: AVR与虚拟仪器古欣 //ICC-AVRapplicationbuilder: 2006-9-311: 42: 36 //Target: M32 //Crystal: 7.3728Mhz //2.56v片内基准电压,输入a1: 即adc0 //误差为: 连续测量模式。 //精度8,输出左对齐ADLAR=1 //注意: 参考电压一定要高于被测电压。 #include #include //数字滤波 #definea0xF4 //a=0.95 #defineb0x0D //b=1-a=0.05 constled_table[16]={0xa0,0xfc,0xc1,0xd0,0x9c,0x92,0x82,0xf8,0x80,0x90,0x88,0x86,0xc7,0xc4,0x83,0x8b};//0~~f typedefunsignedcharuint8; uint8value,value1=0; intx;//最终的值10位 volatileuint8i,j=0; //delay /***********************************/ voidDelay100us(uint8n) { uint8i; for(i=36;n! =0;n--) while(--i); } voidDelay1s(uint8n) { n=n*10; for(;n! =0;n--){ Delay100us(200); } } /******************************/ voidport_init(void) { PORTA=0x00; //做adc输入时不可上拉。 DDRA=0x00; PORTB=0xFF; DDRB=0xFF; PORTC=0xFF; DDRC=0x00; PORTD=0xFF; DDRD=0x00; } //ADCinitialize //Conversiontime: 225uS voidadc_init(void) { ADCSR=0x00;//disableadc ADMUX=0xC0|(1< ACSR=0x80;//使能adc可用,不用修改 ADCSRA=0xA8;//ADC使能,自动触发模式使能,触发源由SFIOR确定,中断使能,分频因子为2 SFIOR=0X60;//触发源设置为: 定时器比较匹配 } //TIMER0initialize-prescale: 1024 //WGM: Normal //desiredvalue: 1Hz //actualvalue: 35.556mSec(-3455.6%) voidtimer0_init(void) { TCCR0=0x00;//stop TCNT0=0x01;//setcount OCR0=0x02;//setcompare//FF TCCR0=0x0D;//starttimer1024分频CTC比较输出定时时间: 256/(7.3728Mhz/1024)=35.556ms } #pragmainterrupt_handlertimer0_ovf_isr: 10 voidtimer0_ovf_isr(void) { TCNT0=0x01;//reloadcountervalue j++; if(j==0)CLI(); } #pragmainterrupt_handlertimer0_comp_isr: 20 voidtimer0_comp_isr(void) { //compareoccuredTCNT0=OCR0 TCNT0=0x01;//reloadcountervalue i++; if(i==0)CLI(); } #pragmainterrupt_handleradc_isr: 15 voidadc_isr(void) { //conversioncomplete,readvalue(int)using... //ADIF硬件清零 ADCSRA|=(1< value=ADCH; //Read8lowbitsfirst(important) //value|=(int)ADCH<<8;//read2highbitsandshiftintotopbyt //value=(value*2.56)/1024; //数字滤波 value1=(char)(((int)a*value1+(int)b*value)>>8); //value1=(int)(a*value1+b*value); x=0|value1; x=x<<2;//真实的10位值 if(((x/100)<16)&&((x/100)>0)) PORTB=led_table[x/100]; elsePORTB=led_table[0]; /*/测试 j++; if(j==255) { //TIMSK=0x00; ADCSRA&=~(1< CLI(); PORTB=led_table[0]; } */ } //callthisroutinetoinitializeallperipherals voidinit_devices(void) { //stoperrantinterruptsuntilsetup CLI();//disableallinterrupts port_init(); timer0_init(); adc_init(); MCUCR=0x00;//电源管理项 GICR=0x00;//boot选项 TIMSK=0x03;//timerinterruptsources比较输出 SEI();//re-enableinterrupts //allperipheralsarenowinitialized } voidmain(void) { init_devices(); ADCSRA|=(1< while (1) { PORTB=led_table[0]; //while((ADCSR&(1< //ADCSRA&=~(1< //Delay1s (1); } } 这两天在看别人写的AVR中AD转换程序,自已拼凑起一个能用的,觉得蛮好玩。 贴出来共享 下面这个程序在ATMEGA16L上通过,直接在LCM上显示PA0口的电压。 单位是0.1mV 本程序只是偶试验AVR的AD转换功能而写,也并非我原创,只是消化了别人的程序凑起来的。 但绝对能用。 同时也望大虾们指点一二。 //单端通道,不放大 #defineAD_SE_ADC00x00//ADC0 #defineAD_SE_ADC10x01//ADC1 #defineAD_SE_ADC20x02//ADC2 #defineAD_SE_ADC30x03//ADC3 #defineAD_SE_ADC40x04//ADC4 #defineAD_SE_ADC50x05//ADC5 #defineAD_SE_ADC60x06//ADC6 //常量定义 #defineVref2650//mV /*********AD转换函数******************/ //AD转换函数 //ADC_PORT为输入的端口 /**************************************/ uint16_tMeasured_Vol_INT(unsignedcharADC_PORT) { uint16_tM_Volt=0; //变换后的电压mV uint32_ttemp32; uint8_ti; ADMUX=0xC0|ADC_PORT; //片内基准电压,单端输入. /* ADMUX(ADCMultiplexerSelectRegister) bit7 bit6 REFS1REFS0 参考电压选择 0 0 AREF,内部Vref关闭 0 1 AVCC,AREF引脚外加滤波电容 1 0 保留 1 1 2.56V的片内基准电压源,AREF引脚外加滤波电容 bit5 ADC结果左对齐选择1=左对齐 0=右对齐 bit4~0 选择32通道 */ ADCSRA=(1< /* ADCSRA(ADCControlandStatusRegisterA) bit7 ADENADC使能=1 bit6 ADSC启动ADC开始转换=1 bit5 ADATE自己触发使能 bit4 ADIFADC中断标志 bit3 ADIEADC中断使能 bit2: 0ADC预分频选择位111=128时钟分频 */ asm("sleep"); for(i=0;i<24;i++) { ADCSRA|=(1< while((ADCSRA&0x10)! =0x10); //等待ADC转换结束 ADCSRA|=(1< ADCSRA|=~(1< temp32=(uint32_t)ADC*Vref; M_Volt+=(uint16_t)(temp32/1023); } ADCSRA&=~(1< return(M_Volt/24); } /****************************************/ /*主函数*/ /****************************************/ intmain(void) { DelayMs(100); /*延时100ms*/ Lcminit();/*液晶模块初始化*/ myprintf("mV%"); while (1) { DelayMs(500); /*延时500ms*/ col=0;row=2; myprintf(" %"); col=60;row=2; show_long((unsignedlong)Measured_Vol_INT(AD_SE_ADC0));//获取端口PA0的转换数据 } } 系统功能 大部分AVR内部带有AD,本节以使用ATMEGA16的内部AD为例,给出AD转换中断程序。 硬件设计 AVR主控电路原理图(点击图片放大,不需要放大镜! ) AD转换值低位,LED控制电路原理图(点击图片放大,不需要放大镜! ) AD转换值高位,LED控制电路原理图(点击图片放大,不需要放大镜! ) 软件设计 下面部分从TXT拷出,拷到网页,代码部分缺省了很多空格,比较凌乱,请谅解! //目标系统: 基于AVR单片机 //应用软件: ICCAVR *010********* ---------------------------------------------------------------------- 实验内容: 使用中断检测AD0口,使用PB/PD口的LED指示AD读到的数据。 ------------------------------------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AVR AD采集转换程序 AD 采集 转换 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)