《初学单片机的40个C程序小实验》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1.闪烁灯1.实验任务如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。2.电路原理图AT8SS31£01234:.711111111PFppppppF*3O/IUCDP31/TXDP32/iWXOt--IP34/TOP3S/TlP3&/WRf»37/RS-POO/AOOPO1/AD1POPO3/AO3PO4/AEMPO.3/AD2FOPO7/AD7ALE1514?1110篮0®/AC/A/A七B□222^-2pPpppppP
17.C语言源程序#include
2NDXIG8V/0Zd2VKZd二VRZdnZd2VKZdsv/9ZdSJwczd乙an=TIVcav沁od9OV/9Odcov/sod▼OVGodeaweodzav/3od-avnodoav/ood7.C语言源程序#include
3vccvccmLQF£929sSOV/SOdww£EOW£zasdOdsv/o£lOuF31IGNDRSTSMCZd0B2J^ir-sQJu-7.方法一(C语言源程序)ftinclude
4OOC22MH«^.C33OpF30"GNDVCC十Kei10uF毋G8AP10P00/AD0Pl1PO1/ADlP1.2PO.2/AD2P1.3PO.3/AD3P14PO4/AD4P15PO5/AD5P16PO6/AD6P17PO7/AD7ALEPSENP3O/RXDP2.7/A15P31/TXDP2.6/A14P324NT0P25/A13P33/INT1P24/A12P34/TOP23/A11P35/T1P22/A1OP36AVRP21/A9P3.7/RDP2O/A8£Q及OY16J□二7.C语言源程序#include
5VCCooYI6二T口二C2:±二12MHg1,C3近t5nIPlOPOO/ADOp11PO"ADIP12PO2/AD2P13PO3/AD3P14PO4/AD4P1.5PO5/ADSP16PO6/AD6P17PO7/AD7ALEPSENP3CMRXDP27/A15P31/TXDP26/A14P32/INT。P25/A13P33/INT1P24/A12P34/TOP23/A11P35TT1P22/A1OP36/WRP21/A9P37/RDP2O/A8具RcGND{unsignedcharm,n,s;for(m=20;m>0;m--)for(n=20;n>0;n-)for(s=248;s>0;s--);)voidmain(void){while(l){if(table[i]!=0x01){Pl=table[i];i++;delay();)else{i=0;}})7.C语言源程序#include
6U7¥IGND,0K第470I二,,二I'":'--C5'T卜,'1'•'4I'I.•<-I;I;VOUTGAINBYPASSGAINGNDLM386NK8)VCCwdOWNs二VKZduzdGMSZd*W9Zdnd_EsdWTVL2Ls92-9sSOVb0dodnav/sodZOVNOd【av=odoav'oodATS9S5130pFGNDnEd19EdEnd§£LLNUSEd£QKC-sdo£o—|gnd7.C语言源程序#include
7■*ilOuFP1.0Pl1Pl2Pl3Pl4Pl.5i'lc-Pl.7P30/RXDP3.1/TXDP32/fNTOP3.3HNT1P3.4/T0P3.5/T1P3.6/WRP37/RD-OoW3QpF8AP0.0/AD0PO1/AD1PO2/AD2PO3/AD3PO4/AD4PO5/AD5P0.6/AD6PO7/AD?ALERenP27/A15P26/A14P25/A13P24/A12P2.3/A11P2.2/A10I'JP20/A8R2220U2LED8_JC2—^-12MH30pFGND图4.7.1(1.LED数码显示原理七段LED显示器内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的极管的接线形式,可分成共阴极型和共阳极型。LED数码管的g〜a七个发光二极管因加正电压而发亮,因加零电压而不以发亮,不同亮暗的组合就能形成不同的字形,这种组合称之为字形码,下面给出共阴极的字形码见表2“0”3FH“8”7FH“],,06H“9”6FH“2”5BH“A”77H“3,,4FH“b”7CH“4”66H“C”39H“5”6DH“d”5EH“6”7DH“E”79H“7”07H“F”71H
87.C语言源程序#include
9程中,不要有干扰进来,因为,在按下的过程中,一旦有干扰过来,可能造成误触发过程,这并不是我们所想要的。因此在按键按下的时候,要把我们手上的干扰信号以及按键的机械接触等干扰信号给滤除掉,一般情况下,我们可以采用电容来滤除掉这些干扰信号,但实际上,会增加硬件成本及硬件电路的体积,这是我们不希望,总得有个办法解决这个问题,因此我们可以采用软件滤波的方法去除这些干扰信号,一般情况下,一个按键按下的时候,总是在按下的时刻存在着一定的干扰信号,按下之后就基本上进入了稳定的状态。具体的一个按键从按下到释放的全过程的信号图如上图所示:从图中可以看出,我们在程序设计时,从按键被识别按下之后,延时5ms以上,从而避开了干扰信号区域,我们再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出为低电平,若这时检测到的是高电平,证明刚才是由于干扰信号引起的误触发,CPU就认为是误触发信号而舍弃这次的按键识别过程。从而提高了系统的可靠性。由于要求每按下一次,命令被执行一次,直到下一次再按下的时候,再执行一次命令,因此从按键被识别出来之后,我们就可以执行这次的命令,所以要有一个等待按键释放的过程,显然释放的过程,就是使其恢复成高电平状态。7.C语言源程序include
10vccP3O/RXDP31/TXDP3P334MT1P34fTOP35TT1P3e/WRP37/RD1QJQ12345671I111ppppppppts8POO/ADOPO1/AD1PO2/AD2PO.3/AD3PO4/AD4PO5/ADSPO6/AD«PO7/AD7ALEPSENP27/A1SP26/A14P25/AI3P24/A12P23/A11P22/A1OP21/A9P2O/A8D房I「.,while(P3_7==0);}7.C语言源程序#include
1110.00—99计数器1.实验任务:利用AT89S51单片机来制作一个手动计数器,在AT89s51单片机的P3.7管脚接一个轻触开关,作为手动计数的按钮,用单片机的P2.0—P2.7接一个共阴数码管,作为00-99计数的个位数显示,用单片机的PO.0-P0.7接一个共阴数码管,作为00—99计数的十位数显示;P3(WRXDP3l/TXDP3245ff^P334KTTP34/TOP3.5/T1P36/WRP37/RDAT89S5101234567plplplplmplplplUItsAroa/ADOPOi/ADlP02/AD2PO3/AD3P04/AD4P0S/AD5P06/AD6PO7/AD7ALEPSEHP27/A1SP26/A14P23/AI3P24/A12P23/A11P2.2yA10P2UA9P2O/A8deXO鬻西萼锚一器一O2d18^8P2=table[Count%10];while(1){if(P3_7==0){delaylOms();if(P3_7==0){Count++;if(Count==100){Count=0;)P0=table[Count/10];P2=table[Count%10];while(P3_7==0);}}}7.C语言源程序#include
1211.00—59秒计时器(利用软件延时)1.实验任务如下图所不,在AT89s51单片机的P0和P2端口分别接有两个共阴数码管,P0口驱动显示秒时间的十位,而P2□驱动显示秒时间的个位。2.电路原理图P31/TXDP32ANT0P334NT1P34/T0P35mP36/^P37/RDismqi.234,67ppp^pppp8POQ/ADOPO1/AD1P02/AD2P03/AD3P04/AD4P05/ADSP0A/AD6PO7/AD7ALE「上zP27/A15P26/A14P2S/A13P24/A12P23/A11P22/A1OP21/A9P20/A8」T「242-ppppp21„g三o{Second=0;P0=table[Second/10];P2=table[Second%10];while(1){delayls();Second++;if(Second==60){Second=0;}P0=table[Second/10];P2=table[Second%10];})7.C语言源程序#include
131.实验任务利用AT89S51单片机的Pl.0-P1.3接四个发光二极管L1-L4,用来指示当前计数的数据;用PL4—PL7作为预置数据的输入端,接四个拨动开关KI—K4,用P3.6/WR和P3.7/RD端口接两个轻触开关,用来作加计数和减计数开关。具体的电路原理图如下图所示2.电路原理图vccU139~37~36~35333230GNDVCC|Hvcc|Tvcc|vcc|11GND卜GHD|55GND|GNDVCCGHDVCCGHDVCCP30/RXDP31/TXDP324NT0P334NTTP3.4/T0P35fTlP36jTWP37/^8APOO/ADOPO1/AD1尸尸28272625N2TT飞7百P02/AD2PO3/AD3PO4/AD4P05/AD5P06/AD6PO7/AD7ALEPSENP27/A15P26/A14P25/A13P24/A12P23/A11P22/A10P21/A9P20/A8AT89s5130pF30pFGND7.C语言源程序#include
14for(j=248;j>0;j—);Pl=curcount;while(P3_6==0);}if(P3_7==0){delaylOms();if(P3_7==0){if(curcount<=0){curcount=0;}else{curcount一一;)Pl=^curcount;while(P3_7==0);}}}voidmain(void){curcount=P3&OxOf;Pl二〜curcount;while(l){if(P3_6==0){delaylOms();if(P3_6==0){if(curcount>=15){curcount=15;}else{curcount++;}13.动态数码显示技术1.实验任务如图4.13.1所示,PO端口接动态数码管的字形码笔段,P2端口接动态数码管的数位选择端,PL7接一个开关,当开关接高电平时,显示“12345”字样;当开关接低电平时,显示“HELLO”字样。2.电路原理图OQ•■■•'|3二■8282二、工d口尸三0盲£ 157.C语言源程序Sinclude 16叶用忏用OMDXIK2lOnF3B!';患醺弱时因因因区区区因区,.7IC盘茄盘/"rrrrrrr]®-^1)0»FHrft1.furpFLyo-L»jcm/Tbn/TuL»jn/Tery/TuLgi_jry/TbLy_jry/TbJry/Tij—8°o-o—L-S4o--L«,o-757K"cm/It7.C语言源程序#include 17P0=table[key];temp=temp&OxOf;while(temp!=OxOf){temp=P3;temp=temp&OxOf;}})P3=0xff;P3_5=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=4;break;caseOxOd:key=5;break;case0x0b:key=6;break;case0x07:key=ll;break;}temp=P3;Pl_0=>l_0;P0二table[key];temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;}})P3=0xff;P3_6=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=l;break;caseOxOd:key=2;break;case0x0b:key=3;break;case0x07:key=12;break;}temp=P3;Pl_0=>l_0;Portable[key];temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;}})P3=0xff;P3_7=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe: 18key=O;break;caseOxOd:key=13;break;case0x0b:key=14;break;case0x07:key=15;后PIOPl1P12PI3PI4P1.5P1.6P17氐8APOO/ADOPO1/AD1P0J/AD2P03/AD3P04/AD4PO5/ADSP0A/AD6PO7/AD7ALErawP3OmXDP3i/TXDP32ANT0P33/iSYTP34/TOP3VTIP36AVKP37/RDan7/A1SP26/A14P25/A13P24/A12P23/A11F22/A1OP21/A9P20/A8一前29万272625242r212rppppp-r-pP至X丞2322I>_20break;)temp=P3;Pl_0=>l_0;PO=table[key];temp=temp&OxOf;while(temp!=OxOf){temp=P3;temp=temp&OxOf;}}}}15.定时计数器TO作定时应用技术(一)1.实验任务用AT89s51单片机的定时/计数器TO产生一秒的定时时间,作为秒计数时间,当-秒产生时,秒计数加1,秒计数到60时,自动从0开始。硬件电路如下图所示2.电路原理图7.C语言源程序(查询法) 19ttinclude 207.C语言源程序ttinclude 21vccP31WRXDP31/TXDP32疝行5P33/UHTP34/T0P35dP36远P37/RDV)S8Uw科RS玄块plplplplplplplpl18>POO/ADOPO1/AD1P02/AD2P03/AD3PO4/AD4POVADSP06/AD6PO7/AD7ALE 226.C语言源程序ttinclude 23voidtO(void)interrupt1using0{tcnt++;if(tcnt==400){tcnt=0;second++;18.“嘀、嘀、.”报警声if(second==100){second=0;}PO=dispcode[second/10];P2=dispcode[second%10];}I.实验任务:用AT89s51单片机产生“嘀、嘀、…”报警声从PL0端口输出,产生频率为lKHz,根据上面图可知:1KHZ方波从P1.0输出0.2秒,接着0.2秒从PL0输出电平信号,如此循环下去,就形成我们所需的报警声了。GNDIIVCCVS-7-1IN.VOUT-jIN.GAIN-x-BYPASS0AIN---GNDGHDLM386C31归NDc.||0047uFGNDLSISPKOUTOND_EAMxlo6w-zdomd二wdurd二wss三nB-L2fLOd9avzodsawsodKWbOdssodravRod-aw-odoawoodVCC一RSTo—八9匚:2ESEdEqmd一OKZUNndCKl'IEd0OSSU2AT您51(1.生活中我们常常到各种各样的报警声,例如“嘀、嘀、…”就是常见的一种声音报警声,但对于这种报警声,嘀0.2秒钟,然后断0.2秒钟,如此循环下去,假设嘀声的频率为IKHz,则报警声时序图如下图所示:1KHZ波形电平信号 24上述波形信号如何用单片机来产生呢?(2.由于要产生上面的信号,我们把上面的信号分成两部分,一部分为1KHZ方波,占用时间为0.2秒;另一部分为电平,也是占用0.2秒;因此,我们利用单片机的定时/计数器T0作为定时,可以定时0.2秒;同时,也要用单片机产生1KHZ的方波,对于1KHZ的方波信号周期为1ms,高电平占用0.5ms,低电平占用0.5ms,因此也采用定时器TO来完成0.5ms的定时;最后,可以选定定时/计数器T0的定时时间为0.5ms,而要定时0.2秒则是0.5ms的400倍,也就是说以0.5ms定时400次就达到0.2秒的定时时间了。7.C语言源程序#include 253.系统板上硬件连线(1.把“单片机系统”区域中的PLO端口用导线连接到“音频放大模块”区域中的SPKIN端口上;(2.在“音频放大模块”区域中的SPKOUT端口上接上一个8欧或者是16欧的喇叭;(3.把“单片机系统”区域中的P3.7/RD端口用导线连接到“独立式键盘”区域中的SP1端口上;4.程序设计方法(1.我们用单片机实定时/计数器TO来产生7OOHZ和500HZ的频率,根据定时/计数器TO,我们取定时250us,因此,700Hz的频率要经过3次250us的定时,而500Hz的频率要经过4次250us的定时。(2.在设计过程,只有当按下SP1之后,才启动T0开始工作,当T0工作完毕,回到最初状态。(3.“叮”和“咚”声音各占用0.5秒,因此定时/计数器T0要完成0.5秒的定时,对于以250us为基准定时2000次才可以。7.C语言源程序#include 26else{t5hz++;if(t5hz=4)20.数字钟(★){t5hz=0;Pl_0=>l_0;}}1.实验任务(1.开机时,显示12:00:00的时间开始计时;(2.P0.0/AD0控制“秒”的调整,每按一次加1秒;(3.P0.1/AD1控制“分”的调整,每按一次加1分;(4.P0.2/AD2控制“时”的调整,每按一次加1个小时;2.电路原理图4:1寸YJon(Nqsss日日日日di3Pp(JMSUILED84sdyJcnzqsss日日日日3PpUMSU2LED84s---Rl560t/i:-j-igndH~~||pct三三—«3QC2AT89s51HI||gndaxwtdaxur&iP5£LIASW9cd艮6MeEAvecmodzavRodmav品ods<^8gav0od9avD0dCawoodTIVNas□IwczdEIVKZduzdHV/EZd2VRa6 27(1.把“单片机系统”区域中的Pl.o—P1.7端口用8芯排线连接到“动态数码显示"区域中的A-H端口上;(2.把“单片机系统:区域中的P3.0—P3.7端口用8芯排线连接到“动态数码显示"区域中的S1—S8端口上;(3.把“单片机系统”区域中的PO.O/ADO、PO.1/ADLP0.2/AD2端口分别用导线连接到“独立式键盘”区域中的SP3、SP2、SP1端口上;7.C语言源程序#include 28tcnt++;if(tcnt==4000){tcnt=O;second++;if(second==60){second=0;minite++;if(minite==60){minite=O;hour++;if(hour==24){hour=0;}})dispbuf[0]=second%10;dispbuf[1]=second/10;dispbuf[3]=minite%10;dispbuf[4]=minite/10;dispbuf[6]=hour%10;dispbuf[7]=hour/10;}21.拉幕式数码显示技术1.实验任务:用AT89S51单片机的PO.O/ADO-PO.7/AD7端口接数码管的a-h端,8位数码管的S1-S8通过74LS138译码器的Y0-Y7来控制选通每个数码管的位选端。AT89S51单片机的Pl.0-P1.2控制74LS138的A,B,C端子。在8位数码管上从右向左循环显示“12345678”。能够比较平滑地看到拉幕的效果。2.电路原理图 29P07P06P05P04P03瓯POTPOOU1Y1GND|VCC|74LS138AB0.0.0.B.房酎房房IqI「「寸4।U。p。q•U4LEDU2AT89S51:Jt-L一eCEdPS2一INWdRNI/rgdoxtIEdD1GNXSV/OZd6VnZd2 30机的定时/计数器TO来控制,每定时1ms对数码管刷新一次,TO采用方式2o(2.在进行数码显示的时候,要对显示单元开辟8个显示缓冲区,每个显示缓冲区装有显示的不同数据即可。7.C语言源程序ttinclude 31for(i=0;i<8;i++){dispbuf[i]=16;}for(i=0;i 32(1.把“单片机系统”区域中的PLO端口用导线连接到“音频放大模块”区域中的SPKIN端口上;(2.把“单片机系统“区域中的P3.0—P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1—C4R1—R4端口上;3.相关程序内容(1.4X4行列式键盘识别;(2.音乐产生的方法;一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器TO来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数TO相关的计数值如下表所示音符频率(HZ)简谱码(T值)音符频率(HZ)简谱码(T值)低1DO26263628#4FA#74064860#1DO#27763731中5so78464898低2RE29463835#5SO#83164934#2RE#31163928中6LA88064968低3M33064021#693264994低4FA34964103中7sl98865030#4FA#37064185高1DO104665058低5SO39264260#1DO#110965085#5SO#41564331in]2RE117565110低6LA44064400#2RE#124565134#646664463高3M131865157低7SI49464524高4FA139765178中1DO52364580#4FA#148065198#1DO#55464633高5so156865217中2RE58764684#5SO#166165235#2RE#62264732高6LA176065252中3M65964777#6186565268中4FA69864820高7sl1967652832、音乐的音拍,一个节拍为单位(C调)曲调值DELAY曲调值DELAY调4/4125ms调4/462ms调3/4187ms调3/494ms调2/4250ms调2/4125ms对于不同的曲调我们也可以用单片机的另外•个定时/计数器来完成。 33下面就用AT89S51单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。在这个程序中用到了两个定时/计数器来完成的。其中TO用来产生音符频率,T1用来产生音拍。7.C语言源程序#include 34caseOxOb:key=2;break;case0x07:key=3;break;)temp=P3;Pl_0=>l_0;PO=table[key];STH0=tab[key]/256;STL0=tab[key]%256;TRO=1;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;}TRO=O;})P3=0xff;P3_5=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i一一)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=4;break;caseOxOd:key=5;break;case0x0b:key=6;break;case0x07:key=7;break;}temp=P3;Pl_0=>l_0;PO二table[key];STH0=tab[key]/256;STL0=tab[key]%256;TRO=1;temp=temp&OxOf;while(temp!=OxOf){temp=P3;temp=temp&OxOf;}TRO=O;})P3=0xff; 35P3_6=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i-)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=8;break;caseOxOd:key=9;break;case0x0b:key=10;break;case0x07:key=ll;break;)temp=P3;P1_O=>1_O;PO二table[key];STH0=tab[key]/256;STL0=tab[key]%256;TRO=1;temp=temp&OxOf;while(temp!=OxOf){temp=P3;temp=temp&OxOf;}TRO=O;})P3=0xff;P3_7=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i-)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=12;break;caseOxOd:key=13;break;case0x0b:key=14;break; 36case0x07:key=15;break;)temp=P3;P1_O="P1_O;PO二table[key];STH0=tab[key]/256;STL0=tab[key]%256;TRO=1;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;)TRO=O;}}})voidtO(void)interrupt1using0{THO=STHO;TLO=STLO;Pl_0=>l_0;23.模拟计算器数字输入及显示1.实验任务(1.开机时,显示“0”(2.第一次按下时,显示“D1”;第二次按下时,显示“D1D2”;第三按下时,显示“D1D2D3”,8个全显示完毕,再按下按键下时,给出“嘀”提示音。2.电路原理图 374Msas•JK♦WKVKwfcK与£6r£(NfKSE•?Koxss(wsQ3S图4.23.11.系统板上硬件连线(1.把“单片机系统”区域中的PL0端口用导线连接到“音频放大模块”区域中的SPKIN端口上;(2.把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4R1-R4端口上;(3.把“单片机系统”区域中的P0.0—P0.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上;(4.把“单片机系统:区域中的P2.0—P2.7端口用8芯排线连接到“动态数码显示"区域中的S1—S8端口上;6.C语言源程序ttinclude 38dispbitcode[]={Oxfe,Oxfd,Oxfb,Oxf7,Oxef,Oxdf,Oxbf,0x7f};unsignedchardispbuf[8]={0,16,16,16,16,16,16,16}unsignedchardispbitcount;unsignedchartemp;unsignedchari,j;unsignedcharkey;unsignedcharkeypos;bitalarmflag;voidchange(unsignedchar*p,unsignedcharcount){while(count>0){*(p+count)=*(p+count-1);count一一;)}voidmain(void){TM0D=0x01;THO=(65536-4000)/256;TLO=(65536-4000)%256;TRO=1;ETO=1;EA=1;while(l){P3=0xff;P3_4=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i-)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=7;break;caseOxOd:key=8;break;case0x0b:key=9;break;case0x07:key=10;break;) 39if((key>=0)&&(key<10)){keypos++;if(keypos<8){change(dispbuf,keypos);dispbuf[0]=key;)else{keypos=8;alarmflag=l;)}temp=P3;P1_O="P1_O;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;}alarmflag=O;)}P3=0xff;P3_5=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i—)for(j=200;j>0;j-);temp=P3;temp=temp&OxOf;if(temp!二OxOf){temp=P3:temp=temp&OxOf;switch(temp){caseOxOe:key=4;break;caseOxOd:key=5;break;case0x0b:key=6;break;case0x07:key=ll;break;}if((key>=0)&&(key<10)){keypos++;if(keypos<8){change(dispbuf,keypos);dispbuf[0]=key;)else{keypos=8;alarmflag=l;)}temp=P3;P1_O="P1_O;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;}alarmflag=0;}) 40P3=0xff;P3_6=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j");temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=l;break;caseOxOd:key=2;break;caseOxOb:key=3;break;case0x07:key=12;break;)if((key>=0)&&(key<10)){keypos++;if(keypos<8){change(dispbuf,keypos);dispbuf[0]=key;}else{keypos=8;alarmflag=l;})temp=P3;Pl_0=>l_0;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;)alarmflag=0;}) 41P3=0xff;P3_7=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=50;i>0;i-)for(j=200;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=O;break;caseOxOd:key=13;break;caseOxOb:key=14;break;case0x07:key=15;break;)if((key>=0)&&(key<10)){keypos++;if(keypos<8){change(dispbuf,keypos);dispbuf[0]=key;}else{keypos=8;alarmflag=l;))temp=P3;Pl_0=>l_0;temp=temp&OxOf;while(temp!=0x0f){temp=P3;temp=temp&OxOf;)alarmflag=0; 42voidtO(void)interrupt1using0{THO=(65536-4000)/256;TLO=(65536-4000)%256;PO=dispcode[dispbuf[dispbitcount]];P2=dispbitcode[dispbitcount];dispbitcount++;if(dispbitcount==8){dispbitcount=0;)if(alarmflag=l) 4324.8X8LED点阵显示技术1.实验任务在8X8LED点阵上显示柱形,让其先从左到右平滑移动三次,其次从右到左平滑移动三次,再次从上到下平滑移动三次,最后从下到上平滑移动三次,如此循环下去。2.电路原理图VCCjii~■RST12MHzGND788765432£PloP)1Pl.2Pl.3Pl6Pl.7UR2CR3CR4CR5CR6CR7CR8P3O/RXDP3l/TXDP32/fNTOP3.3/fNTTP3.4/T0P3S/TlP36/WRP37/RD-APOO/ADOPO1/AD1PO2/AD2POJ3/AD3PO4/AD4PO5/AD5PO6/AD6PO7/AD7ALEPSENP27/A15P26/A14P25/A13P2.4/A12P2^/A11P22/A10P21/A9P2O/A8§图4.24.13.硬件电路连线(1).把“单片机系统”区域中的P1端口用8芯排芯连接到“点阵模块”区域中的"DR1-DR8”端口上;(2).把“单片机系统”区域中的P3端口用8芯排芯连接到“点阵模块”区域中的“DC1—DC8”端口上;4.程序设计内容 44(1).8X8点阵LED工作原理说明8X8点阵LED结构如下图所示图4.24.2从图4.24.2中可以看出,8X8点阵共需要64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一列置1电平,某一行置0电平,则相应的二极管就亮;因此要实现一根柱形的亮法,如图49所示,对应的一列为一根竖柱,或者对应的一行为一根横柱,因此实现柱的亮的方法如下所述:一根竖柱:对应的列置1,而行则采用扫描的方法来实现。一根横柱:对应的行置0,而列则采用扫描的方法来实现。6.C语言源程序#include 45voiddelay(void){unsignedchari,j;for(i=10;i>0;i")for(j=248;j>0;j—);voiddelayl(void){unsignedchari,j,k:for(k=10;k>0;k-)for(i=20;i>0;i—)for(j=248;j>0;j—);)voidmain(void){unsignedchari,j;while(l){for(j=0;j<3;j++)//fromlefttoright3timefor(i=0;i<8;i++){P3=taba[i];Pl=0xff;delayl();}for(j=0;j<3;j++)//from{for(i=0;i<8;i++){P3=taba[7-i];Pl=0xff;delayl();})for(j=0;j<3;j++)//from{for(i=0;i<8;i++){P3=0x00;Pl=tabb[7-i];delayl();}}for(j=0;j<3;j++)//from{for(i=0;i<8;i++){P3=0x00;Pl=tabb[i];delayl();}}}}righttoleft3timetoptobottom3timebottomtotop3time25.点阵式LED“0—9”数字显示技术1.实验任务利用8X8点阵显示数字0到9的数字。2.电路原理图 46vccjjl^■RSTPl.7i-':R21OKUR2CRJCR4CR5CR687654321sLai33aBiR7O§£PloPl1Pl.2Pl.3Pl4P3O/RXDP31/TXDP32/INTOP3.3/1NT1P34/TOP35/T1P36/WRP37/RD-POO/ADOPO1/AD1PO2/AD2PO3/AD3PO4/AD4PO5/ADSPO6/AD6PO7/AD7ALEPSENP27/A15P26/A14P25/A13P24/A12P23/A11P22/A10P21/A9P20/A8aL2MHzC23OpGND图4.25.13.硬件系统连线(1).把“单片机系统”区域中的P1端口用8芯排芯连接到“点阵模块”区域中的“DR1-DR8”端口上;(2).把“单片机系统”区域中的P3端口用8芯排芯连接到“点阵模块”区域中的“DC1-DC8”端口上;4.程序设计内容(1).数字0—9点阵显示代码的形成如下图所示,假设显示数字“0”1234567800003E4141413E00因此,形成的列代码为OOH,OOH,3EH,41H,41H,3EH,OOH,00H;只要把这些代码分别送到相应的列线上面,即可实现“0”的数字显示。 47送显示代码过程如下所示送第一列线代码到P3端口,同时置第一行线为“0”,其它行线为“1”,延时2ms左右,送第二列线代码到P3端口,同时置第二行线为“0”,其它行线为“1”,延时2ms左右,如此下去,直到送完最后一列代码,又从头开始送。数字“1”代码建立如下图所示12345678其显示代码为OOH,OOH,OOH,OOH,21H,7FH,01H,00H数字“2”代码建立如下图所示12345678 48数字“3”代码建立如下图所示OOH,OOH,22H,49H,49H,49H,36H,OOH数字“4”代码建立如下图所示OOH,OOH,OCH,14H,24H,7FH,04H,OOH数字“5”代码建立如下图所示12345678 49数字“6”代码建立如下图所示OOH,OOH,3EH,49H,49H,49H,26H,OOH数字“7”代码建立如下图所示OOH,OOH,40H,40H,40H,4FH,70H,OOH数字“8”代码建立如下图所示12345678数字“9”代码建立如下图所示 50OOH,OOH,32H,49H,49H,49H,3EH,OOH6.C语言源程序#include 51{;})voidtO(void)interrupt1using0{TH0=(65536-3000)/256;TL0=(65536-3000)%256;P3=tab[cnta];Pl=digittab[cntb][cnta];cnta++;if(cnta==8){cnta=0;)timecount++;if(timecount==333){timecount=0;cntb++;if(cntb==10){cntb=0;}}26.点阵式LED简单图形显示技术1.实验任务在8X8点阵式LED显示“★”、和心形图,通过按键来选择要显示的图形。2.电路原理图 52UI8XBLEDQOQQQOQO-UCR2CR3CR4CR5CR6CR7CR8vcc」142R79』RSPl.5Pl.6Pl.7451011121314151617S2P1.0P0.0/AD0P0.1/AD1P0.2/AD2P03/AD3P0.4/AD4P0.5/AD5PO.6/ADI5P0.7/AD7P3.0/RXDP3.1/TXDP3.2/Pmpss/nm-P3.4/T0P3.5/T1P3.6/WP3.7/RD"PSQJP2.7/A15P2.6/A14P2.5/ABP2.4/A12P23/A11P2.2/A10P2.1/A9P2.0借XOAT89s518Y1612MHzGND图4.26.11.硬件系统连线(1).把“单片机系统”区域中的P1端口用8芯排芯连接到“点阵模块”区域中的“DR1-DR8”端口上;(2).把“单片机系统”区域中的P3端口用8芯排芯连接到“点阵模块”区域中的“DC1-DC8”端口上;(3).把“单片机系统”区域中的P2.0/A8端子用导线连接到“独立式键盘”区域中的SP1端子上;2.程序设计内容(1).“★”在8X8LED点阵上显示图如下图所示 5312345678(1).“•”在8X8LED点阵上显示图如下图所示12345678(2).心形图在8X8LED点阵上显示图如下图所示12345678•*••*••**••*••30H,48H,44H,22H,44H,48H,30H,00H6.C语言源程序Sinclude 54unsignedcharcodegraph[3][8]={{0x12,0x14,0x3c,0x48,0x3c,0x14,0x12,0x00},{0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00},{0x30,0x48,0x44,0x22,0x44,0x48,0x30,0x00));unsignedcharcount;unsignedcharcnta;voidmain(void){unsignedchari,j;TM0D=0x01;THO=(65536-4000)/256;TLO=(65536-4000)%256;TRO=1;ETO=1;EA=1;while(l){if(P2_0==0){for(i=5;i>0;i-)for(j=248;j>0;j—);if(P2_0==0){count++;if(count==3){count=0;)while(P2_0==0);}}})voidtO(void)interrupt1using0{THO=(65536-4000)/256;TLO=(65536-4000)%256;P3=tab[cnta];Pl=graph[count][cnta];cnta++;if(cnta==8){cnta=0;}27.ADC0809A/D转换器基本应用技术 551EN3DST2IN4IN1IN5INOIN6AIN7BSTCEOCALED3D7OED6CLKD5VCCD4VREF+DOGNDVRE『1)1D2282273264255246237228219201O191118121713161415ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。它是逐次逼近式A/D转换器,可以和单片机直接接口。(1).ADC0809的内部逻辑结构8路A/D转换器态输出锁存器由上图可知,ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用A/D转换器进行转换。三态输出锁器用于锁存A/D转换完的数字量,当0E端为高电平时,才可以从三态输出锁存器取走转换完的数据。(2).引脚结构IN0-IN7:8条模拟量输入通道ADC0809对输入模拟量要求:信号单极性,电压范围是0—5V,若信号太小,必须进行放大;输入的模拟量在转换过程中应该保持不变,如若模拟量变化太快,则需在输入前增加采样保持电路。地址输入和控制线:4条ALE为地址锁存允许输入线,高电平有效。当ALE线为高电平时,地址锁存与译码器将A,B,C三条地址线的地址信号进行锁存,经译码后被选中的通道的模拟量进转换器进行转换。A,B和C为地址输入线,用于选通IN0-IN7上的一路模拟量输入。通道选择表如下表所示。cBA选择的通道000INO001IN1 56010IN20111\3100IN4101IN5110IN6111IN7数字量输出及控制线:11条ST为转换启动信号。当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。0E为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到的数据;0E=0,输出数据线呈高阻状态。D7-D0为数字量输出线。CLK为时钟输入信号线。因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频率为500KHZ,VREF(+),VREF(-)为参考电压输入。2.ADC0809应用说明(1).ADC0809内部带有输出锁存器,可以与AT89s51单片机直接相连。(2).初始化时,使ST和0E信号全为低电平。(3).送要转换的哪一通道的地址到A,B,C端口上。(4).在ST端给出一个至少有100ns宽的正脉冲信号。(5).是否转换完毕,我们根据EOC信号来判断。(6).当E0C变为高电平时,这时给0E为高电平,转换的数据就输出给单片机了。3.实验任务如下图所示,从ADC0809的通道IN3输入0—5V之间的模拟量,通过ADC0809转换成数字量在数码管上以十进制形成显示出来。ADC0809的VREF接+5V电压。4.电路原理图 57H«gPIDnOfADOPiJKIMDIPI2POMkSPt3POJMkDSPl,P04UD«Pl3P0MLD5Plipo6aMH?PO皿,ALXKfif”8XDF2MHSP31/TXDP234P32tmTD92MH3PJJifilTTF24ai2P3«/n)P23/AHnsfnP22a)oP36^ntP2HA9如何gg*C5_c4a等fr-MalobwMOQk$4;$3abEEE三sBm・4#<“€?LID041・141»lc.MI图1.27.12.系统板上硬件连线(1).把“单片机系统板”区域中的P1端口的PL0-PL7用8芯排线连接到“动态数码显示"区域中的ABCDEFGH端口上,作为数码管的笔段驱动。(2).把“单片机系统板”区域中的P2端口的P2.0—P2.7用8芯排线连接到“动态数码显示"区域中的SIS2S3S4S5S6S7S8端口上,作为数码管的位段选择。(3).把“单片机系统板”区域中的P0端口的PO.O-PO.7用8芯排线连接到“模数转换模块”区域中的D0D1D2D3D4D5D6D7端口上,A/D转换完毕的数据输入到单片机的P0端口(4).把“模数转换模块”区域中的VREF端子用导线连接到“电源模块”区域中的VCC端子上:(5).把“模数转换模块”区域中的A2A1A0端子用导线连接到“单片机系统”区域中的P3.4P3.5P3.6端子上;(6).把“模数转换模块”区域中的ST端子用导线连接到“单片机系统”区域中的P3.0端子上;(7).把“模数转换模块”区域中的0E端子用导线连接到“单片机系统”区域中的P3.1端子上;(8).把“模数转换模块”区域中的EOC端子用导线连接到“单片机系统”区 58域中的P3.2端子上;(1).把“模数转换模块”区域中的CLK端子用导线连接到“分频模块”区域中的/4端子上;(2).把“分频模块”区域中的CKIN端子用导线连接到“单片机系统”区域中的ALE端子上;(3).把“模数转换模块”区域中的IN3端子用导线连接到“三路可调压模块”区域中的VR1端子上;2.程序设计内容(1).进行A/D转换时,采用查询E0C的标志信号来检测A/D转换是否完毕,若完毕则把数据通过P0端口读入,经过数据处理之后在数码管上显示。(2).进行A/D转换之前,要启动转换的方法:ABC=U0选择第三通道ST=0,ST=1,ST=0产生启动转换的正脉冲信号8.C语言源程序#include 59{ST=O;ST=1;ST=O;while(EOC==O);OE=1;getdata=PO;0E=0;dispbuf[2]=getdata/100;getdata=getdata%10;dispbuf[1]=getdata/10;dispbuf[0]=getdata%10;))voidtO(void)interrupt1using0(THO=(65536-4000)/256;TL0=(65536-4000)%256;Pl=dispcode[dispbuf[dispcount]];P2=dispbitcode[dispcount];dispcount++;if(dispcount==8){dispcount=0;}28.数字电压表1.实验任务:利用单片机AT89s51与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,但要求使用的元器件数目最少。2.电路原理图 60P3O/RXDP3EDP32IWTQP334NTTP34/TOP3^fTlP36^P37/RDO1234CJ67PIPIP1PIP1P1P1P134<1--6-7I-1TT-128272625”sl:dpba$3f。$4_C2C3C4C5C6C7_C8>POO/ADOPO1/AD1P02/AD2P03/AD3P04/AD4P05/AD5P067AD6PO7/AD7ALEKENP27/A15P26/A14P2MU3P24/A12P23/AUP22/A10P21/A9P20/A8图1.28.11.系统板上硬件连线a)把“单片机系统”区域中的PL0—P1.7与“动态数码显示"区域中的ABCDEFGH端口用8芯排线连接。b)把“单片机系统”区域中的P2.0—P2.7与“动态数码显示"区域中的SIS2s3s4s5s6s7s8端口用8芯排线连接。c)把“单片机系统”区域中的P3.0与“模数转换模块”区域中的ST端子用导线相连接。d)把“单片机系统”区域中的P3.1与“模数转换模块”区域中的0E端子用导线相连接。e)把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接。f)把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接。 61g)把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上。h)把“模数转换模块”区域中的INO端子用导线连接到“三路可调电压模块”区域中的VR1端子上。i)把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“模数转换模块”区域中的D0D1D2D3D4D5D6D7端子上。1.程序设计内容i.由于ADC0809在进行A/D转换时需要有CLK信号,而此时的ADC0809的CLK是接在AT89S51单片机的P3.3端口上,也就是要求从P3.3输出CLK信号供ADC0809使用。因此产生CLK信号的方法就得用软件来产生了。ii.由于ADC0809的参考电压VREF=VCC,所以转换之后的数据要经过数据处理,在数码管上显示出电压值。实际显示的电压值(D/256*VREF)6.C语言源程序#include 62ST=1;ST=0;while(l){if(EOC=D{0E=l;getdata=P0;0E=0;temp=getdata*235;temp=temp/128;i=5;dispbuf[0]=10;dispbufLl]=10;dispbuf[2]=10;dispbufL3]=10;dispbuf[4]=10;dispbuf[5]=0;dispbuf[6]=0;dispbufL7]=0;while(temp/10){dispbuf[i]=temp%10;temp=temp/10;i++;)dispbuf[i]=temp;ST=1;ST=0;}))voidtO(void)interrupt1using0{CLK=~CLK;}voidtl(void)interrupt3using0{TH1=(65536-4000)/256;TL1=(65536-4000)%256;Pl=dispcode[dispbuf[dispcount]];P2=dispbitcode[dispcount];if(dispcount==7){P1=P1|0x80; 63dispcount++;if(dispcount==8){dispcount=0;}29.两点间温度控制1.实验任务:用可调电阻调节电压值作为模拟温度的输入量,当温度低于30℃时,发出长嘀报警声和光报警,当温度高于60c时,发出短嘀报警声和光报警。测量的温度范围在0—99C。2.电路原理图OmEOC7OEMX卜GND卜U28tOluF7GNDL1D8网8)OJO+TxiFVOUIGAINGMHGHDDInnIHOABIH+nrBYPxrrGNDg10K*♦70_91。ri13BmEGMilbfisfaaGNDALED7D 643.系统板上硬件连线a)把“单片机系统”区域中的PL0-PL7与“动态数码显示"区域中的ABCDEFGH端口用8芯排线连接。b)把“单片机系统”区域中的P2.0—P2.7与“动态数码显示"区域中的S1S2S3S4S5S6S7S8端口用8芯排线连接。c)把“单片机系统”区域中的P3.0与“模数转换模块”区域中的ST端子用导线相连接。d)把“单片机系统”区域中的P3.1与“模数转换模块”区域中的0E端子用导线相连接。e)把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接。f)把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接。g)把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上。h)把“模数转换模块”区域中的INO端子用导线连接到“三路可调电压模块”区域中的VR1端子上。i)把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“模数转换模块”区域中的D0D1D2D3D4D5D6D7端子上。j)把“单片机系统”区域中的P3.6、P3.7用导线分别连接到“八路发光二极管指示模块”区域中的LI、L2±ok)把“单片机系统”区域中的P3.5用导线连接到“音频放大模块”区域中的SPKIN端口上。1)把“音频放大模块“区域中的SPKOUT插入音频喇叭。5.C语言源程序#include 65unsignedinttemp;unsignedchari;sbitST=P3"0;sbitOE=P3'1;sbitE0C=P3c2;sbitCLK=P3*3;sbitLED1=P3*6;sbitLED2=P3*7;sbitSPK=P3c5;bitlowflag;bithighflag;unsignedintcnta;unsignedintcntb;bitalarmflag;voidmain(void){ST=0;0E=0;TM0D=0xl2;TH0=0x216;TL0=0x216;TH1=(65536-500)/256;TL1=(65536-500)%256;TR1=1;TRO=1;ETO=1;ET1=1;EA=1;ST=1;ST=0:while(l){if((lowflag==l)&&(highflag==0)){LED1=O;LED2=1;}elseif((highflag==l)&&(lowflag==0)){LED1=1;LED2=0;)else{LED1=1;LED2=1;}}}voidtO(void)interrupt1using0{CLK—CLK;}voidtl(void)interrupt3using0{TH1=(65536-500)/256; 66TL1=(65536-500)%256;if(EOC==l){0E=l;getdata=P0;0E=0;temp=getdata*25;temp=temp/64;i=6;dispbuf[0]=10;dispbuf[l]=10;dispbuf[2]=10;dispbuf[3]=10;dispbuf[4]=10;dispbuf[5]=10;dispbuf[6]=0;dispbuf[7]=0;while(temp/10){dispbuf[i]=temp%10;temp=temp/10;i++;)dispbuf[i]=temp;if(getdata<77){lowflag=l;highflag=0;)elseif(getdata>153){lowflag=0;highflag=l;)else{lowflag=0;highflag=0;}ST=1;ST=0;}Pl=dispcode[dispbuf[dispcount]];P2=dispbitcode[dispcount];dispcount++;if(dispcount==8){dispcount=0;}if((lowflag==l)&&(highflag==O)){cnta++;if(cnta==800){cnta=O;a1armf1ag=〜a1armflag; 67)if(alarmflag==l){SPK—SPK;})elseif((lowflag==O)&&(highflag==l)){cntb++;if(cntb==400){cntb=0;alarmflag=〜alarmflag;}if(alarmflag==l){SPK—SPK;})else{alarmflag=O;cnta=0;cntb=0;}30.四位数数字温度计1.温度传感器AD590基本知识AD590产生的电流与绝对温度成正比,它可接收的工作电压为4V—30V,检测的温度范围为-55℃—+150℃,它有非常好的线性输出性能,温度每增加1℃,其电流增加luA。AD590温度与电流的关系如下表所示摄氏温度AD590电流经10KQ电压0℃273.2uA2.732V10℃283.2uA2.832V20℃293.2uA2.932V30℃303.2uA3.032V40℃313.2uA3.132V50℃323.2uA3.232V60℃333.2uA3.332V100℃373.2uA3.732V 68AD590引脚图1.实验任务利用AD590温度传感器完成温度的测量,把转换的温度值的模拟量送入ADC0809的其中一个通道进行A/D转换,将转换的结果进行温度值变换之后送入数码管显/J\o2.电路原理图EOC78OE910gndTIN31X2IN4IM1IN5INOIN6▲IH7BSTCEOCALED3D7OED6CLKD5VCCD4VREF*DOQ«DVREF.D】D2UIAD59O28FlCLK)3II123635GSC3C4C5C6C7C8GND^JU3,;53s2bHHEU•d 69端子用导线相连接。(1).把“单片机系统”区域中的P3.1与“模数转换模块”区域中的0E端子用导线相连接。(2).把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接。(3).把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接。(4).把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上。(5).把“模数转换模块”区域中的INO端子用导线连接到自制的AD590电路上。(6).把“单片机系统”区域中的PO.0-P0.7用8芯排线连接到“模数转换模块”区域中的D0D1D2D3D4D5D6D7端子上。1.程序设计内容(1).ADC0809的CLK信号由单片机的P3.3管脚提供(2).由于AD590的温度变化范围在一55C-+150C之间,经过10KQ之后采样到的电压变化在2.182V-4.232V之间,不超过5V电压所表示的范围,因此参考电压取电源电压VCC,(实测VCC=4.70V)。由此可计算出经过A/D转换之后的摄氏温度显示的数据为:如果(D*2350/128)<2732,则显示的温度值为一(2732-(D*2350/128))如果(D*2350/128)22732,则显示的温度值为+((D*2350/128)-2732)7.C语言源程序Sinclude 70sbitST=P3"0;sbitOE=P3'1;sbitEOC=P3c2;sbitCLK=P3*3;sbitLED1=P3*6;sbitLED2=P3*7;sbitSPK=P3c5;voidmain(void){ST=0;0E=0;TM0D=0xl2;TH0=0x216;TL0=0x216;TH1=(65536-4000)/256;TL1=(65536-4000)%256;TR1=1;TRO=1;ETO=1;ET1=1;EA=1;ST=1;ST=0;getdata=148;while(l)(;))voidtO(void)interrupt1using0{CLK=_CLK;}voidtl(void)interrupt3using0{TH1=(65536-4000)/256;TL1=(65536-4000)%256;if(EOC==l){0E=l;getdata=P0;0E=0;temp=(getdata*2350);temp=temp/128;if(temp<2732){temp=2732-temp;sflag=l;}else{temp=temp-2732;sflag=O;}i=3;dispbuf[0]=10;dispbuf[l]=10;dispbuf[2]=10;if(sflag==l){dispbuf[7]=ll;}else{dispbuf[7]=10;}dispbuf[3]=0; 71dispbuf[4]=0;dispbuf[5]=0;dispbuf[6]=0;while(temp/10){dispbuf[i]=temp%10;temp=temp/10;i++;}dispbuf[i]=temp;ST=1;ST=O;}Pl=dispcode[dispbuf[dispcount]];P2=dispbitcode[dispcount];dispcount++;if(dispcount==8){dispcount=0;}31.6位数显频率计数器1.实验任务利用AT89s51单片机的TO、T1的定时计数器功能,来完成对输入的信号进行频率计数,计数的频率结果通过8位动态数码管显示出来。要求能够对0—250KHZ的信号频率进行准确计数,计数误差不超过±1HZ。2.电路原理图 72vccRSTISP30/RXDP31/TXDP324NT0P334NTTP34/TOP35mP36WRP37/RDaNOPIO二APO.O/ADOP0.1/AD1PO2/AD2P03/AD3P0.4/AD4P0.5/AD5P06/AD6PO7/AD7ALEPSENP27/A15P26/A14P25/A13P2.4/A12P23/A11P22/A10P21/A9P2.0/A812MHzGND.mtm:bS1m..?J图4.31.11.系统板上硬件连线(1).把“单片机系统”区域中的PO.0-P0.7与“动态数码显示"区域中的ABCDEFGH端口用8芯排线连接。(2).把“单片机系统”区域中的P2.0-P2.7与“动态数码显示"区域中的S1S2S3S4S5S6S7S8端口用8芯排线连接。(3).把“单片机系统”区域中的P3.4(TO)端子用导线连接到“频率产生器”区域中的WAVE端子上。2.程序设计内容(1).定时/计数器TO和T1的工作方式设置,由图可知,TO是工作在计数状态下,对输入的频率信号进行计数,但对工作在计数状态下的TO,最大计数值为fOSC/24,由于fOSC=12MHz,因此:TO的最大计数频率为250KHzo对于频率的概念就是在一秒只数脉冲的个数,即为频率值。 73所以T1工作在定时状态下,每定时1秒中到,就停止TO的计数,而从TO的计数单元中读取计数的数值,然后进行数据处理。送到数码管显示出来。(1).T1工作在定时状态下,最大定时时间为65ms,达不到1秒的定时,所以采用定时50ms,共定时20次,即可完成1秒的定时功能。1.C语言源程序#include 74{dispbuf[i]=temp[i];}timecount=0;T0count=0;TH0=0;TL0=0;TRO=1;}})voidtO(void)interrupt1using0{T0count++;}voidtl(void)interrupt3using0{TH1=(65536-4000)/256;TL1=(65536-4000)%256;timecount++;if(timecount==250){TR0=0;timecount=0;flag=l;}P0=dispcode[dispbuf[dispcount]];P2=dispbit[dispcount];dispcount++;if(dispcount==8){dispcount=0;}32.电子密码锁设计1.实验任务:根据设定好的密码,采用二个按键实现密码的输入功能,当密码输入正确之后,锁就打开,如果输入的三次的密码不正确,就锁定按键3秒钟,同时发现报警声,直到没有按键按下3种后,才打开按键锁定功能;否则在3秒钟内仍有按键按下,就重新锁定按键3秒时间并报警。2.电路原理图 75tBIrEIis生-£2VNMc£2,/9rdmdMJlvZHVKOdMVGOasovq£COWCOdZOVKM-OY二Od8 76由于采用两个按键来完成密码的输入,那么其中一个按键为功能键,另一个按键为数字键。在输入过程中,首先输入密码的长度,接着根据密码的长度输入密码的位数,直到所有长度的密码都已经输入完毕;或者输入确认功能键之后,才能完成密码的输入过程。进入密码的判断比较处理状态并给出相应的处理过程。(3).按键禁止功能:初始化时,是允许按键输入密码,当有按键按下并开始进入按键识别状态时,按键禁止功能被激活,但启动的状态在3次密码输入不正确的情况下发生的。5.C语言源程序Sinclude 77{if(cmpflag==O){if(P3_6==0)//functionkey{for(i=10;i>0;i-)for(j=248;j>0;j—);if(P3_6==0){if(hibitflag==0){funcount++;if(funcount==pslen+2){funcount=0;cmpflag=l;}Pl=dispcode[funcount];)else{second3=0;}while(P3_6==0);}}if(P3_7==0)//digitkey{for(i=10;i>0;i-)for(j=248;j>0;j—);if(P3_7==0){if(hibitflag==O){digitcount++;if(digitcount==10){digitcount=0;}P2=dispcode[digitcount];if(funcount==l){pslen=digitcount;templen=pslen;)elseif(funcount>l){psbuf[funcount_2]=digitcount;}}else{second3=0}while(P3_7==0);}}}else{cmpflag=0;for(i=0;i 78errorflag=0;rightflag=1;hibitflag=0;a:cmpflag=0;}}}voidtO(void)interrupt1using0{TH0=(65536-500)/256;TL0=(65536-500)%256;if((errorflag==l)&&(rightflag==0)){bb++;if(bb==800){bb=O;alarmf1ag=^a1armf1ag;}if(alarmflag==l){P0_0=>0_0;}aa++;if(aa==800){aa=0;P0_l=>0_l;)second3++;if(second3==6400){second3=0;hibitflag=O;errorflag=0;rightflag=0;cmpflag=0;P0_l=l;alarmflag=0;bb=O;aa=0;}}if((errorflag==0)&&(rightflag==l)){P0_l=0;cc++;if(cc<1000){okflag=l;}elseif(cc<2000){okflag=0;}else{errorflag=0;rightflag=0;hibitflag=O;cmpflag=O;PO_1=1;cc=O;oka=0;okb=0;okflag=0;PO_O=1;}if(okflag=l){oka++;if(oka==2){oka=0;P0_0=〜P0_0;}}else{okb++;if(okb==3){okb=0;PO_O="PO_O;}}} 7933.4x4键盘及8位数码管显示构成的电子密码锁1.实验任务1)用4义4组成0—9数字键及确认键。2)用8位数码管组成显示电路提示信息,当输入密码时,只显示“8.”,当密码位数输入完毕按下确认键时,对输入的密码与设定的密码进行比较,若密码正确,则门开,此处用LED发光二极管亮一秒钟做为提示,同时发出“叮咚”声;若密码不正确,禁止按键输入3秒,同时发出“嘀、嘀”报警声;若在3秒之内仍有按键按下,则禁止按键输入3秒被重新禁止。2.电路原理图 80s日日日日■一•©*9日日日日图4.33.11.系统板上硬件连线(1).把“单片机系统”区域中的PO.0-P0.7用8芯排线连接到“动态数码显示”区域中的ABCDEFGH端子上。(2).把“单片机系统“区域中的P2.0-P2.7用8芯排线连接到“动态数码显示”区域中的S1S2S3S4S5S6S7S8端子上。(3).把“单片机系统”区域中的P3.0-P3.7用8芯排线连接到“4X4行列式键盘”区域中的R1R2R3R4C1C2C3C4端子上。(4).把“单片机系统”区域中的PLO用导线连接到“八路发光二极管模块”区域中的L2端子上。(5).把“单片机系统”区域中的P1.7用导线连接到“音频放大模块”区域中的SPKIN端子上。 81789456123Dri0Enter4.程序设计内容(6).把“音频放大模块”区域中的SPKOUT接到喇叭上。(1).4X4行列式键盘识别技术:有关这方面内容前面已经讨论过,这里不再重复。”,接着输入最大6位数的进行密码比较,然后给出相应8位数码显示,初始化时,显示“P密码,当密码输入完后,按下确认键,的信息。在输入密码过程中,显示器只显示“8.”。当数字输入超过6个时,给出报警信息。在密码输入过程中,若输入错误,可以利用“DEL”键删除刚才输入的错误的数字。(3).4X4行列式键盘的按键功能分布图如图4.33.2所示:图4.33.25.C语言源程序ttinclude 82unsignedintseconds;unsignedintaa,bb;unsignedintcc;bitokflag;bitalarmflag;bithibitflag;unsignedcharoka,okb;voidmain(void){unsignedchari,j;TM0D=0x01;TH0=(65536-500)/256;TL0=(65536-500)%256;TRO=1;ET0=l;EA=1;while(l){P3=0xff;P3_4=0;temp=P3;temp=temp&OxOf;if(temp!=0x0f){for(i=10;i>0;i--)for(j=248;j>0;j-);temp=P3;temp=temp&OxOf;if(temp!=0x0f){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=7;break;caseOxOd:key=8;break;case0x0b:key=9;break;case0x07:key=10;break;)temp=P3;if((key>=0)&&(key<10)){if(keycount<6){getps[keycount]二key;dispbuf[keycount+2]=19;) 83keycount++;if(keycount==6){keycount=6;}elseif(keycount>6){keycount=6;keyoverflag=l;//keyoverflow})elseif(key==12)//deletekey{if(keycount>0){keycount—;getps[keycount]=0;dispbuf[keycount+2]=16;)else{keyoverflag=l;}}elseif(key==15)//enterkey{if(keycount!=pslen){errorflag=l;rightflag=0;second3=0;)else{for(i=0;i 84{for(i=10;i>0;i-)for(j=248;j>0;j—);temp=P3;temp=temp&OxOf;if(temp!-OxOf){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=4;break;caseOxOd:key=5;break;caseOxOb:key=6;break;case0x07:key=ll;break;)temp=P3;P1_1=>1_1;if((key>=0)&&(key<10)){if(keycount<6){getps[keycount]=key;dispbuf[keycount+2]=19;)keycount++;if(keycount==6){keycount=6;)elseif(keycount>6){keycount=6;keyoverflag=l;//keyoverflow}elseif(key==12)//deletekey{if(keycount>0){keycount—;getps[keycount]=0;dispbuf[keycount+2]=16;)else{keyoverflag=l;})elseif(key==15)//enterkey{if(keycount!=pslen){errorflag=l;rightflag=0; 85second3=0;}else{for(i=0;i 86break;}temp=P3;P1_1="P1_1;if((key>=0)&&(key<10)){if(keycount<6){getps[keycount]=key;dispbufLkeycount+2]=19;)keycount++;if(keycount==6){keycount=6;}elseif(keycount>6){keycount=6;keyoverflag=l;//keyoverflow)}elseif(key==12)//deletekey{if(keycount>0){keycount一;getps[keycount]=0;dispbuf[keycount+2]=16;}else{keyoverflag=l;}}elseif(key==15)//enterkey{if(keycount!=pslen){errorflag=l;rightflag=O;second3=0;)else{for(i=0;i 87temp=temp&OxOf;if(temp!=0x0f){for(i=10;i>0;i一一)for(>248temp=P3;temp=temp&OxOf;if(temp!=OxOf){temp=P3;temp=temp&OxOf;switch(temp){caseOxOe:key=O;break;caseOxOd:key=13;break;caseOxOb:key=14;break;case0x07:key=15;break;}temp=P3;P1_1=>1_1;if((key>=0)&&(key<10)){if(keycount<6){getps[keycount]=key;dispbuf[keycount+2]=19;)keycount++;if(keycount==6){keycount=6;)elseif(keycount>6){keycount=6;keyoverflag=l;//keyoverflow)}elseif(key==12)//deletekey{if(keycount>0){keycount—;getps[keycount]=0;dispbuf[keycount+2]=16;)else{keyoverflag=l;}}elseif(key==15)//enterkey 88{if(keycount!=pslen){errorflag=l;rightflag=0;second3=0;}else{for(i=0;i 89if((errorflag==l)&&(rightflag==0)){bb++;if(bb==800){bb=O;alarmflag=^a1armf1ag;}if(alarmflag==l)//soundalarmsignal{P1_7=>1_7;}aa++;if(aa==800)//lightalarmsignal{aa=O;P1_O="P1_O;)second3++;if(second3=6400){second3=0;errorflag=0;rightflag=O;alarmflag=O;bb=O;aa=O;))elseif((errorflag==O)&&(rightflag==l)){Pl_0=0;cc++;if(cc<1000){okflag=l;}elseif(cc<2000){okflag=0;}else{errorflag=0;rightflag=O;Pl_7=l;cc=0;oka=0;okb=0;okflag=0;Pl_0=l;)if(okflag=l){oka++;if(oka=2){oka=0;P1_7=>1_7; 90else{okb++;if(okb=3){okb=0;P1_7=>1_7;}}if(keyoverflag==l) 91{P1_7=~P1_7;}}SDASCI.NC(3NI>匚匚I匚-“34.带有存储器功能的数字温度计一DS1624技术应13AnnA'中=1,用1.DS1624基本原理DS1624是美国DALLAS公司生产的集成了测量系统和存储器于…体的芯片。数字接口电路简单,与12c总线兼容,且可以使用一片控制器控制多达8片的DS1624o其数字温度输出达13位,精度为0.03125C。DS1624可工作在最低2.7V电压下,适用于低功耗应用系统。(1).DS1624基本特性♦无需外围元件即可测量温度♦测量范围为-55c〜+125C,精度为0.03125c♦测量温度的结果以13位数字量(两字节传输)给出♦测量温度的典型转换时间为1秒♦集成了256字节的E2PROM非易性存储器♦数据的读出和写入通过一个2一线(I2C)串行接口完成♦采用8脚DIP或S0IC封装,如图2.34.1图2.34.1(2).引脚描述及功能方框图其引脚描述如表1所示: 92表1DS1624弓弓|脚・冷哥Q1CSDA72一线(PC)甲行数据输入府出•,2^SCX<2一线(PC)串行时钟竭.3~ZC~未连持一4—GZE>・」地.5AA2・>后选地址输入A2~6"Al«,片本地址输入A27・、AO*,首选地址幅入A0.、8“Vdd/电漉谕(+2.7V~+5.5V)aDS1624的功能结构图如图4.34.2所示:A。二Al二A2.GNDj.~~地址及IO控利状态寄存需及控制适辑•温度传感器•EWROM存储器(256字节)DS1624内幅结杓图图4.34.2(3).DS1624温度测量工作原理图4.34.3是温度测量的原理结构图 93图4.34.3温度测量的原理结构图DS1624在测量温度时使用了独有的在线温度测量技术。它通过在一个由对温度高度敏感的振荡器决定的计数周期内对温度低敏感的振荡器时钟脉冲的计数值的计算来测量温度。DS1624在计数器中预置了一个初值,它相当于一55C。如果计数周期结束之前计数器达到0,已预置了此初值的温度寄存器中的数字就会增加,从而表明温度高于一55C。与此同时,计数器斜坡累加电路被重新预置一个值,然后计数器重新对时钟计数,直到计数值为0。通过改变增加的每1C内的计数器的计数,斜坡累加电路可以补偿振荡器的非线性误差,以提高精度,任意温度下计数器的值和每一斜坡累加电路的值对应的计数次数须为已知。DS1624通过这些计算可以得到0.03125c的精度,温度输出为13位,在发出读温度值请求后还会输出两位补偿值。表2给出了所测的温度和输出数据的关系。这些数据可通过2线制串行口连续输出,MSB在前,LSB在后。表2温度与输出数据关系表温度数字量输出(二进制)数字量输出(十六进制)+125℃0111,1101,0000,00007D00H+25.0625℃0001,1001,0001,00001910H+0.5℃0000,0000,1000,00000080H+0℃0000,0000,0000,00000000H-0.5℃1111,1111,1000,0000FF80H-25.0625℃1110,0110,1111,0000E6F0H-55℃1100,1001,0000,0000C900H由于数据在总线上传输时MSB在前,所以DS1624读出的数据可以是一个字节(分辨率为1℃),也可以是两个字节,第二个字节包含的最低位为0.03125C。 94表2是13位温度寄存器中存储温度值的数据格式1111高八位字节低八位字节SB14B13B12B11B10B9B8B7B6B5B4B3000表3温度值的数据存储格式其中S-为符号位,当S=0时,表示当前的测量的温度为正的温度;当S=1时,表示当前的测量的温度为负的温度。B14-B3为当前测量的温度值。最低三位被设置为OoDS1624工作方式DS1621的工作方式是由片上的配置/状态寄存器来决定的,如表4,该寄存器的定义如下:表4配置/状态寄存器格式DONE1001011SH0T其中DONE为转换完成位,温度转换结束时置1,正在进行转换时为0;1SHOT为温度转换模式选择。1SH0T为1时为单次转换模式,DS1624在收到启动温度转换命令EEH后进行一次温度转换。1SH0T为0时为连续转换模式,此时DS1624将连续进行温度转换,并将最近一次的结果保存在温度寄存器中。该位为非易失性的。片内256字节存储器操作控制器对DS1624的存储器编程有两种模式:一种是字节编程模式,另一种是页编程模式。在字节编程模式中,主控制器发送地址和一个字节的数据到DS1624O在主器件发出开始(START)信号以后,主器件发送写控制字节即1001A2A1A00(其中R/W控制位为低电平“0”)。指示从接收器被寻址,DS1624接收后应答,再由主器件发送访问存储器指令(17H)后,DS1624接收后应答,接着由主器件发送的下一个字节字地址将被写入到DS1624的地址指针。主器件接收到来自DS1624的另一个确认信号以后,发送数据字节,并写入到寻址的存储地址。DS1624再次发出确认信号,同时主器件产生停止条件STOP,启动内部写周期。在内部写周期DS1624将不产生确认信号。在页编程模式中,如同字节写方式,先将控制字节、访问存储器指令(17H)、字地址发送到DS1624,接着发N个数据字节,其中以8个字节为一个页面。主器件发送不多于一个页面字节的数据字节到DS1624,这些数据字节暂存在片内 95页面缓存器中,在主器件发送停止信号以后写入到存储器。接收每一个字节以后,低位顺序地址指针在内部加1。高位顺序字地址保持为常数。如果主器件在产生停止条件以前要发送多于一页字的数据,地址计数器将会循环,并且先接收到的数据将被覆盖。像字节写操作一样,•旦停止条件被接收到,则内部写周期将开始。存储器的读操作在这种模式下,主器件可以从DS1624的EEPROM中读取数据。主器件在发送开始信号之后,主器件首先发送写控制字节1001A2A1A00,主器件接收到DS1624应答之后,发送访问存储器的指令(17H),收到DS1624的应答之后,接着发送字地址将被被写入到DS1624的地址指针。这时DS1624发送应答信号之后,主器件并没有发送停止信号,而是重新发送START开始信号,接着又发送读控制字节1001A2A1A01,主器件接收到DS1624应答之后,开始接收DS1624送出来的数据,主器件每接收完一个字节的数据之后,都要发送一个应答信号给DS1624,直到主器件发送一个非应答信号或停止条件来结束DS1624的数据发送过程。DS1624的指令集数据和控制信息的写入读出是以表5和表6所示的方式进行的。在写入信息时,主器件输出从器件(即DS1624)的地址,同时R/W位置0。接收到响应位后,总线上的主器件发出一个命令地址,DS1624接收此地址后,产生响应位,主器件就向它发送数据。如果要对它进行读操作,主器件除了发出命令地址外,还要产生一个重复的启动条件和命令字节,此时R/W位为1,读操作开始。下面对它们的命令进行说明。访问存储器指令[17H]:该指令是对DS1624的EEPROM进行访问,发送该指令之后,下一个字节就是被访问存储器的字地址数据。访问设置寄存器指令[ACH]:如果R/W位置0,将写入数据到设置寄存器。发出请求后,接下来的一个字节被写入。如果R/W位置1,将读出存在寄存器中的值。读温度值指令[AAH]:即读出最后一个测温结果。DS1624产生两个字节,即为寄存器内的结果。开始测温指令[EEH]:此命令将开始一次温度的测量,不需再输入数据。在单次测量模式下,可在进行转换的同时使DS1624保持闲置状态。在连续模式下,将启动连续测温。 96停止测温指令[22H]:该命令将停止温度的测量,不需再输入数据。此命令可用来停止连续测温模式。发出请求后,当前温度测量结束,然后DS1624保持闲置状态。直到下一个开始测温的请求发出才继续进行连续测量。表5主机对DS1624写操作通信格式T2C通信开始主器件发送控制字节(DS1624地址和写操作)DS1624应答主器件发送访问DS1624的指令DS1624应答主器件发送的数据字节DS1624应答T2C通信停止表6主机对DS1624读操作通信格式12C主器件发送控制字节(DS1624地址和写操作)DS1624应答问DS1624的指令12C通信开始主器件发送控制字节(DS1624地址和读操作)DS1624应答数据字节0主机应答数据字IJ1主机非应答I2C通信停止2.实验任务用一片DS1624完成本地数字温度的测量,并通过8位数码管显示出测量的温度值。其硬件电路图如图4344所示3.电路原理图 97IDuFUISDA1DS184CD",:1,MHzLED84sVDDAOAlK21OKSDASCLNCGNDGHDlyJ34■8S-,sQ123.4.56.7F1F1P1P1PIP1P1P1P3O/RXDP31/TXDP32/TNTOP33/INT1P34/TOP35/T1P36/WRP37/ftt>将8APOO/ADOPO1/AD1PO2/AD2PO3/AD3PO4/AD4PO5/AD5PO6/AD6PO7/AD7ALEFSENP27/A15P26/A14P25/A13P24/A12P23/A1】P22/A10P2.1/A9P2.0/A8lOTTlLED84SU3S2S3:ms,m图4.34.44.系统板上硬件连线(1).把“单片机系统”区域中的PO.O-PO.7用8芯排线连接到“动态数码显示"区域中的ABCDEFGH端子上。(2).把“单片机系统”区域中的P2.0-P2.7用8芯排线连接到“动态数码显示"区域中的S1S2S3S4S5S6S7S8端子上。(3).把DS1624芯片插入到“二线总线模块”区域中的8脚集成座上,注意芯片不插反。(4).把“二线总线模块”区域中的PIN1PIN2分别用导线连接到“单片机系统”区域中的P1.6和P1.7端子上。(5).把“二线总线模块”区域中的PIN4PIN5PIN6分别用导线连接到“电源模块”区域中的GND端子上。5.程序设计内容(1).由于DS1624是I2C总线结构的串行数据传送,它只需要SDA和SCL两根线完成数据的传送过程。因此,我们在进行程序设计的时候,也得按着12c协议来对DS1624芯片数据访问。有关I2C协议参看有关资料,这里不详述。对于AT89s51单片机本身没有12c硬件资源,所以必须用软件来模拟12c协议过程。(2).要从DS1624中读取温度值,首先启动DS1624的内部温度A/D开始 98转换,对应着有相应的命令用来启动开始温度转换,有关DS1624的指令集参考前面的叙述。一般情况下,DS1624经过一次温度的变换,需要经过1秒钟左右的时间,所以等待1秒钟后,即可读取内部的温度值,对于读取的温度值,仍然通过DS1624的指令集来完成温度的读取。但所有有数据的传送过程必须遵循12c协议。4.C语言源程序#include 99biti_send(unsignedchari_data);unsignedcharireceive(void);bitstart_temperature_T(void);bitreadtemperatureT(unsignedchar*p);voiddelay(void)(_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TvoiddelaylOms(void)(unsignedinti;for(i=0;i<1000;i++)(delay();}}voidistart(void)(SCL=1;delay();SDA=0;delay();SCL=0;delay();voidi_stop(void)(SDA=0;delay();SCL=1;delay();SDA=1;delay();SCL=0;delay();}voidi_init(void) 100(SCL=0;i_stop();}voidi_ack(void)(SDA=0;iclock();SDA=1;)biticlock(void)(bitsample;SCL=1;delay();sample=SDA;_nop_();_nop_();SOO;delay();return(sample);)bitisend(unsignedcharidata)(unsignedchari;for(i=0;i<8;i++)(SDA=(bit)(idata&0x80);i_data=i_data«l;i_clock();}"SDA=1;return(〜i_clock());)unsignedcharireceive(void)unsignedchari_data=O;unsignedchari; 101for(i=0;i<8;i++)(i_data*=2;if(i_clock())i_data++;)return(i_data);)bitstart_temperature_T(void)(istart();if(i_send(0x90))(if(i_send(Oxee))(i_stop();delay();return(1);}else(i_stop();delay();return(0);else(i_stop();delay();return(0);bitreadtemperatureT(unsignedchar*p)(istart();if(i_send(0x90))(if(isend(Oxaa))i_start();if(isend(0x91))(*(p+l)=i_receive();i_ack();*p=i_receive();i_stop();delay();return(1); 102)else(i_stop();delay();return(0);))else(i_stop();delay();return(0);))else(i_stop();delay();return(0);))voidmain(void)(Pl=0xff;timecount=0;displaycount=0;TMOD=Ox21;TH1=0x06;TLl=0x06;TR1=1;ET1=1;ETO=1;EA=1;if(start_temperature_T())〃向DS1624发送启动A/D温度转换命令,成功则启动TO定时Iso(secondflag=O;secondcount=0;TH0=55536/256;TL0=55536%256;TRO=1;}while(l)(if(secondflag==l){secondflag=0;TRO=O;if(readtemperatureT(temperdata))//TO定时Is时间到,读取DS1624的温度值(for(x=0;x<8;x++)(displaybuffer[x]=16;}x=2;result=temperdata[l];〃将读取的温度值进行数据处理,并送到显示缓冲区while(result/10){displaybuffer[x]=result%10;result=result/10;x++;) 103displaybuffer[x]=result;result=temperdata[O];result=result»3;displaybuffer[0]=(dotcode[result])%10;displaybuffer[1]=(dotcode[result])/10;if(start_temperature_T())〃温度值数据处理完毕,重新启动DS1624开始温度转场(secondflag=0;secondcount=0;TH0=55536/256;TL0=55536%256;TRO=1;voidtO(void)interrupt1using0//TO用于定时Is时间到(secondcount++;if(secondcount==100){secondcount=0;secondflag=l;)TH0=55536/256;TL0=55536%256;}voidtl(void)interrupt3using0//Tl定时1ms用数码管的动态刷新(timecount++;if(timecount==4)//Tl定时1ms到(timecount=0;if(displaycount==5)(P0=(displaycode[displaybuffer[7-displaycount]]|0x80);〃在该位同时还要显示小数点)else(P0=displaycode[displaybuffer[7-displaycount]];}P2=displaybit[displaycount];displaycount++;if(displaycount==8)displaycount=0; 10435.DS18B20数字温度计使用1.DS18B20基本知识DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。1、DS18B20产品的特点(1)、只要求一个端口即可实现通信。(2)、在DS18B20中的每个器件上都有独一无二的序列号。(3)、实际应用中不需要外部任何元器件即可实现测温。(4)、测量温度范围在一55。C到+125。C之间。(5)、数字温度计的分辨率用户可以从9位到12位选择。(6)、内部有温度上、下限告警设置。2、DS18B20的引脚介绍T0-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。(底视图)图1表1DS18B20详细引脚功能描述一序号.名称引脚功能描述1GND地信号2DQ数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。3VDD可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。3.DS18B20的使用方法由于DS18B20采用的是l-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89s51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。 105由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了儿种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。DS18B20的复位时序VDDGND~主机发出复位脉冲量小值,48(Xis最大值;960us15s50usDS18B20的复位时序图”主机接收历琶蝌时间厂一DS18B20发出“—►应答脉冲“DS18B20的读时序对于DS18B20的读时序分为读0时序和读1时序两个过程。对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成•个读时序过程,至少需要60us才能完成。DS18B20的写时序对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样10总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。 1064.实验任务用一片DS18B20构成测温系统,测量的温度精度达到0.1度,测量的温度的范围在一20度到+100度之间,用8位数码管显示出来。5.电路原理图2346SDA-7SCL811*11141*1A111pppppppp10FFFFFFdqFP3.0/RXDP3.1/TXDP3.2/INT0P3.3/iNTlP3.4/T0P3.5/T1P3.6/^P3.7/RD旦国8P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7ALEPSENP2.7/A15P2.6/A14P2.5/A13P2.4/A12P2.3/AUP2.27A10P2.1/A9P2.0/A8Q只o38C237C336C435C534C633C732C8302928S827S726S625S524S423S322S221SI39ClU1DS18B20gnd|-1JgndDQLED84S10129011£S10U45IS4£03£028012LED84S654321AT89S516.系统板上硬件连线 107(1).把“单片机系统”区域中的PO.0-P0.7用8芯排线连接到“动态数码显示"区域中的ABCDEFGH端子上。(2).把“单片机系统”区域中的P2.0-P2.7用8芯排线连接到“动态数码显示"区域中的SIS2s3s4s5s6s7s8端子上。(3).把DS18B20芯片插入“四路单总线”区域中的任一个插座中,注意电源与地信号不要接反。(4).把“四路单总线”区域中的对应的DQ端子连接到“单片机系统”区域中的P3.7/RD端子上。5.C语言源程序#include 108voidwritecommandtodsl8b20(unsignedcharcommand)(unsignedchari;unsignedcharj;for(i=0;i<8;i++){if((command&0x01)==0)(DQ=O;for(j=35;j>0;j—);DQ=1;}else(DQ=O;for(j=2;j>0;j-);DQ=1;for(j=33;j>0;j—■);}command=_cror_(command,1);unsignedcharreaddatafromdsl8b20(void){unsignedchari;unsignedcharj;unsignedchartemp;temp=0;for(i=0;i<8;i++)(temp=_cror_(temp,1);DQ=O;_nop_();_nop_();DQ=1;for(j=10;j>0;j—);if(DQ==l)temp=temp|0x80;}else 109{temp=temp|0x00;}for(j=200;j>0;j—);}return(temp);)voidmain(void){TM0D=0x01;TH0=(65536-4000)/256;TL0=(65536-4000)%256;ETO=1;EA=1;while(resetpulseO);writecommandtodsl8b20(Oxcc);writecommandtodsl8b20(0x44);TRO=1;while(1)voidtO(void)interrupt1using0(unsignedcharx;unsignedintresult;THO=(65536-4000)/256;TLO=(65536-4000)%256;if(displaycount==2)(PO=displaycode[displaybufLdisplaycount]]0x80;)elseP0=displaycode[displaybuf[displaycount]];P2=displaybit[displaycount];displaycount++;if(displaycount==8)(displaycount=0;} 110timecount++;if(timecount==150)(timecount=0;while(resetpulse());writecommandtodsl8b20(Oxcc);writecommandtodsl8b20(0xbe);readdata[0]=readdatafromdsl8b20();readdata[I]=readdatafromdsl8b20();for(x=0;x<8;x++){displaybuf[x]=16;}sflag=0;if((readdata[l]&0xf8)!=0x00){sflag=l;readdata[1]=^readdata[1];readdata[0]=^readdata[0];result=readdata[O]+l;readdata[O]=result;if(result>255){readdata[1]++;}}readdata[1]=readdata[1]«4;readdata[1]=readdata[1]&0x70;x=readdata[0];x=x»4;x=x&OxOf;readdata[1]=readdata[1]|x;x=2;result=readdata[1];while(result/10){displaybuf[x]=result%10;resu1t=result/10;x++;}displaybuf[x]=result;if(sflag==l){displaybuf[x+1]=17;}x二readdata[0]&OxOf;x=x«l;displaybuf[0]=(dotcode[x])%10;displaybuf[1]=(dotcode[x])/10;while(resetpulseO);writecommandtodsl8b20(Oxcc);writecommandtods18b20(0x44);
此文档下载收益归作者所有