单片机C语言编程基础生动形象AT89C52为例子_第1页
单片机C语言编程基础生动形象AT89C52为例子_第2页
单片机C语言编程基础生动形象AT89C52为例子_第3页
单片机C语言编程基础生动形象AT89C52为例子_第4页
单片机C语言编程基础生动形象AT89C52为例子_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND基础知识:单片机编程基础单片机的外部枷1、DIP40双列直插:2、PO,Pl,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平)3、电源VCC(PIN40)和地线GND(PIN20):4、高电平复位RESET(PIN9):(10uF电容接VCC与RESET,即可实现上电复位)5、内置振荡电路,外部只要接晶体至XI(PIN18)和XO(PIN19);(频率为主频的12倍6、程序配ffiEA(PIN31)接高电平VCC:(运彳亍单片机内部ROM中的程序)7、P3支持第二功能:RXD、TXD、INTO、INTI、T

2、O.T1单片机内部I/O部件,(所为学习单片机,实际上曄制以下I/O部件,完成指定任务)1、四个8位通用I/O端口,对应引脚PO、Pl.P2和P3:2、两个16位定时计数器;(TMOD,TCON,TLO,THO,TL1,TH1)3、一个串行通信接口:(SCON,SBUF)4、一个中断控制器;(IE,IP)针对AT89C52单片札头文件AT89x52h給出了讯陳功能奇存器所有増口的定义.教科书的畑頁给出了针对ICS51茶列单片机的C语言扩舷出理.c语1、十六进制表示字节0 x5a:二进制为0101101OB:0 x6E为01101110。2、如果将一个16位二进数赋给一个8位的字节变虽,则H动截

3、断为低8位,而丢掉高8位。3、卄var表示对变虽var先増一:var表示对变虽后减一。4、x|=OxOf;表示为x=x|OxOf;5、TMOD=(TMOD&OxfO)|0 x05;表示给变in:TMOD的低四位赋值0 x5,而不改变TMOD的高四位。6、While(1);表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是;在某引曲出高电平的編程方法*(比如pi3OnrO引妙ffincludevoidmain(void)该头文档中有单片机内部资源的符号化定义,其中包含P1.3/void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口XPl_3=1;Vhile(1);/给Pl

4、_3赋值1,引脚P1.3就能输出高电平VCC死循坏,相当LOOP:gotoLOOP;注童:P0的每个引脚要输出高电平时,必须外接上拉电阻(如4K7)至VCC电源。在某引urn出低电平的编程方法,(比如曲7引脚)ffincludevoidmain(void)该头文档中有单片机内部资源的符号化定义,其中包含F2.7/void表示没有输入参数.也没有函数返值.这入单片机运行的复位入口ffincludevoidmain(void)i该头文档中有单片机内部资源的符号化定义,其中包含F31/void表示没有输入参数,也没有函数返值,这入单片机运行的复位入口iVhile(1)/非寥表示玫,如果为真则执行下面

5、循环体的语句iP3_l=1;P3_l=0;给P3_l赋值1,引脚P3.1就能输出高电平VCC给P3_l赋值0,引脚P3.1就能输出低电平GND山于一直为真,所以不断输出高、低、高、低从而形成方波在某引出方波编程方法*at如P3引H)林引脾般入电后,从另f引耐出,(皈P0.4I0T(P1.1)include该头文档中有单片机内部资源的符号化定义,其中包禽P0.4和Pl.1voidmain(void)/void表示没有输入参数.也没有函数返值,这入单片机运行的复位入口Pl_l=1;初始化。P1.1作为输入,必须输出高电平Vhile(1)/非零表示真,如果为真则执行下而循环体的语句if(Pl_l=1

6、)读取P1.1,就是认为F1.1为输入,如果P1.1输入高电平VCCP0.4=0;给P0.4賦值0,引脚F0.4就能输出低电平GNDelse否则P1.1输入为低电平GND/P0_4=0P0_4=1;给P0_4賦值0,引脚P04就能输出低电平GND给P0.4賦值1.引脚F0.4就能输出高电平VCC由于一直为其,所以不断根据Pll的输入惜况,改变P0.4的输出电平将粗口8个引入电平.低四位取朋.从另fit口8个引耐出*(HIP2-10T(P3)ffincludevoidmain(void)j该头文档中有单片机内部资源的符号化定义,其中包含P2和P3/void表示没有输入参数,也没有函数返值,这入单

7、片机运行的复位入口iP3=Oxff;Vhile(1)初始化。F3作为输入,必须输出高电平,同时给P3口的8个引脚输出高电平/非寥表示真,如果为真则执行下面循环体的语句取反的方法是异或1,而不収反的方法则是异或0P2=P3Px0f读取P3,就是认为P3为输入,低四位异或者1,即取反,然后输出/111于一直为真,所以不断将P3取反输出到P2注童:一个字节的8位D7、D6至D0,分别输出到P37、P36至P30,比如P3=0 x0f则P37、P3.6、P3.5、P3.4四个引脚都输出低迫平,而P3.3、F3.2、P3.1、P3.0四个引脚都输岀高电平。同样,输入一个端口P2,即是将P2.7、P2.6

8、至P2.0.读入到一个字节的8位D7、D6至D0。P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND第一节:单数码管按键显示单片机量小茶统的砒K理接钱图*1、接电源:VCC(PIN40).GND(PIN20)。加接退耦电容0luF2、接晶体:XI(PIN18).X2(PIN19)o注意标出晶体频率(选用12MHz),还有轴助电容30pF3、接复位:RES(PIN9)接上电复位电路,以及手动复位电路,分析复位工作腹理4、接配置:EA(PIN31)o说明原因。发光二极的控控林单片机I/O*出将一发光二极管LED的正极(阳极)接Pl.l,LED的负极(阴极)接地GND。只要Pl.1输出

9、高电平VCC,LED就正向导通(导通时LED上的压降大于IV),有电流流过LED,至发LED发亮。实际上由于P1.1高电平输出电阻为10K,起到输出限流的作用,所以流过LED的电流小于(5V-1V)/10K=0.4S只要Pl.1输出低电平GND,实际小T0.3V,LED就不能导通,结果LED不亮。开关双健恤入入先输出高ffincludedefineLEDPlJdefineKEY.ONPl飞defineKEY.OFFvoidmain(void)一个按键KEY.0N接在P1.6与GND之间,另一个按键KEY.OFF接F1.7与GND之间,按KEY.0N后LED亮.按KEY.OFF后LED火。同时按

10、下LED半亮,LED保持后松开键的状态,即ON亮OFF几/用符号LED代替Pl_l/用符号KEY_ON代替Pl_6/用符号KEY_OFF代替Fl_7单片机复位后的执行入口.void表示空,无输入参数,无返回值KEY.ON=1;/作为输入,首先输出高,接下KEY_ON,Pl.6则接地为0,否则输入为1KEY_OFF=1;Vhile(1)作为输入,首先输出高,接下KEY_OFF,P1.7则接地为0,否则输入为1永远为真所以永远循环执行如下括号内所有语句if(KEY_ON=O)LED=1;是KEY_ON接下,所示Pll输出高,LED亮if(KEY_OFF=0)LED=0;是KEY_OFF接下,所示P

11、l1输出低,LED灭松开键后,都不给LED赋值,所以LED保持最后按键状态。同时按下时,LED不断亮灭,各占一半时间.交替频率很快,山丁人眼惯性,看上去为半亮态一支七段数码管实际山8个发光二极管构成,其中7个组形构成数字8的七段笔画,所以称为七段数码管,而余下的1个发光二极管作为小数点。作为习惯,分别给8个发光二极管标上记号:a,b,c,d,e,f,g,h对应8的顶上一画,按顺时针方向排,中间一画为g.小数点为h。我们通常又将各二极与一个字节的8位对应,a(D0),b(Dl),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7)相应8个发光:极管正好与单片机一个端口Pn的8个

12、引脚连接,这样单片机就可以通过引脚输出高低电平控制8个发光:极的亮与火,从而显示各种数字和符号:对应字节,引脚接法为:a(PdO),b(Pn.l),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)oP2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND如果将8个发光二极管的负极(阴极)内接在一起,作为数码管的一个引脚.这种数码管则被称为共阴数码管,共同的引脚则称为共阴极,8个正极则为段极。否则,如果是将正极(阳极)内接在一起引出的,则称为共阳数码管,共同的引脚则称为共阳极,8个负极则为段极。以单支共阴数码管为例,可将段极接到某端口Pn,共

13、阴极接GND,则可编写出对应十六进制码显示宇符共明級緩选福其阳敬綾选啊显示*捋共阳桜段选谒03FHC0HC39HC6H106HF9HD5EHA1H25BHA4HE79H86H34FHB0HF71H84H466HWHPtJH2H56DH92HU3EHC1H67DH阿r33HCEH707HF8Hy6EH91H37FH80H8FFH00H9FH90H00HFFHA77HS8HB7CHP2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND的七段码表字节数据如右图:16键码显示的程序我们在F1端口接一支共阴数码管SLED.在F2、F3端口接16个按键,分别编号为KEY_O、KEY_1到KEY_

14、F,操作时只能按一个键,按键后SLED显示对应键编号。include#defineSLEDPl#defineKEY_OP2P#defineKEYP2l#defineKEY_2P2*2defineKEY_3P2*3#defineKEY_4P2*4defineKEY_5P25#defineKEY_6P2飞#defineKEYP2=defineKEY_8P3,0#defineKEY_9P3l#defineKEY_AP3*2defineKEY_BP3*3#defineKEY_CP3tdefineKEY_DP35defineKEY_EP3飞defineKEY_FP3=CodeunsignedcharSe

15、g7Code16=/用十六进数作为数纽下标,可直接取得对应的七段编码字节/0123456789AbCdEF0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x740 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;voidmain(void)unsignedchari=0;/作为数组下标P2=Oxff;/P2作为输入.初始化输出高P3=Oxff;/P3作为输入.初始化输出高Vhile(1)if(if(if(if(if(if(if(if(KEY.0=0)i=0;if(KEY.1=0)i=l;KEY2=0)i=2;i

16、f(KEY3=0)i=3;KEY4=0)i=4;if(KEY5=0)i=5;KEY6=0)i=6;if(KEY7=0)i=7;KEY8=0)i=8;if(KEY9=0)i=9;KEYA=0)i=0 xA;if(KEYB=0)i=0 xB;KEYC=0)i=0 xC;if(KEYD=0)i=0 xD;KEYE=0)i=0 xE;if(KEYF=0)i=0 xF;P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDSLED=Seg7Codei;开始时显示0,根据i取应七段编码第二节双败码管可调秒联解:只要满足题目要求.方法越简单越好。山丁单片机I/O资源足够,所以双数码管可接成静态显示

17、方式,两个共阴数码管分别接在P1(秒十位)和P2(秒个位)口,它们的共阴极都接地,安排两个按键接在F3.2(十位数调整)和P3.3(个位数调整)上,为了方便计时,选用12)(Hz的晶体。为了达到耕确计时,选用定时器方式2,每计数250重载一次,即250us.定义一整数变量计数重载次数,这样计数4000次即为一秒。定义两个字节变呈S10和S1分别计算秒十位和秒个位。编得如下程序:ffincludeCodeunsignedcharSeg7Code16=/用十六进数作为数组下标,可直接取得对应的七段编码字节/0123456789AbCdEF0 x3f,0 x06,0 x5b,0 x4f,0 x66,

18、0 x6d,0 x740 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;voidmain(void)unsignedintus250=0;unsignedcharslO=0;unsignedcharsi=0;unsignedcharkeylO=0;记忆按键状态,为1按下unsignedcharkeyl=0;记忆按键状态,为1按下/初始化定时器TimerOTMOD=(TMOD&OxFO)|0 x02;TH1=-250;对于8位二进数来说,-250=6,也就是加250次1时为256.即为0/循环1/循环2TRI=1;whiled)Pl=Se

