推荐-单片机语言学习好_第1页
推荐-单片机语言学习好_第2页
推荐-单片机语言学习好_第3页
推荐-单片机语言学习好_第4页
推荐-单片机语言学习好_第5页
免费预览已结束,剩余20页可下载查看

付费下载

下载本文档

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

文档简介

1、DIP402、P0,P1,P2,P38I/OI/O3、电源VIN40)和地线GND(PIN20RESET(PIN9(10uF(12倍)7、P3支持第二功能:RXD、TXD、INT0、INT1、T0、 I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,18I/OP0、P1、P23、一个串行通AT89C52AT89x52hSFRC3、++varvarvar4、x|=0x0f;xx|5、TMODTMOD&0xf0|0x05TMOD0x5,而不改变TMOD的高四位。6、While(1);表示无限执行该语句,即死循环。语句后的分号表示空循环体,在某引脚输出高电平的编程方法:(比 P1.3(PIN4)引脚#include<AT89x52.h>//该头文档中有单片机资源的符号化定义,其中voidmain(void) //void{P1_3=1; //给P1_3赋值1,引脚P1.3就能输出高电平VCCWhile(1); //死循环,相当LOOP:gotoLOOP;}注意:P0的每个引脚要输出高电平时,必须外接上拉电阻(如4K7)至VCC#include<AT89x52.h>//该头文档中有单片机资源的符号化定义,其中voidmain(void) //void{P2_7=0; //给P2_7赋值0,引脚P2.7就能输出低电平GNDWhile(1); //死循环,相当LOOP:gotoLOOP;}在某引脚输出编程方:(比如P3.1引脚#include<AT89x52.h>//该头文档中有单片机资源的符号化定义,其中voidmain(void) //void{While(1 {P3_1=1; //给P3_1赋值1,引脚P3.1就能输出高电平VCCP3_1= 形成}将某引脚的输入电平取反后,从另一个引脚输出(比如P04NOT(P11))#include<AT89x52.h>//该头文档中有单片机资源的符号化定义,其中包P0.4P1.1voidmain(void) //void{P1_1= //初始化。P1.1While(1 {if(P1_1==1 P0_4= //给P0_40P0.4P1.1=}//给P0_40,引脚P0.4 =}//给P0_41,引脚P0.4 P1.1}88(比如P2=NOT(P3))#include<AT89x52.h>//该头文档中有单片机资源的符号化定义,其中包P2和P3voidmain(void) //void{P3= //初始化。P3P38While(1 1,P2=P3^0x0f//P3,就是认为P3为输入,低四位异或者1,即取 P3}注意个字8位D7D6至D0分别输P37P36至P30,比如P3=0x0f,则P37、P36、P35、P34四个引脚都输出低电平,而P3.3、P3.2、P3.1、P3.0四个引脚都输出高电平。同样,输入一个端口P2,即是将P27、P26至P2.0,读入到一个字节8D7、D6D0。IN40GND(PI20:X1(PIN18X2(PIN1912MHz30pF3、接复位:RES(PIN9。接上电复位电路,以及手动复位电路,分析复位工作EA(PIN31IO输出要P1.1出高电平VCC,LED导通(导通时LED上的压降大于1V,有电LED(5V-1V)/10K0.4mAP1.1低电平GND,实际小于0.3V,LED就不能导通,结果LED不亮。KEY_ONP1.6与GNDKEY_OFF接P1.7与GNDONOFF#include#defineLED //用符号LED代替P1_1#defineKEY_ON //用符号KEY_ON代替P1_6#define //用符号KEY_OFF代替voidmain(void) //单片机复位后的执行,void表示空,无{KEY_ON= 0,KEY_OFF=1; KEY_OFF,P1.7为0,否则输入为1While(1 {if(KEY_ON==0 LED=1;KEY_ONP1.1亮if(KEY_OFF==0)LED=0;KEY_OFFP1.1灭 //同时按下时,LED}段笔画所以称为七段数码管而余下的1个发光二极管作为小数点。作为,分别给8个发光二极管标上记号:a,b,c,d,e,f,g,h。对应8的顶上一画,按顺时针方向排,中间一画为g,小数点为h。通常又将各二极与一个字节的8位对应,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相应8个发光二极管正Pn88法为:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),这种数码管则被称为共阴数码管,共同的引脚则称为共阴极,8个正极则如果是将正极PDF文件使用"pdfFactory称为共阳数码管,共同的引脚则称为共阳极,8个负极则为段极。以单支共阴数码管为例,可将段极接到某端口Pn,共阴极接GND,则可编写P1SLEDP2、P316为KEY_0KEY_1到KEY_F,操作时只能按一个键按键后SLED显示对应键#include<at89x52.h>#defineSLEDP1#defineKEY_0P2^0#defineKEY_1P2^1#defineKEY_2P2^2#defineKEY_3P2^3#defineKEY_4P2^4#defineKEY_5P2^5#defineKEY_6P2^6#defineKEY_7P2^7#defineKEY_8P3^0#defineKEY_9P3^1#defineKEY_AP3^2#defineKEY_BP3^3#defineKEY_CP3^4#defineKEY_DP3^5#defineKEY_EP3^6#defineKEY_FP3^7CodeunsignedcharSeg7Code[16]= //0 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};voidmain(void{unsignedchari=0; P20xff;P2P30xff;P3While(1){0)0)0)0)0)0)0)0)0)0)0)0)if(KEY_C==0)i=0xC; if(KEY_D==0)i=0xD;if(KEY_E==0) if(KEY_F==0)SLED=Seg7Code[i }}I/O码管可接成静态显示方式,两个共阴数码管分别接在P1(秒十位)和P2(秒个位)口,它们的共阴极都接地,安排两个按键接在P3.2(十位数调整)和P3.3(个位数调整)12MHz2,250250us,定义一整数变量计数重载次4000S10S1#includeCodeunsignedcharSeg7Code[16]=//用十六进数作为数组下标,可直接取//0123456789AbCdEF{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};voidmain(void{unsignedintus250=0;unsignedchars10=0;unsignedchars1=0;unsignedcharkey10=0; unsignedcharkey1= //初始化定时器TMOD=(TMOD&0xF0)|TH1=-250; 0TR1= P1=Seg7Code[s10]; P2=Seg7Code[s1];//显示秒个位while(1 if(TF01){TF0=if(++us2504000){us250=0;if(++s1>=10){s1=if(++s10>=6)s10=}}} P3.2= if(key10==1){//等松键if(P3.2==1) } if(P3.2==0){key10=if(++s10>=6)s10=}} P3.3= if(key1==1 if(P3.3==1 if(P3.30){key11;if(++s1>=10)s1=}}第三节:路通60106010P16#include//sbitsbitSNRed=P1^0; sbitSNYellow=P1^1; sbitSNGreen=P1^2; sbitEWRed=P1^3; sbitEWYellow=P1^4; sbitEWGreen //东西方向绿/*用产生延时一个单位时间*/voidDelay1Unit(void){unsignedinti,for(i=0;i<1000;i++for(j<0;j<1000;j+j1ms时//还可以通过生成汇编程序来计算指令周期数,结合晶体频率来调整j循环次1ms}/*nvoidDelay(unsignedintn){for(;n!=0;n--)Delay1Unit();}voidmain(void){while(1{SNRed=0;SNYellow=0;SNGreen=1;EWRed=1;EWYellow=0;EWGreen=0;Delay(60);SNRed=0;SNYellow=1;SNGreen=0;EWRed=1;EWYellow=0;EWGreen=0;Delay(10);SNRed=1;SNYellow=0;SNGreen=0;EWRed=0;EWYellow=0;EWGreen=1;Delay(60);SNRed=1;SNYellow=0;SNGreen=0;EWRed=0;EWYellow=1;EWGreen=0;Delay(10);}}fosc=12MHz,1ms#includeunsignedchar DisBuf[7]SLED,voidDisplayBrushvoid CodeunsignedcharSeg7Code[16]= staticunsignedchari=0;//(0≤i≤7)P2= //显示消隐,以免下一段码值显示一支P1=Seg7Code[DisBuf[i]];//从显示缓冲区取出原始数据,查表变为七P2=cathode[i]; if(++i>=8)i=0; }voidTimer0IntRoute(void)interrupt{TL0=-1000; TH0=(-1000)>>8;//取(-1000)8TH0,1ms}voidTimer0Init(void TMOD=(TMOD&0xf0|0x01T0,1TL0=-1000;1msTH0=(-TR0= ET0= } dataValue){DisBuf[index]=dataValue;}voidmain(void{unsignedcharfor(i=0;i<8;iDisplay(i,8-iDisBuf[0]EA= }#ifndef#ifndef#define //只要过一次,即#include<key.h>,则定义符unsignedcharkeyHit(void); unsignedcharkeyGet(void); voidkeyPut(unsignedcharucKeyValucKeyValvoidkeyBack(unsignedcharucKeyVal); ucKeyVal定义函数体文档KEY.C#include#define 16unsignedcharKeyBuf[KeyBufSize]; //先出,循环存取,下标从0到KeyBufSize-1unsignedcharKeyBufWp=0; unsignedchar unsignedcharkeyHit(void) if(KeyBufWp==KeyBufRp)return(0);elsereturn(1);unsignedcharkeyGet(void unsignedchar while(keyHit()==0 //等待按键,因为函数keyHit()的返回值为retVal=KeyBuf[KeyBufRp if(++KeyBufRp>=KeyBufSize)KeyBufRp=0; return(retVal}voidkeyPut(unsignedcharucKeyVal KeyBuf[KeyBufWp]=ucKeyVal;//键值存入数组if(++KeyBufWp>=KeyBufSize)KeyBufWp=0; }voidkeyBack(unsignedcharucKeyVal{KeyBufRp=0;1FFH,KeyBufSize,即从数组头退回到数KeyBufRpif(KeyBufRpKeyBufSizeKeyBufRp=KeyBufSize-1;KeyBuf[KeyBufRp]=ucKeyVal;//回存键值}电路共同点:P2GND,P2.0aP2.1共同点:codeunsignedcharSeg7Code[10Codeunsignedchar//0 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};例一:P1.0接一按键到GND, 为‘6’,显示按键#include#includevoidmain(void P1_0=1; while(1)//为真,即死循环 if(P1_0==0 keyPut(6);//保存按键值为按键队while(P1_00);//如果一直按着键,则不停地执行该循环,}if(keyHit()!=0)P2=Seg7Code[keyGet}}例二:在例一中考虑按键20ms抖动问题#include#includevoidmain(void P1_0=1; while(1)//为真,即死循环 if(P1_0==0 delay20ms();20ms,跳过接下抖动keyPut(6);//保存按键值为按键队列while(P1_00);//如果一直按着键,则不停地执行该循环,delay20ms();//20ms,跳过}if(keyHit()!=0)P2=Seg7Code[keyGet}}#include#includevoidmain(void P1_0=1; while(1)//为真,即死循环 if(P1_0==0 20ms,跳过接下抖动if(P10==1continue;//假按键keyPut(6);//保存按键值为按键队列while(P1_00);//如果一直按着键,则不停地执行该循环,delay20ms20ms,}if(keyHit()!=0)P2=Seg7Code[keyGet}}/****************************************************************************************采用晶体为12KHz时,指令周期为1ms(即主频为1KHz),这样T0工作在定时器方式2,8位自动重载。计数值为20,即可产生20ms的周期性中断,在中断*****************************************************************************************/#include#includevoidmain(void{TMOD=(TMOD&0xf0)|0x02;T1,T0TH0=-20; //计数周期为20个主频脉,即20ms T0 while(1)//为真,即死循{if(keyHit()!=0)P2=Seg7Code[keyGet}}voidtimer0int(void)interrupt1//20ms;T0 staticunsignedcharP1_0=1; switch(sts){case0:if(P1_0==0)sts=1;break; case1:if(P1_0==1) else{sts=2;keyPut(6case2:if(P1_0==1)sts=3;break; case3:if(P1_0==0) else //真松键,回状态0}}/****************************************************************************************如果采用晶体为12MHz时,指令周期为1us(即主频为1MHz),要产生20ms左右的计时,则计数值达到20000,T0工作必须为定时器方式1,16位非自动重载,即可产生20ms的周期性中断,在中断服务程序中实现按键扫描*****************************************************************************************/#include#includevoidmain(void{TMOD=(TMOD&0xf0)|0x01;T1,T0TL0=- 20000位TH0=(-T01)//为真,即死循{if(keyHit()!=0)P2=Seg7Code[keyGet}}voidtimer0int(void)interrupt1//20ms;T0 staticunsignedcharTL0=- TH0=(- P1_0=1; switch(sts){case0:if(P1_0==0)sts=1;break; case1:if(P1_0==1) else{sts=2;keyPut(6case2:if(P1_0==1)sts=3;break; case3:if(P1_0==0) else //真松键,回状态0}} X4按键/****************************************************************************************P1444X4X,Y0x7,0xb,0xd,0xe,0xfkeyCode123456789ABCDEF*****************************************************************************************/#include<at89x52.h>#include“KEY.H”unsignedcharkeyScan(void)//返回0{codeunsignedchar/0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF{ 0unsignedcharx,y, //低四位输入,高四位输出0 //P1输入后,四位,作为X值 //高四位输入,低四位输出0y=(P1>>4)&0x0f;//P1输入后移位到低四位,并四位,作为Y值retVal=keyCode[x]*4+keyCode[y]; if(retVal==0)return(0);elsereturn(retVal-4);}=voidmain(void){TMOD(TMOD&0xf0)|0x01;T1,T01TL0=- 20000位TH0=(- T0 while(1)//为真,即死循{if(keyHit()!=0)P2=Seg7Code[keyGet}}voidtimer0int(void)interrupt1//20ms;T0 staticunsignedcharTL0=- TH0=(- P1_0=1; switch(sts){case0:if(keyScan()!=0sts=1;break1case1:if(keyScan()==0)sts=0; //假按错,或干扰,回状态0else{sts=2;keyPut(keyScan());} case2:if(keyScan()==0)sts=3; 3caseif(keyScan()!=0) else //真松键,回状态0}}24MHz2MHzT1100us,T0测信号是周期性矩形波(0.5us1MHz,大1Hz1S0.1%。1KHz1S个数来测量信号频,而信号频率低于1KHz时,可以通过测量信号的周期来求出1KHz1ms,1000us,而我们用的定时器计时脉冲周期为0.5us,如果定时多计或少计一个脉冲,误差为1us,所以相对误差为1us/1000us=0.1%。信号周期越大,即信号频率越低,相1KHz1000us,显然采用上面的测量方法,不能达到测量精度要求,这时采用1S单位时间计数10001MHz,而定时脉冲为2MHz,多计或少计一个信号脉冲,这样相对误差为1/1000,可INT1(P3.3unsignedint //对100us100usunsignedcharunsignedintK64; unsignedcharoldT0;unsignedintoldus,oldK64,unsignedlong bitHighLow=1; //1voidInitialHigh(void){IE=0;IP=0;TMOD=(TMOD&0xf0)|0x02;TH0=-200;TL0=TH0;PX0=1;T0=1;TMOD=(TMOD&0x0f)|0x50;TH1=0;TL1=0;T1=1;ET1=1;Us100=0;Second=0;K64=0;oldK64=0;TCON|=0x50; TR0=1;TR1=1;EA=1;}voidInitialLow(void{IE=0;IP=0;TMOD=(TMOD&0xf0)|0x02;TH0=-200;TL0=TH0;ET0=1;TR0=1;INT1=1;IT1=1;EX1=1;Us100=0;Second=0;oldK64=0;oldT1=0;EA=1;}voidT0intr(void)interrupt if(HighLow==0)++us100;if(++us100>=10000 unsignedinttmp1,TR1=0;tmp1=(TH1<<8)+(TL1);tmp2=K64;fcy=((tmp2-oldK64)<<16)+(tmp1-oldT1);oldK64=tmp1;oldT1=tmp2;}}voidT1intr(void)interrupt3{ ++K64;}voidX1intr(void)interrupt2 staticunsignedcharsts=0;switch(sts){case0:sts=1;case1:oldT0=TL0;oldus=us100;sts=2;break;case2:{unsignedchartmp1,TR0=0;tmp1=TL0;tmp2=us100;fcy=1000000L/((tmp2-oldus)*100L+(256-tmp1)/2);Second++;}Sts=0;}}voidmain(void{if(HighLow==1)InitialHigh();elseInitialLow();{if(Second!=0{Second=//displayfcy 前面的数码管驱动程序,注意下面对T0中断 unsignedcharfor(i=0;i<8;i++){Display(i,fcy%10);fcy/=10;}if(HighLow==1if(fcy<1000L){InitalLow();}if(fcy>1000L){}}}//修改T0的中断服务程序,让它在完成时标的功能时,同时完成数码管显示刷voidT0intr(void)interrupt{staticunsignedcharms=0;if(HighLow==0)++us100;if(++us100>=10000 unsignedinttmp1,TR1=0;tmp1=(TH1<<8)+(TL1);tmp2=K64;fcy=((tmp2-oldK64)<<16)+(tmp1-oldT1);oldK64=tmp1;oldT1=tmp2;}if(++ms>=10){ms=0;DisplayBrush();/1ms}整状态时,按键不足一秒为光标移动‘M’,超过一秒则为调整读数,每0.5秒加一‘A10W’。enumstatus={Work,Change,Add,Move,Screen TimeunsignedcharTime[12]={0,4,0,6,1,0,0,8,4,5,3,2};//0406084532unsignedcharcursor=12;//指向秒个位,=0unsignedcharYmDhMs= staticunsignedcharsts=小数点显示与YmDhMs变量相关。voidDisScan(void)//动态刷新显示时调用。没编完,针对共阴数码管,只{//DisBuf每个显示数据的高四位为标志,最D7为负号,D6为小数点unsignedchartmp=Seg7Code[?x&0x1f]; 将低5位变为七段码if(?x&0x40)tmp|= if(?x&0x20){if(S01&0x01)tmp=0;,S01tmp}voidDisplay(void {if(cursor!=0){YmDhMs=(cursor+3)/4;}//1..4=1; for(i=(YmDhMs-1)*4;i<(YmDhMs)*4;i++ unsignedcharj=i%4;Disbuf[j]=Time[i];if(i==(cursor-1))Disbuf[j]|=0x20;,cursor!=0时if(i==9)||//小数点:分个位(i==7)||//小数点:时个位(i==5)||//小数点:日个位(i==3)//小数点:月个位)Disbuf[j]|=//if(i==2){if(Time[2]==1)DisBuf[2]=“-1”;DisBuf=“-”;}YmDhMs将屏数据装入cursor将屏数据装入}voidKeyScan(void voidProcessKey(void {keyVal=if(keyVal==0)return;switch(sts){caseif(keyVal{if(YmDhMs==0)YmDhMs=3;}if(keyVal=={sts=Change;YmDhMs=3;Cursor=}caseChange:if(keyVal==‘W’)if(keyVal==‘A’if(keyValMcursor}}22.1184MHzAT89C521,/r/

温馨提示

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

评论

0/150

提交评论