版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
PAGEPAGE1实验LED流水灯一、实验目的1.学习单片机并口的使用方法。2.学习延时子程序的编写和使用。3.学习集成开发环境MedWin的安装与使用。4.学习STC单片机在线下载软件STC-ISP的使用。二、实验内容所谓流水灯就是8个发光二极管(LED)轮流点亮,周而复始。实验板上以P0口作输出口,经74LS244驱动,接8只发光二极管LED0-LED7。当单片机的引脚输出为低电平时发光二极管点亮,为高电平时息灭。编写程序,使8个发光二极管循环点亮,时间间隔约0.5秒。三、实验电路连线实验板上与本实验有关的硬件如下图所示。74LS244驱动输出串联8个限流电阻接8个LED发光管,以防止其电流过大而烧坏。单片机的主时钟为11.0592MHz。JMP0和JMP1都短接1-2脚。四、实验说明1、P0口作为通用接口时是一准双向口,它作为输出口时与一般的双向口使用方法相同。由准双向口结构可知当P0口用作输入口时必须先对它置“1”。若不先对它置“1”,读入的数据是不正确的。输出时需要接上拉电阻,P0口内部没有上拉电阻,若将外围电路设计为低有效,高无效,则无需再外接上拉电阻。2、编写一个软件延时子程序,延时时间约0.5秒,采用三重循环实现,汇编语言程序如下:DELAY:MOVR7,#198DEL1:MOVR6,#50DEL2:MOVR5,#23 DJNZR5,$ DJNZR6,DEL2DJNZR7,DEL1 RET查指令表可知执行MOV指令需用1个机器周期,DJNZ指令需用2个机器周期,在11.0592MHz晶振时,一个机器周期时间长度为1.085μs,所以该段程序执行时间为:[1+(1+2×23)×50]×198×1.085μs≈500mS3、若使用C语言,可用for循环实现延时,下面的程序延时约500mS。voiddelay(void){ inti,j; for(i=0;i<1000;i++) for(j=0;j<50;j++) {_nop_();_nop_();}}4、流水灯的主程序(汇编语言)为: ORG0000H LJMPMAIN ORG0100HMAIN: CLRP1.5 ;P1.5=0,关闭蜂鸣器。MOVA,#0FEHLOP: MOVP0,A LCALLDELAY RLA SJMPLOP END5、流水灯的C语言主程序为:#include<reg51.h>#include<stdio.h>#include<intrins.h>voidmain(void){ unsignedchara,c; P1=0xdf; //P1.5=0,关闭蜂鸣器。 a=0xfe; while(1) { P0=a; c=a&0x80; a=a<<1; a=a|(c==0x80); delay(); }}五、思考题1.如何使点亮的LED从右往左移动?2.如何使点亮的LED从两边往中间移动?
实验二用一位数码管循环显示数字0~9一、实验目的1.学习单片机并口的使用方法。2.学习延时子程序的编写和使用。3.学习LED数码管的驱动、编码。二、实验内容实验板上有8个LED数码管,编写程序,使最右边的一个LED数码管循环显示0~9十个数字。时间间隔约0.5秒,其余LED数码管关闭。三、实验电路连线实验板上与本实验有关的硬件如下图所示。8个共阳的LED数码管(S0-S7)上同名的引脚连接在一起,由单片机P0口通过74HC244驱动(段控制),R12-R19为限流电阻。单片机P2口的8个引脚分别通过三极管Q0-Q7控制8个LED数码管的公共端(位控制)。单片机的主时钟为11.0592MHz。JMP0短接2-3脚,JMP1短接1-2脚。8λLEDÊýÂë¹Ü¶¯Ì¬ÏÔʾµç·8λÊý¾ÝÇý¶¯Íâ½Ó¾§Õñ四、实验说明1、P0口和P2都是准双向口,输出时需要接上拉电阻。P0内部没有上拉电阻,P2口内部有弱上拉。2、下表为驱动LED数码管的段代码表,1--代表对应的笔段亮,0--代表对应的笔段不亮。若需要在最右边(S0)显示数字“5”,只要将从表中查得的段代码2CH写入P0口,再将P2.0置高,P2.1-P2.7置低即可。数字dpecgbfa十六进制P0.7P0.6P0.5P0.4P0.3P0.2P0.1P0.0共阴共阳010110111B74810001010014EB210101101AD523100111019D624000111101E64610111011BB4470001010115EA810111111BF409100111119F603、实现最右边的一个LED数码管循环显示0~9十个数字的C语言程序如下:#include<reg51.h>#include<stdio.h>#include<intrins.h>#defineucharunsignedcharconstucharcodetab[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60};voiddelay(void){ inti,j; for(i=0;i<1000;i++) for(j=0;j<50;j++) {_nop_();_nop_();}}voidmain(void){ uchari; P2=0x01; P1=0xdf; while(1) { P0=tab[i]; delay(); i++; if(i==10)i=0; }}4、实现最右边的一个LED数码管循环显示0~9十个数字的汇编语言程序如下:ORG0000H LJMPMAIN ORG0100HMAIN: MOVP1,#0DFH MOVP2,#01H MOVR1,#00HLOOP: MOVA,R1 MOVDPTR,#TAB MOVCA,@A+DPTR MOVP0,A LCALLDELAY INCR1 MOVA,R1 CJNEA,#10,LOOP CLRA MOVR1,A SJMPLOOP DELAY: MOVR7,#198DEL1: MOVR6,#50DEL2: MOVR5,#23 DJNZR5,$ DJNZR6,DEL2 DJNZR7,DEL1 RETTAB: DB48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H END五、思考题1.分别写出六个字母(用于显示十六进制数)的段代码,编写程序,在最右边数码管上实现0-F的循环显示。2.能否交替点亮点8个LED数码管?
实验三LED数码管的动态驱动一、实验目的1.学习LED数码管的动态驱动编程。2.学习使用定时/计数器、中断。3.学习汇编语言的有关运算。二、实验内容编写程序,使实验板上的8个LED数码管稳定显示8个不同的数字,并使这四位数从00000000开始,每0.5秒钟加1。三、实验电路连线本实验有关的硬件见实验二。四、实验说明1.在实验二中,我们已经能够让某一个LED数码管显示需要的数字,比如选让第一个LED显示“1”,隔一较短的时间(如2.5毫秒)后关闭第一个LED,让第二个LED显示“2”,如此周而复始,让8个LED依次显1、2、3、4、5、6、7、8,我们就能看到8个LED上稳定地显示8个不同的数字。当然,每个瞬间只有一个LED被点亮,大家亮的时间相同,均为2.5毫秒,8个LED数码管点亮一遍需要20毫秒,一秒钟各亮50次,所以看上去不会有闪烁感,但亮度只是实验二中LED亮度的八分之一。要实现每隔再隔2.5毫秒变换一个LED,最好的方法是使用定时器中断。2.汇编语言参考程序为:LED_PORT EQU P0 ;笔划输出,低有效SCN_PORT EQU P2 ;段扫描输出,低有效(P2.4-P2.7) DSEG ORG 10HDISP_BUF: DS 8 ;显示缓冲区SCN_INX: DS 1 ;扫描指针SCN_COD: DS 1 ;扫描码CNT: DS 1 ;中断计数,每2.5ms加1 CSEG ORG 00H LJMP MAIN ;主程序入口,转初始化程序 ORG 0BH ;定时中断0入口 LJMP INTP0 ;每2.5ms中断一次,用于刷新显示;初始化 ORG 30HMAIN: MOV SP,#50H ;初始化堆栈指针 CLR RS0 ;选用第0组通用寄存器 CLR RS1 CLRP1.5 CLR A MOV CNT,A MOVR1,#8 MOVR0,#DISP_BUFLOOP1: MOV@R0,A ;显示缓冲区清零 INCR0 DJNZR1,LOOP1 MOV SCN_INX,A ;扫描指针置0MOVSCN_COD,#80H ;右边LED先点亮MOV TMOD,#01H ;定时器0,方式1 MOV TH0,#0F7H ;计数初值,每次2.5ms(11.0592MHz晶振) MOV TL0,#000H ;65536-(2.5ms/1.085us)=65536-2304=63232=0F700H SETB TR0 ;启动定时器0 SETB EA ;中断总允许 SETB ET0 ;允许定时器0中断 SJMP $ ;主程序在此循环;定时器0中断服务程序,间隔2.5msINTP0: PUSH ACC PUSH PSW MOV TH0,#0F7H ;置计数初值 MOV TL0,#00H SETB RS0 ;选用第1组通用寄存器 CLR RS1 MOV A,SCN_INX ;取扫描指针 ANL A,#07H ;清除高5位 ADD A,#DISP_BUF ;加显示缓冲区首地址 MOV R1,A MOV A,@R1 MOV DPTR,#CODE_TAB ;DPTR指向笔划代码表 ANL A,#0FHMOVCA,@A+DPTR ;取笔划代码 MOVLED_PORT,A ;笔划代码送LED口 MOV A,SCN_COD ;取扫描段代码 MOV P2,AMOV A,SCN_CODRRA ;扫描段代码循环右移一位 MOV SCN_COD,A INC SCN_INX ;扫描指针+1 INC CNT MOV A,CNT CJNEA,#200,EN MOV CNT,#0 INC DISP_BUF+7 ;个位加一 MOV A,DISP_BUF+7 CJNEA,#10,EN ;不进位转移 MOV DISP_BUF+7,#0 ;进位则个位清零 INC DISP_BUF+6 ;十位加一 MOV A,DISP_BUF+6 CJNEA,#10,EN MOV DISP_BUF+6,#0 ;进位则十位清零 INC DISP_BUF+5 ;百位加一 MOV A,DISP_BUF+5 CJNEA,#10,EN MOV DISP_BUF+5,#0 ;进位则百位清零 INC DISP_BUF+4 ;千位加一 MOV A,DISP_BUF+4 CJNEA,#10,EN MOV DISP_BUF+4,#0 ;进位则千位清零 INC DISP_BUF+3 ;万位加一 MOV A,DISP_BUF+3 CJNEA,#10,EN MOV DISP_BUF+3,#0 ;进位则万位清零 INC DISP_BUF+2 ;十万位加一 MOV A,DISP_BUF+2 CJNEA,#10,EN MOV DISP_BUF+2,#0 ;进位则十万位清零 INC DISP_BUF+1 ;百万位加一 MOV A,DISP_BUF+1 CJNEA,#10,EN MOV DISP_BUF+1,#0 ;进位则百万位清零 INC DISP_BUF+0 ;千万位加一 MOV A,DISP_BUF+0 CJNEA,#10,EN MOV DISP_BUF+0,#0 ;进位则千万位清零 EN: POP PSW POP ACC RETI;笔划代码表CODE_TAB: DB 48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H END3.C语言参考程序为:#include<reg51.h>#defineucharunsignedcharconstucharcodetab1[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60};constucharcodetab2[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};ucharbuf[8]={0,0,0,0,0,0,0,0};//显示缓冲区,开机先显示"00000000"voidmain(void){ P1=0xdf; EA=1; //允许中断 TMOD=0x01; //设定时器0为模式1(16位) ET0=1; //定时器0中断允许 TH0=0xf7; //晶振11.0592MHz,2.5ms TL0=0; TR0=1; //开始计数 while(1); //死循环,等待中断}voidtimeint(void)interrupt1//定时器0中断服务程序{ staticuchark,count; chari; TH0=0xf7; //设置定时器时间常数 TL0=0; k++; k&=0x07; P0=tab1[buf[k]]; //笔划代码送P0口 P2=tab2[k]; //控制扫描码送P2口 if(++count==200) //计数200次为2.5msX200=0.5s { count=0; //到0.5秒钟,显示的数字加一 for(i=7;i>=0;i--) {buf[i]++; if(buf[i]==10)buf[i]=0;//加到10向前进位 elsebreak; } }}五、思考题如何让8个LED数码管从00-00-00开始,每秒钟自动加1,前两位代表时,中间两位代表分,后两位代表秒?
实验四用单片机自动演奏乐曲一、实验目的(1)进一步熟悉89C51定时器/计数器的功能及应用;(2)掌握其初始化与中断服务程序的编程方法;(3)掌握用定时器/计数器发出不同音调的编程方法。二、实验内容用单片机的定时器/计数器0作定时器使用,工作于模式1,中断产生方波发声,根据各个的频率,计算对应的定时时间常数,定时器中断后按此常数赋初值,从而发出对应的音调。将歌曲的音调和节拍编成一个表,用音调作为定时器的初值,用节拍控制发音时间,就可以实现自动演奏。三、实验电路连线本实验有关的硬件如右图所示。四、实验说明声单定时初值常数计算方法:根据下表的音阶频率,计算对应的音阶周期T,用T/2计算定时周期数(晶振11.0592MHz),填入下表中。定时器的计数初值为65536-定时周期数,在程序计算产生。定时周期数增加1倍,音阶降低八度,定时周期数降低1倍,音阶升高八度。音阶(C调)1234567频率(Hz)256288320341384427480周期(μs)3906347231252932260423422083定时周期数3600320028802702240021581920自动演奏《东方红》乐曲的C语言程序为:#include<REG51.h>#defineucharunsignedchar#defineuintunsignedintsbitP15=P1^5;codeuintcyc[]={3600,3200,2880,2702,2400,2158,1920};//音阶1-7对应的计数周期数codeuchartone[]={15,15,16,12,11,11,06,12,15,15,16,21,16,15,11,11, 06,12,15,12,11,7,6,5,15,12,13,12,11,11,6,12, 13,12,11,12,11,7,6,5,0};//乐曲《东方红》的简谱表codeuchartime[]={8,4,4,16,8,4,4,16,8,8,4,4,4,4,8,4, 4,16,8,8,8,4,4,8,8,8,4,4,8,4,4,4, 4,4,4,4,4,4,4,16,0};//节拍表(8为1拍,约570mS)ucharH0,L0,cnt;voidcntint0(void)interrupt1//定时器0中断用于产生音调{ TH0=H0; TL0=L0; P15=~P15; //P1.5是音乐信号输出脚}voidcntint1(void)interrupt3//定时器1中断用于产生节拍{ cnt++; //定时器的计数初值为0,所以不用赋值}voidmain(void){ uchari,a,t; uintb;next: TMOD=0x11; EA=1; ET0=1; ET1=1; cnt=0; TR1=1; i=0; while(1) { t=tone[i]; //读音调 if(t==0)break; //是0,则结束 b=cyc[t%10-1]; if(t<10)b=b*2; if(t>20)b=b/2;b=b/2; H0=(65536-b)/256; L0=(65536-b)%256; cnt=0; a=time[i]; //读节拍 if(a!=255)TR0=1; //255是休止符 while(a>cnt); TR0=0; i++; for(b=0;b<1000;b++); } P15=1; //关闭喇叭 gotonext; //重放一遍}五、思考题参考《东方红》乐曲的演奏程序,编写《康定情歌》乐曲的演奏程序。《康定情歌》的乐谱如下:康定情歌13,15,16,16,15,16,13,12,12,13,15,16,16,15,16,13,13,13,15,16,16,15,8,8,8,4,4,8,8,12,4,8,8,8,4,4,8,16,8,8,8,8,4,4,16,13,12,12,15,13,12,13,12,11,12,6,6,12,8,8,12,4,8,8,4,4,4,4,8,24,8,24,15,13,12,6,16,15,13,12,13,12,11,12,6,5,68,24,8,16,8,8,8,4,4,4,4,8,16,8,32附:自动演奏乐曲《八月桂花启遍地开》的汇编语言参考程序。ORG0000HLJMPSTART ORG000BH INC20H ;中断服务,中断计数器加1 MOVTH0,#0DCH MOVTL0,#00H ;11.0592MHz晶振,形成10毫秒中断 RETISTART: MOVSP,#50H MOVTH0,#0DCH MOVTL0,#00H MOVTMOD,#01H MOVIE,#82HMUSIC0: NOP MOVDPTR,#DAT ;表头地址送DPTR MOV20H,#00H ;中断计数器清0MUSIC1: NOP CLRA ;ACC清零 MOVCA,@A+DPTR ;查表取代码 JZEND0 ;是00H,则结束 CJNEA,#0FFH,MUSIC5 ;如果是休止符,往下执行 LJMPMUSIC3MUSIC5: NOP MOVR6,A ;R6=18H音符的频率 INCDPTR ;DPTR加一 MOVA,#0 MOVCA,@A+DPTR ;取节拍代码送R7 MOVR7,A ;R7=30H音符发音的时间 SETBTR0 ;启动计数MUSIC2: NOP CPLP1.5 ;P1.5是音乐输出引脚 MOVA,R6 MOVR3,A ;R3=R6=18H LCALLDEL MOVA,R7 CJNEA,20H,MUSIC2 ;中断计数器(20H)=R7否?;不等,则继续循环 MOV20H,#00H ;等于,则取下一代码 INCDPTR LJMPMUSIC1MUSIC3: NOP ;休止100毫秒 CLRTR0 MOVR2,#0DH ;R2=13MUSIC4: NOP MOVR3,#0FFH ;R3=255 LCALLDEL DJNZR2,MUSIC4 INCDPTR LJMPMUSIC1END0: NOP MOVR2,#0FFH ;歌曲结束,延时1秒后继续MUSIC6: MOVR3,#00H LCALLDEL DJNZR2,MUSIC6 LJMPMUSIC0DEL: NOPDEL3: MOVR4,#02HDEL4: NOP DJNZR4,DEL4 NOP DJNZR3,DEL3 RETDAT: DB18H,30H,1CH,10H,20H,40H,1CH,10H,18H,10H,20H,10H,1CH,10H,18H,40H DB1CH,20H,20H,20H,1CH,20H,18H,20H,20H,80H,0FFH,20H,30H,1CH,10H,18H DB20H,15H,20H,1CH,20H,20H,20H,26H,40H,20H,20H,2BH,20H,26H,20H,20H DB20H,30H,80H,0FFH,20H,20H,1CH,10H,18H,10H,20H,20H,26H,20H,2BH,20H DB30H,20H,2BH,40H,20H,20H,1CH,10H,18H,10H,20H,20H,26H,20H,2BH,20H DB30H,20H,2BH,40H,20H,30H,1CH,10H,18H,20H,15H,20H,1CH,20H,20H,20H DB26H,40H,20H,20H,2BH,20H,26H,20H,20H,20H,30H,80H,20H,30H,1CH,10H DB20H,10H,1CH,10H,20H,20H,26H,20H,2BH,20H,30H,20H,2BH,40H,20H,15H DB1FH,05H,20H,10H,1CH,10H,20H,20H,26H,20H,2BH,20H,30H,20H,2BH,40H DB20H,30H,1CH,10H,18H,20H,15H,20H,1CH,20H,20H,20H,26H,40H,20H,20H DB2BH,20H,26H,20H,20H,20H,30H,30H,20H,30H,1CH,10H,18H,40H,1CH,20H DB20H,20H,26H,40H,13H,60H,18H,20H,15H,40H,13H,40H,18H,80H,00H END
实验五电子钟一、实验目的1.学习使用定时/计数器。2.学习独立式按键的查询识别方法。3.学习实用程序的编程技巧。二、实验内容在实验板上编写程序,实验电子钟功能。时间显示格式为HH-MM-SS,用按键可以调整当前时间,具有整点提示功能。三、实验电路连线本实验有关显示部分的硬件见实验二,按键连接见下图。四、实验说明该电子钟在上电或复位后时间从13时59分50秒开始,若要使电子钟断电后照常行走,应采取电池供电。为了降低使用成本及减小体积,可采用两节5号电池,其满电量时电压为3伏,89C51单片机的正常工作电压范围为4.5~5.5伏,无法使用,可选用89C2051单片机(电压范围2.7~6伏),最好使用工作电压更低的单片机(如1.8伏)。为了延长电池使用寿命,必须采取一些节电措施,如将LED换成液晶、让单片机不工作时进入休眠方式、适当降低单片机的时钟频率等。电子钟C语言参考程序如下:(含按键检测、调整时间、整点提示功能)#include<reg51.h>#include<stdio.h>#include<intrins.h>typedefunsignedcharuchar;typedefunsignedintuint;typedefunsignedlongulong;#defineK00x01#defineK10x02#defineK20x04#defineK30x08ucharsec=50,min=59,hour=13;ucharkey_new;uintcount;uintdelay_time;bitkey_on,key_again;bitNewTime=0;sbitP15=P1^5;voidkeyscan();voiddelay(uintt);voidmain(){ P1=0xdf; TMOD=0x01; TH0=(65536-2304)/256; //设置定时器初值,2.5ms中断一次 TL0=(65536-2304)%256; TR0=1; ET0=1;EA=1; while(1) { if(key_on) { key_on=0; switch(key_new) { caseK0:sec=0;min++;min%=60;count=0;break; caseK1:sec=0;hour++;hour%=24;count=0;break; caseK2:sec=0;hour=0;min=0;count=0;break; caseK3:sec=0;hour=23;min=59;count=0;break; } } if(NewTime==1) { NewTime=0; if((min==59)&&(sec>=55)) { P15=1;delay(80);P15=0;} elseif((min==0)&&(sec==0)) { P15=1;delay(250);P15=0;} } }}//==========================================================================voidkeyscan(){ uchardatakey_temp; staticuchardatakeylong; key_temp=(~P1)&0x0f; if(key_temp==0) {key_new=key_temp;keylong=0;key_on=0;key_again=0;} elseif(key_new!=key_temp) {key_new=key_temp;key_on=0;key_again=0;keylong=1;} elseif(keylong<4) {key_on=0;key_again=0;keylong++;} elseif(keylong==4) {key_on=1;key_again=1;keylong++;} elseif(keylong>200){key_on=0;key_again=1;keylong=170;} else{keylong++;}}//==========================================================================voidtimer_0(void)interrupt1{ codeucharTAB1[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60}; codeucharTAB2[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; staticuchardsp[8]; staticucharn; TH0=(65536-2304)/256; //设置定时器初值,2.5ms中断一次 TL0=(65536-2304)%256; delay_time++; if(++count==400) { ++sec;count=0;NewTime=1; if(sec==60) {++min; sec=0;} if(min==60) {++hour; min=0;} if(hour==24) {hour=0;} } dsp[0]=TAB1[hour/10]; dsp[1]=TAB1[hour%10]; dsp[2]=0xf7; dsp[3]=TAB1[min/10]; dsp[4]=TAB1[min%10]; dsp[5]=0xf7; dsp[6]=TAB1[sec/10]; dsp[7]=TAB1[sec%10]; n++;n%=8; P0=dsp[n];P2=TAB2[n]; if((count%10)==0)keyscan();}//========================================================================voiddelay(uintt){ EA=0; delay_time=0; EA=1; while(delay_time<t);}五、思考题1.给电子钟加上打铃的功能,打铃时间固定。2.给电子钟加上打铃时间调节功能。如何实现多点(4个)打铃功能?附:电子钟汇编参考程序,不含按键检测和整点提示功能。LED_PORT EQU P0 ;笔划输出,低有效SCN_PORT EQU P2 ;段扫描输出,低有效(P2.4-P2.7) DSEG ORG 10HDISP_BUF: DS 8 ;显示缓冲区SCN_INX: DS 1 ;扫描指针SCN_COD: DS 1 ;扫描码CNT: DS 2 ;中断计数,每2.5ms加1 CSEG ORG 00H LJMP MAIN ;主程序入口,转初始化程序 ORG 0BH ;定时中断0入口 LJMP INTP0 ;每2.5ms中断一次,用于刷新显示;初始化 ORG 30HMAIN: MOV SP,#50H ;初始化堆栈指针 CLR RS0 ;选用第0组通用寄存器 CLR RS1 CLRP1.5 CLR A MOV CNT+0,A MOV CNT+1,A MOV DISP_BUF+0,#2 ;时十位 MOV DISP_BUF+1,#3 ;时个位 MOV DISP_BUF+2,#10 ;显示'-' MOV DISP_BUF+3,#5 ;分十位 MOV DISP_BUF+4,#8 ;分个位 MOV DISP_BUF+5,#10 ;显示'-' MOV DISP_BUF+6,#0 ;秒十位 MOV DISP_BUF+7,#0 ;秒个位 MOV SCN_INX,A ;扫描指针置0MOVSCN_COD,#80H ;右边LED先点亮MOV TMOD,#01H ;定时器0,方式1 MOV TH0,#0F7H ;计数初值,每次2.5ms(11.0592MHz晶振) MOV TL0,#000H ;65536-(2.5ms/1.085us)=65536-2304=63232=0F700H SETB TR0 ;启动定时器0 SETB EA ;中断总允许 SETB ET0 ;允许定时器0中断 SJMP $ ;主程序在此循环;定时器0中断服务程序,间隔2.5msINTP0: PUSH ACC PUSH PSW MOV TH0,#0F7H ;置计数初值 MOV TL0,#00H SETB RS0 ;选用第1组通用寄存器 CLR RS1 MOV A,SCN_INX ;取扫描指针 ANL A,#07H ;清除高5位 ADD A,#DISP_BUF ;加显示缓冲区首地址 MOV R1,A MOV A,@R1 MOV DPTR,#CODE_TAB ;DPTR指向笔划代码表 ANL A,#0FHMOVCA,@A+DPTR ;取笔划代码 MOVLED_PORT,A ;笔划代码送LED口 MOV A,SCN_COD ;取扫描段代码 MOV P2,AMOV A,SCN_CODRRA ;扫描段代码循环右移一位 MOV SCN_COD,A INC SCN_INX ;扫描指针+1 INC CNT ;中断计数,计2个200次1秒 MOV A,CNT CJNEA,#200,EN MOV CNT,#0 INCCNT+1 MOVA,CNT+1 CJNEA,#2,EN MOVCNT+1,#0 INC DISP_BUF+7 ;秒个位加一 MOV A,DISP_BUF+7 CJNEA,#10,EN ;不进位转移 MOV DISP_BUF+7,#0 ;进位则秒个位清零 INC DISP_BUF+6 ;秒十位加一 MOV A,DISP_BUF+6 CJNEA,#6,EN MOV DISP_BUF+6,#0 ;进位则秒十位清零 INC DISP_BUF+4 ;分个位加一 MOV A,DISP_BUF+4 CJNEA,#10,EN MOV DISP_BUF+4,#0 ;进位则分个位清零 INC DISP_BUF+3 ;分十位加一 MOV A,DISP_BUF+3 CJNEA,#6,EN MOV DISP_BUF+3,#0 ;进位则分十位清零 INC DISP_BUF+1 ;时个位加一 MOV A,DISP_BUF+1 CJNEA,#10,EN1 MOV DISP_BUF+1,#0 ;进位则时个位清零 INC DISP_BUF+0 ;时十位加一 EN1: MOVA,DISP_BUF+0 CJNEA,#2,EN MOVA,DISP_BUF+1 CJNEA,#4,EN MOV DISP_BUF+0,#0 MOV DISP_BUF+1,#0 EN: POP PSW POP ACC RETI;笔划代码表CODE_TAB: DB 48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H,0F7H END
实验六单片机与PC机的串行通信一、实验目的1.学习单片机串口的设置。2.学习TTL-RS232信号的转换。3.学习单片机串行通信程序设计。二、实验内容实验板上有RS-232接口,将该接口与PC机的串口连接,可以实现单片机与PC机的串行通信,进行双向数据传输。本实验要求在实验五的基础上增加通讯功能,单片机每秒钟向PC机发送用ASCII码表示的时间,格式为HH:MM:SS(时:分:秒)。同时可以通过PC机向单片机发送修改时间的指令,实现时间的调整,指令格式为TIMEHH:MM:SS。三、实验电路连线本实验有关的硬件见下图。四、实验说明51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通信。进行串行通讯信要满足一定的条件,比如电脑的串口是RS232电平(-5~-15V为1,+5~+15V为0),而单片机的串口是TTL电平(大于+2.4V为1,小于-0.7V为0),两者之间必须有一个电平转换电路,上图中用MAX232E集成电路实现RS232电平与TTL电平的相互转换。为了能够在PC机上看到单片机发出的数据,我们必须借助一个Windows软件进行观察,这里我们可以使用免费的串口调试程序SSCOM32或Windows的超级终端。单片机与PC机的串行通信C51参考程序如下:#include<reg51.h>#include<stdio.h>#include<intrins.h>typedefunsignedcharuchar;typedefunsignedintuint;typedefunsignedlongulong;#defineK00x01#defineK10x02#defineK20x04#defineK30x08ucharsec=50,min=59,hour=13;ucharkey_new;uintcount;uintdelay_time;bitkey_on,key_again;bitNewTime=0;sbitP15=P1^5;voidkeyscan();voiddelay(uintt);voidSentTime();voidmain(){ P1=0xdf; TMOD=0x21; //定时器0工作方式1,定时器1工作方式2。 TH0=(65536-2304)/256; //设置定时器0初值,2.5ms中断一次 TL0=(65536-2304)%256; SCON=0x50; //串口工作方式1,允许接收 TH1=0xfd; //设置波特率为9600 TL1=0xfd; TR0=1; TR1=1; ET0=1; ES=1; EA=1; //中断允许 IP=0; PS=1; //串行中断高优先级 while(1) { if(key_on) { key_on=0; switch(key_new) { caseK0:sec=0;min++;min%=60;count=0;break; caseK1:sec=0;hour++;hour%=24;count=0;break; caseK2:sec=0;hour=0;min=0;count=0;break; caseK3:sec=0;hour=23;min=59;count=0;break; } } if(NewTime==1) { NewTime=0; SentTime(); if((min==59)&&(sec>=55)) { P15=1;delay(80);P15=0;} elseif((min==0)&&(sec==0)) { P15=1;delay(250);P15=0;} } }}//==========================================================================voidkeyscan(){ uchardatakey_temp; staticuchardatakeylong; key_temp=(~P1)&0x0f; if(key_temp==0) {key_new=key_temp;keylong=0;key_on=0;key_again=0;} elseif(key_new!=key_temp) {key_new=key_temp;key_on=0;key_again=0;keylong=1;} elseif(keylong<4) {key_on=0;key_again=0;keylong++;} elseif(keylong==4) {key_on=1;key_again=1;keylong++;} elseif(keylong>200){key_on=0;key_again=1;keylong=170;} else{keylong++;}}//==========================================================================voidtimer_0(void)interrupt1{ codeucharTAB1[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60}; codeucharTAB2[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; staticuchardsp[8]; staticucharn; TH0=(65536-2304)/256; //设置定时器初值,2.5ms中断一次 TL0=(65536-2304)%256; delay_time++; if(++count==500) { ++sec;count=0;NewTime=1; if(sec==60) {++min; sec=0;} if(min==60) {++hour; min=0;} if(hour==24) {hour=0;} } dsp[0]=TAB1[hour/10]; dsp[1]=TAB1[hour%10]; dsp[2]=0xf7; dsp[3]=TAB1[min/10]; dsp[4]=TAB1[min%10]; dsp[5]=0xf7; dsp[6]=TAB1[sec/10]; dsp[7]=TAB1[sec%10]; n++;n%=8; P0=dsp[n];P2=TAB2[n]; if((count%10)==0)keyscan();}//==========================================================================voiddelay(uintt){ delay_time=0; while(delay_time<t);}//==========================================================================voidints(void)interrupt4{ staticucharj=0; constucharcodetab[]="TIME00:00:00"; ucharch,t[12]; if(RI==0){TI=0;return;}; RI=0; ch=SBUF; if((tab[j]=='0')||((tab[j]!='0')&&(ch==tab[j]))){t[j]=ch;j++;} else j=0; if(j==13) { hour=(t[5]-'0')*10+(t[6]-'0'); min=(t[8]-'0')*10+(t[9]-'0'); sec=(t[11]-'0')*10+(t[12]-'0'); j=0; } return;}//==========================================================================voidSentTime(){ ES=0; SBUF='0'+(hour/10); while(TI==0);TI=0; SBUF='0'+(hour%10); while(TI==0);TI=0; SBUF=':'; while(TI==0);TI=0; SBUF='0'+(min/10); while(TI==0);TI=0; SBUF='0'+(min%10); while(TI==0);TI=0; SBUF=':'; while(TI==0);TI=0; SBUF='0'+(sec/10); while(TI==0);TI=0; SBUF='0'+(sec%10); while(TI==0);TI=0; SBUF='\r'; while(TI==0);TI=0; SBUF='\n'; while(TI==0);TI=0; ES=1;}五、思考题1.改变串行通讯的波特率,如4800,2400等。修改程序,用PC机控制单片机是否每秒钟向PC机传送时间,命令为:传送PC机发送SEND1;不传送PC机发送SEND0。2.实验五思考题要求给电子钟加上打铃的功能,编写程序,实现通过PC机设置单片机多点(如4个打铃点)打铃时间。
实验七I2C串行flash存储器的读写一、实验目的1.学习I2C总线串行flash存储器24C01的读写操作。2.学习多个C51程序文件的编写和编译方法。二、实验内容实验板上有1片串行flash存储器24C01,编写程序,对该存储器进行读写操作。具体要求是,每次程序初始化时,读取24C01地址为0x00-0x02的3个单元的值,将0-2单元的值分别赋给时、分、秒,作为时钟的起始时间;每次时钟秒更新,再将当前时间的时、分、秒分别存储到24C01地址为0x00-0x02的3个单元。这样,单片机每次开机后,时间接着上次关机的时间继续计时。三、实验电路连线本实验有关的电路连接见右图。四、实验说明89C51单片机没有内部闪存,若有用户输入的数据需掉电保持,则要加外部闪存,24CXX系列就是常用的闪存芯片。串行闪存芯片的引脚少,占线路板面积小,与单片机的连线简单,因而被广泛使用。89C51单片机不支持I2C总线协议,必须按照I2C总线时序用软件模拟。1.实现对24C01进行读写的C语言程序:24c01.c#include<reg51.h>#include<intrins.h>//对24C01的读、写externvoidDelayMs(unsignedint);externvoidRead24c01(unsignedchar*RamAddress,unsignedcharRomAddress,unsignedcharbytes);externvoidWrite24c01(unsignedchar*RamAddress,unsignedcharRomAddress,unsignedcharbytes);/***************************************************************************/#define WriteDeviceAddress0xa0#define ReadDviceAddress0xa1/***************************************************************************/sbit SCL=P1^6;sbit SDA=P1^7;/***************************************************************************/voidDelayMs(unsignedintnumber){ unsignedchartemp; for(;number!=0;number--) { for(temp=112;temp!=0;temp--){ } }}/***************************************************************************/voidStart(){ SDA=1;SCL=1;SDA=0;SCL=0;}/***************************************************************************/voidStop(){ SCL=0;SDA=0;SCL=1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年云服务数据保护协议
- 2024年修订版:研发场地租赁协议
- 2024年创业团队股权分配与合作协议
- 2024年区间合作协议书:新版
- 2024年商业街区门面租赁协议
- 2024年分手协议范本样本
- 2024年合作框架:家居产品联合销售协议
- 2024年二人共创业:合伙协议书
- 2024年中介机构外聘顾问合作协议
- 2024年合作股权退出协议
- 儿童青少年视力普查规范
- 汽车修理工劳动合同三篇
- 2024年全国职业院校技能大赛高职组(药学技能赛项)考试题库(含答案)
- 2024至2030年中国羽毛球行业发展现状及投资趋势研究报告
- 第2课《原始农业与史前社会》教学设计-2024-2025学年七年级历史人教版(2024版)上册
- 新时代智慧物流行业人才培养与团队建设方案
- 2024年公司市场化选聘经理层考核管理办法
- 2024年【汽车驾驶员(技师)】证模拟考试及答案
- 临床医学:肿瘤标志物
- 瑜伽脊柱扭转课程设计
- 风电项目风机吊装专项施工方案
评论
0/150
提交评论