19、gTCodeslO;显示秒十位P2=SegTCodesi;显示秒个位vhile(1)计时处理if(TFO=1)10个单位时间,南北黄,东西红:P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDTFO=0;if(卄us250=4000)us250=0;if(卄si=10)si=0;if(卄slO=6)slO=0;break;结束“循环2”,修改显示按十位键处理P3.2=1;/P3.2作为输入,先要输出高电平if(keylO=L)等松键if(P3.2=1)keyl0=0;1else/未按键if(P3.2=0)keylO=1;if(卄slO=6)slO=0;break;结束“循环2”,

20、修改显示/按个位键处理P3.3=1;/P3.3作为输入,先要输出高电平if(keyl=1)等松键if(P3.3=1)keyl=0;else未按键if(P3.3=0)keyl=1;if(卄si=10)si=0;break;结束“循环23修改显示循环2end循环1end/nain,end第三节,+字路口交通灯如果一个单位时间为1秒,这里设定的十字路口交通灯按如下方式四个步骤循环工作:60个单位时间,南北红,东西绿:10个单位时间,南北红,东西黃:60个单位时间,南北绿,东西红:P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND南北方向红灯/南北方向黃灯/南北方向绿灯/东西方向红灯/东

21、西方向黄灯/东西方向绿灯voidDelay(unsignedintn)voidmain(void)for(;nl=0;n)DelaylUnit();解:用Pl端口的6个引脚控制交通灯,高电平灯亮,低电平灯灭。include/sbit用來定义一个符号位地址,方便编程,提高可读性,和可移植性sbitSNRed二P1P;sbitSNYellow二Pl;sbitSNGreen二P2;sbitEIRed二P3;sbitEiYellow=P1*4;sbitEIGreen二P5;/*用软件产生延时一个单位时间*/voidDelaylUnit(void)unsignedinti,j;for(i=0;i1000

22、;i+)for(j0;j1000;j卄);通过实测,调整j循环次数,产生1ms延时还可以通过生成汇编程序來计算指令周期数,结合晶体频率來调整j循环次数,接近1ms/*延时n个单位时间*/P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDP2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDwhile(1)SNRe左0;SNYellov=0;SNGreen=l;EVRecl;EWYellov=0;EWGreen=0;Delay(60SNRe左0;SNYellov=l;SNGreen=0;EVRecl;EWYellov=0;SNRed=l;SNYellov=0;SNGree

23、n=0;EWRe左0;EWYellov=0;SNRed=l;SNYellov=0;SNGreen=0;EWRe左0;EWYellov=l;EWGreen=0;Delay(EWGreen=l;Delay(EWGreen=0;Delay(106010P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDP2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GND第四节,数码管驱动显示w12345678Pl端口接8联共阴数码管SLED8的段极:P1.7接段h,P1.0接段aP2端口接8联共阴数码管SLED8的段极:P2.7接左边的共阴极,P2.0接右边的共阴极方案说明:晶振频率fosc

24、=12MHz,数码管采用动态刷新方式显示,在Ms定时断服务程序中实现includeunsignedcharDisBuf8;/全局显示缓冲区,DisBuf0对应右SLED,DisBuf7对应左SLED,voidDisplayBrush(void)codeunsignedcharcathode8=0 xfe,Oxfd,Oxfb,0 xf7,Oxef,Oxdf,Oxbf,0 x7f;/阴极控制码CodeunsignedcharSeg7Code16=用十六进数作为数组下标,可直接取得对应的七段编码字节0 x3f,0 x06,0 x5b,Oxlf,0 x66,0 x6cl0 x7d,0 x07,0 x7

25、f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;staticunsignedchari=0;/(0Wi7)循环刷新显示,ill丁是静态变虽,此赋值只做一次。#include“key.h”defineKeyBufSize16/定义按键缓冲队列字节数P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDP2=Oxff;显示消隐.以免下一段码值显示在前一支SLEDPl=SegTCodeEDisBufti;从显示缓冲区取出腹始数据,査表变为七段码后送出显示P2=cathodei;将对应阴极置低,显示if(卄i=8)i=0;指向下一个数码管和相应数据vo

26、idTimerOIntRoute(void)internet1TLO=-1000;/lllTTLO只有8bits,所以将(-1000)低8位赋给TLOTHO=000)8;取(-1000)的高8位赋给THO,重新定时hnsDisplayBrushO;voidTimerOInit(void)TMOD=(TMOD&OxfO)|0 x01;初始化,定时器TO,工作方式1TLO=-1000:定时InsTHO=000)8;TRO=1;允许TO开始计数ETO=1;允许T0计数溢出时产生中断请求voidDisplay(unsignedcharindex,unsignedchardataValue)DisBuf

27、index=dataValue;voidmain(void)unsignedchari;for(i=0;i8;)Display8-i);/DisBuf0为右,DisBuf7为左TimerOInit();EA=1:/允许CPU响应中断请求Vhile(l);第五节Ifit盘驱动指提供一些函数给任务调用,获取按键信息,或读収按键值。定义一个头文档,描述可用函数,如下:#ifndef_KEY_H_防止重复引用该文档,如果没有定义过符号_KEY_H_,则编译下面语句defineKEYH/只要引用过一次,即#include,则定义符号_KEY_H_unsignedcharkeyHit(void);如果按键

28、,则返回非0,否则返Al0unsignedcharkeyGet(void);/读取按键值,如果没有按键则等待到按键为止voidkeyPut(unsignedcharucKeyVal);/保存按键值ucKeyVal到按键缓冲队列末voidkeyBack(unsignedcharucKeyVal);/退IE键值ucKeyVal到按键缓冲队列首#endif定义函数体文档KEY.C,如下:P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDunsignedcharKeyBufKeyBufSize;定义一个无符号字符数组作为按键缓冲队列。该队列为先进/先出,循环存収,下标从0到KeyBufS

29、ize-1unsignedcharKeyBufWp=O;/作为数组下标变蛍,记录存入位代unsignedcharKeyBufRp=O;作为数组下标变壶记录读出位代如果存入位匿与读出位理相同,则表明队列中无按键数据unsignedcharkeyHit(void)if(KeyBufWp=KeyBufRp)return(0);elseretum(1);unsignedcharkeyGet(void)unsignedcharretVal;/暂存读出键值vhile(keyHit0=0);等待按键,因为函数keyHit0的返回值为0表示无按键retVal=KeyBufKeyBufRp;从数组中读出键值if

30、(卄KeyBufRp=KeyBufSize)KeyBufRp=O;读位理加1,超出队列则循坏回初始位旌return(retVal);voidkeyPut(unsignedcharucKeyVal)KeyBufKeyBufWp=ucKeyVal;/键值存入数组if(卄KeyBufWp=KeyBufSize)KeyBufWp=O;存入位代加1超出队列则循环Al初始位理/*山丁某种凍肉,读出的按键,没有用,但其它任务要用该按键,但传送又不方便。此时可以退回按键队列,就如収错了信件,有必要退回一样*/voidkeyBack(unsignedcharucKeyVal)/*如果KeyBufRp=O;减1后

31、则为FFH,大TKeyBufSize,即从数组头退回到数纽尾。或者山丁干扰使得KeyBufRp超出队列位直,也要调整回到正常位迓,*/if(KeyBufRp=KeyBufSize)KeyBufRp=KeyBufSize-l;KeyBufKeyBufRp=ucKeyVal;回存键值下面渐进讲解键盘物理层的驱动。电路共同点:F2端口接一共阴数码管,共阴极接GND,P2.0接a段、P2.1接b段、P2.7接h段。软件共同点:codeunsignedcharSeg7Code10是七段数码管共阴编码表。CodeunsignedcharSeg7Code16=/0123456789AbCdEF0 x3f,0

32、 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;-:戸10接一按矽|5,栅号为r6显示按健.includeinclude“KEYvoidmain(void)Pl-0=1;作为输入引脚,必须先输出高电平vhile(1)永远为真,即死循环if(Pl_0=0)如果按键,则为低电平keyPut(6);/保存按键编号值为按键队列hile(Pl_0=0);如果一直按着键,则不停地执行该循环,实际是等待松键if(kejdlitO!=0)/如果队列中有按键P2=Seg7Codeke

33、yCetO;从队列中取出按键值,并显示在数码管上例二在例一中考虑按健2E抖动旬题includeinclude“KEY.R”voidmain(void)Pl_0=1;作为输入引脚,必须先输出高电平vhile(1)永远为真,即死循环if(Pl_0=0)如果按键,则为低电平delaygQas0;/延时2伽s,跳过接卞抖动keyPut(6);/保存按键编号值为按键队列hile(Pl_0=0);如果一直按着键,则不停地执行该循环,实际是等待松键deav20NS0;/延时20ms,跳过松开扌斗动if(kejdlitO!=0)/如果队列中有按键P2=Seg7CodekeyCetO;从队列中取出按键值,并显示

34、在数码管上例m在例二中考虔干扰问息即小于20“的负脉冲干扰includeinclude“KEY.R”voidmain(void)Pl_0=1;作为输入引脚,必须先输出高电平vhile(1)永远为真,即死循环if(Pl_0=0)如果按键,则为低电平delay20ms();/延时20ns,跳过接下抖动if(P10=2丿continue;假按键keyPut(6);/保存按键编号值为按键队列hile(Pl_0=0);如果一直按着键,则不停地执行该循环,实际是等待松键delay20ms();/延时20jis,跳过松开抖动if(kejdlitO!=0)/如果队列中有按键P2=Seg7CodekeyCetO

35、;从队列中取出按键值,并显示在数码管上例四,状态图编程法.ift过2Z周期中新,扫描按!./*釆用晶体为121Hz时.指令周期为IBS(即主頻为lKHz).这样TO工作在定时参方式2,8位自动计数值为20,即可产生2.的周期性中帕在中牺务程序中实现拠由描*/includeinclude“KEY.H”voidmain(void)TMOD=(TMOD&OxfO)THO=-20;TLO=THO;TRO=1;ETO=1;EA=1;10 x02;不改变T1的工作方式.TO为定时器方式2计数周期为20个主频脉,即20ms先软加载一次计数值允许T0开始计数允许T0计数溢出时产生中断请求允许CPU响应中断请求

36、vhile(1)永远为真即死循环if(keyHitO!=0)如果队列中有按键P2=Seg7CodekeyCetO;从队列中取出按键值,并显示在数码管上voidtimerOint(void)interrupt1/20ms:TO的中断号为1staticunsignedcharsts=O;Pl-0=1;作为输入引脚,必须先输出高电平switch(sts)case0:if(Pl_0=0)sts=l;break;/按键则转入状态1case1:if(Pl_0=l)sts=O;假按错,或干扰,回状态0elsests=2;keyPut(6);确实按键,键值入队列,并转状态2break;case2:if(Pl_

37、0=l)sts=3;break;如果松键,则转状态3case3:if(Pl_0=0)sts=2;假松键.回状态2elsests=O;真松键,回状态0,等待下一次按键过程佛五,炖图编程法.如果采用鼻体为IN&时,指令周期为试即知I为IHz),要产生2E左右的计时,则计数值达到2000GT0工作必須为定时器方式1,16位非自动皿,即可产生2Z的周期性中斷,在中斷服务程序中咖ftlteincludeinclude“KEY.H”P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDvoidmain(void)TMOD=(TMOD&OxfO)TLO=-20000;THO=(-20000)8;T

38、RO=1;ETO=1;EA=1;vhile(1)/永远为真,if(keyHitO!=0)|0 x01;/不改变T1的工作方式.TO为定时器方式1计数周期为20000个主频脉,动取低8位右移8位,实际上是取高8位允许T0开始计数允许T0计数溢出时产生中断请求允许CPU响应中断请求即死循环P2=Seg7CodekeyGet()voidtinerOint(void)interrupt1staticunsignedcharsts=O;TLO=-20000;THO=(-20000)8;Pl-0=1;如果队列中有按键;从队列中収出按键值,并显示在数码管上/20ms:TO的中断号为1方式1为软件重载实际上是

39、取高8位右移8位,作为输入引脚.必须先输出高电平P2.7=0;给P2_7赋值0,引脚P2.7就能输出低电平GNDswitch(sts)case0:if(Pl_0=0)sts=l;break;/按键则转入状态1case1:if(Pl_0=l)sts=O;假按错,或干扰,回状态0elsests=2;keyPut(6);确实按键,键值入队列,并转状态2break;case2:if(Pl_0=l)sts=3;break;如果松键,则转状态3case3:if(Pl_0=0)sts=2;假松键.回状态2elsests=O;真松键,回状态0,等待下一次按键过程例六,4X4按健/仙网*神+*伙”卄卄卄计卄卄卄

40、卄啊仙艸由P1MI口的离4位和低4位构成4X4的矩阵题,本程序只认为单曲作为合法,同时按多健时劫:.这样下面的X,Y的合法值为0 x7,Oib,OxdOxe,Oxf,通过表kgfe形射蚣可得按It值*/includeincludeKEY.H”unsignedcharkeyScan(void)返回0表示无按键,或无效按键,其它值为按键编码值codeunsignedcharkeyCode16=/OxO,0 x1,0 x2,0 x3,0 x4,0 x5,0 x6,0 x7,0 x8,0 x9,OxA,OxB,OxC,OxD,OxE,OxF0,0,0,o,0,0,0,1,0,0,0,2,0,3,4,0

41、unsignedcharx,y,retVal;Pl=0 x0f;/低四位输入,高四位输出ox二Pl&OxOf;/Pl输入后,清高四位,作为X值Pl=OxfO;/高四位输入,低四位输出0y=(Pl4)&OxOf;/P1输入后移位到低四位,并清高四位,作为Y值retVal=keyCodex*4+keyCodey;根据木公式倒算按键编码if(retVal=0)return(0);elsereturn(retVal-4);比如按键T,得X=0 x7,Y=0 x7,算得retVal=5,所以返回函数值1。双如按键“厂得X=0 xb,Y=0 xd,算得retVal=lb所以返回函数值7。voidmain(

42、void)TMOD=(TMOD&OxfO)TLO=-20000:THO=(-20000)8;TRO=1;ETO=1;EA=1;0 x01;/不改变T1的工作方式,TO为定时器方式1计数周期为20000个主频脉,|动取低8位右移8位,实际上是取高8位允许T0开始计数允许T0计数溢出时产生中断请求允许CPU响应中断请求vhile(1)永远为真即死循环if(keyHitO!=0)如果队列中有按键P2=Seg7CodekeyGetO;从队列中取出按键值,并显示在数码管上voidtimerOint(void)interrupt1/20ns:TO的中断号为1staticunsignedcharsts=O;

43、TLO=-20000;方式1为软件重载THO=(-20000)8;右移8位,实际上是取高8位P1-0=1;作为输入引脚,必须先输出高电平switch(sts)case0:if(keyScanO!=0)sts=l;break;按键则转入状态1case1:if(keyScan()=0)sts=O;/假按错,或干扰,回状态0elsests=2;keyPut(keyScanO);确实按键,键值入队列.并转状态2break;case2:if(keyScan()=0)sts=3;break;/如果松键.则转状态3case3:if(keyScanO!=0)sts=2;/假松键,回状态2elsests=O;真

44、松键,回状态0,等待下一次按键过程第六节,低频頻率计实例目的:学时定时器、计数器、中断应用说明:选用24MHz的晶体,主频可达2MHzo用T1产生100us的时标,T0作信号脉冲计数器。假设晶体频率没有误基,而且稳定不变(实际上可达万分之一):被测信号是周期性矩形波(正负脉冲宽度都不能小丁0.5us),频率小T-1MHZ,大T-lHzo要求测虽时标IS,测蚩:粘度为0.1%O解:从测嵐梏度要求來看,当频率超过1KHz时,可采用1S时标内计数信号脉冲个数來测呈信号频,而信号频率低TlKHz时,可以通过测虽信号的周期來求出信号频率。两种方法Fl动转换。对丁低TlKHz的信号,信号周期最小为1ms,

45、也就是说超过1000US,而我们用的定时器计时脉冲周期为0.5us,如果定时多计或少计一个脉冲,误差为lus,所以相对误差为1us/1000us=0.1%0信号周期越大,即信号频率越低,相对误垫就越小。从上而描述来看,当信号频率超过lKHz后,信号周期就少丁JOOSis.显然采用上而的测呈方法,不能达到测嵐梏度要求,这时我们采用1S单位时间计数信号的脉冲个数,最少能计到1000个脉冲,山丁信号频率不超过1MHz,而我们定时脉冲为2MHz,最左多计或少计一个信号脉冲,这样相对误至为1/1000,可见信号频率越高,相对误羞越小。信号除输入到T1(P3.5)夕卜,还输入到INTI(P3.3)ouns

46、ignedintuslOO;对lOOus时间间隔单位计数,即有多少个100usQunsignedcharSecond;unsignedintK64;对64K单位计数,即有多少个64KunsignedcharoldTO;unsignedintoldus,oldK64,oldTl;unsignedlongfey;存放频率值,单位为HzbitHighLov=l;voidInitialHigh(void)/l:表示信号超过lKHz;0:表示信号低T-lKHzoIE=0;IP=0;HighLow=l;TMOD=(TMOD&OxfO)|0 x02;TH0=-200;TLO=THO;PXO=1;T0=l;T

47、MOD=(TMOD&OxOf)|0 x50;TH1=O;TL1=O;Tl=l;ET1=1;Usl00=0;SeconO;K64=0;oldK64=0;oldTl=0;TCON|=0 x50;/同时理TRO=1;TR1=1;EA=1;voidInitialLov(void)IE=0;IP=0;HighLow=0;TMOD=(TMOD&OxfO)|0 x02;TH0=-200;TLO=THO;ETO=1;TRO=1;INTI=1;IT1=1;EX1=1;Usl00=0;SeconO;K64=0;oldK64=0;oldTl=0;EA=1;voidTOintr(void)internet1if(Hi

48、ghLow=0)卄uslOO;elseif(+US100=10000)unsignedinttmpl,tnp2;TR1=O;tnpl=CTH18)+(TL1);tmp2=K64;TR1=1;fcy=(tmp2-oldK64)16)+(tnpl-oldTl);oldK64=tnpl;oldTl=tnp2;Second;us100=0;voidTlintr(void)internet3+K64;voidXlintr(void)internet2staticunsignedcharsts=O;switch(sts)case0:sts=1;break;case1:oldTO=TLO;oldus=usl

