您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > 单片机 ADC&DAC&PWM
单片机第6课哈尔滨工业大学业余无线电俱乐部A/D转换:AnalogtoDigitalConverter我们的单片机只能处理0/1的数据,如果我们想通过单片机的引脚输入一个“0.5”是不可能实现的——单片机的引脚只能识别“0/1”两种状态~这种只能处理、识别“整数”的元器件,我们称它是“数字的”。我们测电压的时候,电压是一个连续变化的数,可以认为是一个“实数”,我们称这种为“模拟的”为了能让单片机这种“数字器件”能接收“电压”这种“模拟量”,我们就需要一种“模拟/数字转换器”,俗称“ADC”模拟量是怎么变成数字量的?ADC将模拟量转化为数字量,一般需要以下三个步骤:采样量化编码采样因为ADC是将“一个模拟量(电压值)”转化为数字量的元件,所以他会先记录现在时刻的输入电压,然后进行转换成数字值,转换需要一个不短的时间,等转换完成后再记录下一个时刻的输入电压,然后转换……整个过程就是“采样——转换——采样——转换……”采样当我们采样的速度很快的时候,我们把每一个点连起来就和输入的图像很像了~每秒钟采样的次数,就叫做“采样频率”我们希望采样频率越高越好~采样采样频率越高,我们就越容易把真实的图像采集下来,以便以后的处理,以及以后“恢复”它~为了能从这些采样的数据点中不失真的恢复原来的波形,采样的频率最少为输入波形最高频率的2倍(奈圭斯特采样定律)量化由于数字量是“离散的”,可以认为就是只能用整数表示,而模拟量是“连续的”,可以用整个实数表示。为了将模拟量转化为数字量,我们需要把实数“四舍五入”为整数,这个过程就叫做“量化”16(4.6875~5.0000)15(4.3750~4.6875)14(4.0625~4.3750)13(3.7500~4.0625)12(3.4375~3.7500)11(3.1250~3.4375)10(2.8125~3.1250)9(2.5000~2.8125)8(2.1875~2.5000)7(1.8750~2.1875)6(1.5626~1.8750)5(1.2500~1.5626)4(0.9375~1.2500)3(0.6250~0.9375)2(0.3125~0.6250)1(0.0000~0.3125)我们把0~5V电压分成了16份,每份为0.3125V像这样每一份间距是相等的,叫做“均匀量化”每一份之间的分界线没有必要深究属于哪一份……0V5V量化我们一般量化的时候,我们会把一个标准的参考电压进行“量化”,得到一系列标准的“小格子”~我们一般会把一整个值(0~5V)量化成为2^N个小格子,其中N称为“量化等级”16(4.6875~5.0000)15(4.3750~4.6875)14(4.0625~4.3750)13(3.7500~4.0625)12(3.4375~3.7500)11(3.1250~3.4375)10(2.8125~3.1250)9(2.5000~2.8125)8(2.1875~2.5000)7(1.8750~2.1875)6(1.5626~1.8750)5(1.2500~1.5626)4(0.9375~1.2500)3(0.6250~0.9375)2(0.3125~0.6250)1(0.0000~0.3125)4(3.75~5.00)3(2.50~3.75)2(1.25~2.50)1(0.00~1.25)5V5V0V0V参考电压参考电压编码我们把一个采样好的电压(2.98V)和量化好的参考电压进行比较,得到了对应的“小格子”的代码,这个过程就叫做编码我们只要把小格子的代码告诉单片机,单片机就能知道我们输入的电压是多少了(因为参考电压是定死的,不能修改的,他的电压是多少我们都知道)16(4.6875~5.0000)15(4.3750~4.6875)14(4.0625~4.3750)13(3.7500~4.0625)12(3.4375~3.7500)11(3.1250~3.4375)10(2.8125~3.1250)9(2.5000~2.8125)8(2.1875~2.5000)7(1.8750~2.1875)6(1.5626~1.8750)5(1.2500~1.5626)4(0.9375~1.2500)3(0.6250~0.9375)2(0.3125~0.6250)1(0.0000~0.3125)2.98V输入电压参考电压10(0x0A)单片机可以知道,输入电压在2.8125~3.125之间量化等级4编码如果参考电压分的格数比较少(4份——量化等级2),那我们得到的结果比较“粗糙”,我们最后只能知道输入电压在2.50~3.75之间量化等级很重要!!我们当然希望量化等级越高越好~2.98V输入电压参考电压3(0x03)单片机可以知道,输入电压在2.50~3.75之间4(3.75~5.00)3(2.50~3.75)2(1.25~2.50)1(0.00~1.25)量化等级2量化&编码根据量化编码的程度(量化等级)不一样,一般ADC又分为以下几种:8位AD(量化等级8)10位AD(量化等级10)12位AD(量化等级12)……量化等级越高,精度越高,转换速度越慢……ADC实现的过程5V0V参考电压采样161514131211109876543212.98V输入电压(采样电压)量化10(0x0A)编码(比较)模拟量数字量这里隐含了一个“比较”的过程……比较:获得采样电压对应的“小格子”ADC比较的方式有很多种,具体很复杂,我不想多说,有兴趣大家可以自己查一下~按照比较方式的不同,ADC又分为以下几种:闪速型(速度最快)逐次逼近型(速度比较快)双积分型(精度较高)Sigma-delta型(精度最高)我们的单片机自带了AD功能~我们可以很方便的直接使用~~整个P1口都可以作为ADC的通道什么叫做“通道”?其实我们的单片机只有一个ADCP1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7ADC多路选择开关——可以选择ADC连在哪个引脚上我们可以通过修改单片机寄存器,控制多路选择开关连接不同引脚,对不同引脚输入的电压进行测量~看看如何设置I/O成为ADC的通道哪一个脚对应的位设为1,就作为ADC的通道,不作为普通I/O口使用了~我们的开发版引出了三个ADC通道给大家~引出的两个ADC2.5V标准电压单片机中和ADC有关的寄存器P1ASF:设置P1哪个脚作为ADC通道ADC_CONTR:ADC控制寄存器ADC_RES:ADC转换结果寄存器ADC_RESL:ADC转换结果寄存器低AUXR1:ADC转换结果格式设置寄存器IE:ADC中断使能(开始工作)寄存器IP、IPH:中断优先级寄存器ADC_CONTR寄存器寄存器名bitB7B6B5B4B3B2B1B0ADC_CONTRnameADC_POWERspeed1speed0ADC_FLAGADC_STARTCHS2CHS1CHS0CHS2、CHS1、CHS0:模拟通道选择选择哪个通道进行ADC输入ADC_CONTR寄存器寄存器名bitB7B6B5B4B3B2B1B0ADC_CONTRnameADC_POWERspeed1speed0ADC_FLAGADC_STARTCHS2CHS1CHS0ADC_START:ADC转换启动控制位设置为1时开始采样并转换,转换完成自动变为0ADC_FLAG:ADC转换完成标志位一次ADC转换完成后,该位自动变成1,一定要软件清0(写程序置零)ADC_CONTR寄存器寄存器名bitB7B6B5B4B3B2B1B0ADC_CONTRnameADC_POWERspeed1speed0ADC_FLAGADC_STARTCHS2CHS1CHS0speed1、speed0:ADC转换速度设置转换速度越快,耗电越大ADC_POWER:ADC电源开关,‘1’为开打开电源后,应等待一段时间,等ADC内部电源稳定后再进行采样,以保证转换精度(为保证精度,最好所有转换完成后再关闭电源)ADC转换得到什么数呢?ADRJ=0:ADC_RES[7:0],ADC_RESL[1:0]=1024*Vin/VccADRJ=1:ADC_RES[1:0],ADC_RESL[7:0]=1024*Vin/VccADC_RES从第0位到第7位,ADC_RESL从第0位到第1位有效ADC_RES从第0位到第1位,ADC_RESL从第0位到第7位有效ADC可以这样初始化:voidADC_init(){AUXR1&=0xfb;//ADRJ=0,读取模式P1ASF=0X83;//设置P1.7、P1.1、P1.0为AD模式(作为AD通道10000011)ADC_CONTR|=0x80;//打开AD电源Delay500ms();//等待一段时间让AD电源稳定ADC_CONTR|=0x60;//设置最快速度转换ADC_CONTR&=0xef;//清零ADC中断ADC_FLAG=0;}我们初始化ADC的选择通道可以这样:Voidinit_P1.7(){ADC_CONTR&=0xef;//清零ADC中断ADC_FLAG=0;ADC_CONTR&=0XF8;//设置通道7(P1.7)作为AD输入ADC_CONTR|=0X07;//设置通道7(P1.7)作为AD输入ADC_CONTR|=0X08;//打开ADC转换一次While(ADC_CONTR&0X10!=0);//等待AD转换完成}初始化P1.7通道Voidinit_P1.1(){ADC_CONTR&=0xef;//清零ADC中断ADC_FLAG=0;ADC_CONTR&=0XF8;//设置通道7(P1.1)作为AD输入ADC_CONTR|=0X01;//设置通道7(P1.1)作为AD输入ADC_CONTR|=0X08;//打开ADC转换一次While(ADC_CONTR&0X10!=0);//等待AD转换完成}初始化P1.1通道Voidinit_P1.0(){ADC_CONTR&=0xef;//清零ADC中断ADC_FLAG=0;ADC_CONTR&=0XF8;//设置通道7(P1.0)作为AD输入ADC_CONTR|=0X00;//设置通道7(P1.0)作为AD输入ADC_CONTR|=0X08;//打开ADC转换一次While(ADC_CONTR&0X10!=0);//等待AD转换完成}初始化P1.0通道Voidinit_P1.x(charx){ADC_CONTR&=0xef;//清零ADC中断ADC_FLAG=0;ADC_CONTR&=0XF8;//设置通道7(P1.x)作为AD输入ADC_CONTR|=x;//设置通道7(P1.x)作为AD输入ADC_CONTR|=0X08;//打开ADC转换一次While(ADC_CONTR&0X10!=0);//等待AD转换完成}总结成初始化P1.x通道ADC转换的结果存在这里:ADRJ=0:10位AD转换结果高8位在ADC_RES,低2位在ADC_RESL低2位ADRJ=1:10位AD转换结果高2位在ADC_RES低2位,低8位在ADC_RESL获取ADC采样的结果、恢复成电压值ADRJ=0:ADC_RES[7:0],ADC_RESL[1:0]=1024*Vin/Vcc1、两个寄存器的值进行合并:intt1,t2,date;t1=ADC_RES;t2=ADC_RESL;date=t12+t2;2、离散的数还原成电压值:doublevolte;volte=5.0*(date/1024);intGet_AD_date(){unsignedlongintt1,t2,data;doublevolte;t1=ADC_RES;//高两位t2=ADC_RESL;//低八位date=(t12)+t2;returndate;}整理成这样一个结构:voidmain(){doubleVOL0,VOL1,VOL7;ADC_init();while(1){Init_P1.x(0);VOL0=Ge
本文标题:单片机 ADC&DAC&PWM
链接地址:https://www.777doc.com/doc-5014654 .html