49、00;sts=2;break;case2:unsignedchartmpl,5p2;TRO=0;tnpl=TL0;tmp2=usl00;TRO=1;fey=1000000L/(tJnp2-oldus)*100L+(256-tmpl)/2);Second卄;Sts=0;break;voidmain(void)if(HighLow=l)InitialHighO;elseInitialLowO;Vhiled)if(Second1=0)Second=0;/displayfey引用前而的数码管驱动程序,注意下面对TO中断服务程序的修改unsignedchari;for(i=0;i8;i卄)Display

50、(i,fcy%10);fey/=10;if(HighLow=l)if(fcy1000L)InitalHighO;修改TO的中断服务程序,让它在完成时标的功能时,同时完成数码管显示刷新voidTOintr(void)internet1staticunsignedcharms=0;if(HighLow=0)卄uslOO;elseif(+US100=10000)unsignedinttmpl,tnp2;TR1=O;tiipl=(THl8)+(TL1);tmp2=K64;TR1=1;fcy=(tmp2-oldK64)16)+(tnpl-oldTl);oldK64=tnpl;oldTl=tnp2;Sec

51、ond;us100=0;if(+ms=10)ms=0;DisplayBrushO;/lms数码管刷新第七节:电子表单键可调电子表:主要学习编程方法。外部中断应用,中断嵌解:电子表分为工作状态和调整状态。平时为工作状态,按键不足一秒,接键为换屏S。按键超过一秒移位则进入调整状态C,而且调整光标在秒个位开始。调整状态时,按键不足一秒为光标移动,超过一秒则为调整读数,每0.5秒加一直到松键;如果10秒无按键则|动回到工作状态如果有年、月、口、时、分、秒。四联数码管可分三屏显示,显示格式为“年月”、“口.时.”、“分.秒”,从小数点的位直来区分显示内容。(月份的十位数也可以用“-”和“-1”表示)。e

52、nuastatus=Work,Change,Add,Move,Screen/状态牧举计时和调整都是对下而时间数组Tine进行修改unsignedcharTime12=(0,4,0,6,1,0,0,8,4,5,3,2:/04年06月0日08时45分32秒unsignedcharcursor=12;/指向秒个位,=0时无光标unsignedcharYnDhMs=3;/指向分秒”显示,=0时无屏显staticunsignedcharsts=Work;/*如果cursor不为0,装入DisBuf的对应数位,按02秒周期闪烁,即设一个01秒计数器SOI,S01为奇数时灭,S01为偶数时亮。小数点显示与Y

53、jaDhMs变昴:相关。*/voidDisScan(void)动态刷新显示时调用。没编完,针对共阴数码管,只给出控控制算法(/DisBuf每个显示数据的高四位为标志,最高位D7为负号,D6为小数点,D5为闪烁unsignedchartup;tmp=Seg7Code?x&Oxlf;设?x为显示数据,高3位为控制位,将低5位变为七段码if(?x&0 x40)tmp|=0 x80;添加小数点if(?x&0 x20)if(S01&0 x01)tnp=0;/闪烁,S01奇数时不亮这里没有处理负号位将tnp送出显示,并控制对应数码管动作显示voidDisplay(void)/根据状态进彳亍显示if(cursor!=0)YjnDhMs=(cursor+3)/4;/l.4=1;5.8=2;9.12=3for(i=(YmDhMs-l)*4;i(YmDhMs)*4;i卄)unsignedcharj=i%4;Disbufj=Tinei;if(i=(cursor-1)Disbufj|=0 x20;/闪烁cursor1=0时才闪烁(i=9)II小数点:分个位(i=7)II小数点:时个位(i=5)II小数点:日个位(i=3)小数点:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论