版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、学习目标1.了解定时/计数器的结构及其工作原理。2.掌握单片机的定时/计数器控制方式。3.掌握应用单片机进行频率测试控制的原理。4.掌握液晶的使用方法。二、学习任务任务一方波信号的产生;任务二单片机驱动液晶;任务三单片机简易频率计设计。三、任务分解任务一方波信号的产生【任务描述】本任务采用AT89C51单片机,利用定时/计数器T0通过P1.1引脚输出周期为500Hz的方波。【任务描述】【任务分析】从P1.1引脚输出周期为500Hz的方波信号,实际就是要产生周期为2ms的方波,只要每1ms将信号的幅值由0变到1或由1变到0即可,可采用取反指令来实现。为了提高CPU的效率,可采用定时中断的方式,每1ms产生一次中断,在中断服务程序中将输出信号取反即可。【相关知识】内设2个16位可编程定时/计数器T0,T1具有计数方式和定时方式4种工作模式一、定时器的结构及工作原理组成:两个16位的定时器T0和T1,以及他们的工作方式寄存器TMOD和控制寄存器TCON等组成。内部通过总线与CPU相连。定时器T0和T1各由两个8位特殊功能寄存器TH0、TL0、TH1、TL1构成。工作方式寄存器TMOD:用于设置定时器的工作模式和工作方式;控制寄存器TCON:用于启动和停止定时器的计数,并控制定时器的状态;单片机复位时,两个寄存器的所有位都被清0。8051定时器内部结构框图一、定时器的结构及工作原理两个可编程的定时器/计数器T1、T0。每个定时器内部结构实际上就是一个可编程的加法计数器,由编程来设置它工作在定时状态还是计数状态。两种工作模式: (1)计数器工作模式
就是对外部事件进行计数。计数脉冲来自相应的外部输入引脚T0(P3.4)或T1(P3.5)。当输入信号发生由1至0的负跳变(下降沿)时,计数器(TH0,TL0或TH1,TL1)的值增1。计数的最高频率一般为振荡频率的1/24。Why? (2)定时器工作模式
也是通过计数实现的。计数脉冲来自内部时钟脉冲,每个机器周期计数值增1,每个机器周期=12个振荡周期,因此计数频率为振荡频率的1/12。所以定时时间=计数值×机器周期。4种工作方式(方式0-方式3)。一、定时器的结构及工作原理当控制信号定时器工作在定时方式;加1计数器对脉冲f进行计数,每来一个脉冲,计数器加1,直到计时器计满溢出;因为,即一个计数脉冲的周期就是一个机器周期;计数器计数的是机器周期脉冲个数。从而实现定时。当控制信号定时器工作在计数方式;加1计数器对来自输入引脚T0(P3.4)和T1(P3.5)的外信号脉冲进行计数,每来一个脉冲,计数器加1,直到计时器计满溢出;TxTHxTFxTLxTRxINTx定时计数
控制信号K“1”启动,计数器运行;“0”停止,计数器停止;定时器/计数器原理框图加1计数器控制信号K可以控制计数器的“启动”和“停止”,
TCON(88H)振荡周期:是振荡脉冲的周期,也成为“拍”,用P表示。就是晶体振荡器的周期,或外部振荡脉冲的周期。是MCS-51单片机的最小时序单位。P1P2S1振荡周期时钟周期机器周期机器周期指令周期XTAL2(OSC)S2S3S4S5S6S1S2S4S5S3S6P1P1P1P1P1P1P1P1P1P1P1P2P2P2P2P2P2P2P2P2P2P2时钟周期:是振荡源信号经二分频后形成的时钟脉冲信号,用S表示。每个时钟周期分成P1、P2两个节拍,又被称为一个状态。是MCS-51单片机的最基本的时序单位。机器周期:通常将完成一个基本操作所需的时间称为机器周期,由6个状态(12拍)组成,所以一个机器周期可以依次表示为S1P1、S2P2……S6P1、S6P2。通常算术逻辑操作发生在节拍P1期间,而内部寄存器到寄存器的传送发生在节拍P2期间。指令周期:是指CPU执行一条指令所需要的时间。是MCS-51单片机的最大的时序单位,由若干个振荡周期组成。一个指令周期通常含有1~4个机器周期,MCS-51典型的指令周期为一个机器周期。
振荡周期、时钟周期、机器周期和指令周期在每个机器周期的S5P2期间采样检测引脚输入电平。若前一个机器周期采样值为“1”,后一个机器周期采样值为“0”,则计数器加1。新的计数值在检测到输入引脚电平发生“1”到“0”的负跳变(下降沿)后,于下一个机器周期的S3P1期间装入计数器中。由于CPU需要两个机器周期来识别一个“1”到“0”的跳变信号,所以最高的计数频率为振荡周期的1/24。P1P2S1振荡周期状态周期机器周期机器周期指令周期XTAL2(OSC)S2S3S4S5S6S1S2S4S5S3S6P1P1P1P1P1P1P1P1P1P1P1P2P2P2P2P2P2P2P2P2P2P2定时/计数器对输入信号的要求外部计数脉冲的最高频率为系统振荡器频率的1/24,例如选用12MHz频率的晶体,则可输入500KHz的外部脉冲。输入信号的高、低电平至少要分别保持一个机器周期。 如图所示,图中Tcy为机器周期。可编程定时器的工作方式、启动、停止、溢出标志、计数器等都是可编程的——通过设置寄存器TMOD,TCON,TH0,TL0,TH1和TL1实现。当设置了定时器的工作方式并启动定时器工作后,定时器就按被设定好的工作方式独立工作,不再占用CPU,只有在计数器计满溢出时才向CPU申请中断,占用CPU。由此可见,定时器是单片机中工作效率高且应用灵活的部件。二、定时器的TMOD和TCON寄存器8051单片机定时器主要有几个特殊功能寄存器组成: TMOD,TCON,TH0,TL0,TH1,TL1。TMOD:设置定时器的工作方式;TCON:控制定时器的启动和停止;TH0和TL0
:存放定时器T0的初值或计数结果;TH0存放高8位,TL0存放低8位;TH1和TL1
:存放定时器T1的初值或计数结果;TH1存放高8位,TL1存放低8位;
8位分为两组,高4位控制T1,低4位控制T0。(1)GATE—门控位
0:
以TRX(X=0,1)来启动定时器/计数器运行。
1:
用外中断引脚(INT0*或INT1*)上的高电平和TRX来启 动定时器/计数器运行。(2)M1、M0—工作方式选择位
M1M0
工作方式
00
方式0,13位定时器/计数器。
01
方式1,16位定时器/计数器。
10
方式2,8位常数自动重新装载
11
方式3,仅适用于T0,
T0分成两个8位计数器,T1停止计数。(3)C/T*—计数器模式和定时器模式选择位
0:
定时器模式。
1:
计数器模式。(4)TMOD无位地址,不能位寻址。(5)复位时,TMOD所有位均为“0”。低4位与外部中断有关,后面介绍。高4位的功能如下:
(1)TF1、TF0
—计数溢出标志位 定时器T0或T1计数溢出时,由硬件自动将此位置“1”;
TFx可以由程序查询,也是定时中断的请求源;
(2)TR1、TR0
—计数运行控制位
TRx=1:
启动定时器/计数器工作
TRx=0:
停止定时器/计数器工作MCS-51单片机的定时器/计数器是可编程的,但在进行定时或计数之前要对程序进行初始化,具体步骤如下:(1)对TMOD赋值,以确定定时器的工作模式;(2)置定时/计数器初值,直接将初值写入寄存器的TH0、TL0或TH1、TL1;(3)根据需要,对IE置初值,开放定时器中断;(4)对TCON寄存器中的TR0或TR1置位,启动定时/计数器,置位以后,计数器即按规定的工作模式和初值进行计数或开始定时。初值计算:
设计数器的最大值为M,则置入的初值X为:计数方式:X=M-计数值定时方式:由(M-X)T=定时值,得X=M-定时值/TT为计数周期,是单片机的机器周期。(模式0:M为213,模式1:M为216,模式2和3:M为28)例如:机器周期为1μs时,若工作在模式0,则最大定时值为:213×1μs=8.192ms
若工作在模式1,则最大定时值为:216×1μs=65.536ms三、定时器的工作方式MCS-51的定时器T0有4种工作方式: 即:方式0,方式1,方式2,方式3。MCS-51的定时器T1有3种工作方式: 即:方式0,方式1,方式2。1.方式0
M1、M0设置为00,为13位计数器,以T1为例,其框图如下:计数脉冲输入加1计数器TH1D12D11D10D9D8D7D6D5TL1×
×
×
D4D3D2D1D0在这种方式下,16位寄存器TH1和TL1只用13位,由TH1的8位和TL1的低5位组成。TL1的高3位不定。当TL1的低5位计数溢出时,向TH1进位。而TH1计数溢出时,则向中断标志位TF1进位(即硬件将TF1置1),并请求中断。可通过查询TF1是否置“1”或考察中断是否发生来判定定时器T1的操作完成与否。当C/T=0时,为定时工作模式,开关接到振荡器的12分频器输出上,计数器对机器周期脉冲计数。其定时时间为:
(213-初值)×振荡周期×12
例如:若晶振频率为12MHz,则最长的定时时间为(213-0)×(1/12)×12us=8.191ms当C/T=1时,为计数工作模式,开关与外部引脚T1(P3.5)接通,计数器对来自外部引脚的输入脉冲计数。当外部信号发生负跳变时计数器加1。
GATE控制定时器Tx(T1或T0)的条件:(1)当GATE=0时,“或门”输出恒为1,“与门”的输出信号K由TRx决定(即此时K=TRx),定时器不受INTx输入电平的影响,由TRx直接控制定时器的启动和停止。
TRx=1;计数启动;
TRx=0;计数停止;(2)当GATE=1时,“与门”的输出信号K由INTx输入电平和TRx位的状态一起决定(即此时K=TRx·INTx), 当且仅当TRx=1且INTx=1(高电平)时,计数启动;
否则,计数停止。
返回2.方式1
M1、M0=01,为16位的计数器,除位数外,其他与方式0相同。其定时时间为:
(216-初值)×振荡周期×12
例如:若晶振频率为12MHz,则最长的定时时间为
(216-0)×(1/12)×12us=65.536ms2.方式2
M1、M0=10,为自动恢复初值的8位计数器,等效框图如下:TLx作为8位计数器,THx作为重置初值的缓冲器。
THx作为常数缓冲器,当TLx计数溢出时,在置“1”溢出标志TFx的同时,还自动的将THx中的初值送至TLx,使TLx从初值开始重新计数。定时器/计数器的方式2工作过程如图(x=0,1)。优点:
方式0和方式1用于循环重复定时或计数时,在每次计数器挤满溢出后,计数器复0。若要进行新一轮的计数,就得重新装入计数初值。这样一来不仅造成编程麻烦,而且影响定时精度。而方式2具有初值自动装入的功能,避免了这个缺点,可实现精确的定时。缺点: 只有8位计数器,定时时间短、计数范围小。其定时时间为:
(28-初值)×振荡周期×12若晶振频率为12MHz,则最长的定时时间为(28-0)×(1/12)×12us=0.256ms方式2工作过程图
(x=0,1)。3.方式3
只适用于定时器/计数器T0。T1不能工作在方式3。 如果将T1置为方式3,则相当于TR1=0,停止计数(此时T1可用来作串行口波特率产生器)。1.工作方式3下的T0
T0在方式3时被拆成两个独立的8位计数器:TH0和TL0。
8位计数器TL0使用T0的状态控制位C/T*、GATE、TR0、INT0,它既可以工作在定时方式,也可以工作在计数方式。8位定时器TH0被固定为一个8位定时器(不能作外部计数模式),并使用定时器T1的状态控制位TR1,同时占用定时器T1的中断请求源TF1。此时,定时器TH0的启动或停止只受TR1控制。
TR1=1时,启动TH0的计数;TR1=0时,停止TH0的计数各引脚与T0的逻辑关系如图所示:2.T0工作在方式3下T1的各种工作方式注意:当T0处于方式3时,T1仍可设置为方式0、方式1和方式2。当时由于TR1、TF1和T1的中断源都已被定时器T0(中的TH0)占用,所以定时器T1仅有控制位C/T来决定其工作在定时方式或计数方式。当计数器计满溢出时,不能置位“TF1”,而只能将输出送往串口。所以,此时定时器T1一般用作串口的波特率发生器,或不需要中断的场合。
(1)T1工作在方式0(2)T1工作在方式1(3)T1工作在方式2【例4-1】若单片机的频率为12MHz,请计算2ms所需要的定时器初值。解:在频率为12MHz时,每个计数脉冲的时间间隔为0.001ms,所以其计数脉冲个数为2/0.001=1000个。在方式0,则计数初值为:213-2000=6192=1100000110000B即:(TH0)=11000001B=0xC1(取初值X的高8位),(TL0)=00010000B=0x10(取初值X的低5位,TL0寄存器在方式0下只用到低5位,高3位未使用,TH0使用了8位,一共的计数位是8+5=13位)所以定时器的初值为(TH0)=0xC1,(TL0)=00010000B=0x10H。【任务实施】P1.0引脚输出方波电路对应的程序代码如下:#include<reg51.h>//定义头文件sbitP1_1=P1^1;voidtimer0(void)interrupt1//定时器0中断服务程序
{TH0=0xE0;TL0=0x18; //装入时间常数P1_1=!P1_1; //P1.1取反
}voidmain(void){TMOD=0x00; //定时器0方式0TH0=0xE0;TL0=0x18; //装入时间常数TR0=1; //启动定时器TF0=0;EA=1; //开全局中断
ET0=1; //开定时器0中断
while(1); //主程序死循环,空等待
}【进阶提高】前面我们已经熟悉了定时器的一般应用,如果定时器要实现比较长时间的定时,还能用我们之前介绍的方法予以解决吗?使用定时器T0的中断来控制P2.0引脚LED的闪烁,要求闪烁周期2s,即亮1s,灭1s。定时器T0工作于方式1时,其最大可计脉冲数次数为65536,对于12MHz的时钟频率,一个脉冲的宽度为1.00μs,则最大计时长度只有1.00×65536=65536μs,即大约65ms。所以要计时1s或更长的时间,还需采用一种被称作“软件计数”的方法:加入我们设定定时时间为50ms,设置一个变量Countor来储存定时器T0的中断次数,即每产生1次50ms定时中断,使变量Countor自加1,那么当Countor自加20次时,所计时间就是1s。#include<reg51.h>#defineuintunsignedint#defineucharunsignedcharsbitLED=P1^0;uintCount=0;voidmain(){TMOD=0x01;//设置定时器0为工作方式1TH0=0x3C;TL0=0xB0;EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0while(1){if(TF0==1){TF0=0;TH0=0x3c;//1次定时100ms,计数10次,就为1秒。
TL0=0xb0;}if(Count==20){Count=0;LED=~LED;}}}voidtime0()interrupt1{Count++;}任务二单片机驱动液晶【任务描述】单片机驱动液晶1602,能够将英文和数字显示出来。本任务要求设计LCD1602与单片机的接口电路,编写程序使LCD1602的第一行显示“OK”,第二行显示“AT89C51”。【任务分析】最直接把要显示的内容写在数组里,程序开始LCD初始化,写字符显示位置指令,满足其各种时序要求,然后根据显示的字符所占的位数,写个for循环语句,放入数据函数,这样就可以在指定位置开始显示要显示的内容。【相关知识】一、液晶1602驱动方法VL-液晶屏对比度的调节L命令是对液晶屏显示的设置H数据是要显示的东西51单片机的1602液晶1602液晶的存储器结构1.DDRAM:显示数据RAM,用来寄存待显示的字符代码。共80个字节,其地址和屏幕的对应关系如下图:要在屏幕上显示字符,只需向相关DDRAM中写入该字符的ASCII码即可。1602液晶的存储器结构2.CGROM:字符发生存储器,已经存储了160个不同的点阵字符图形,按ASCII码排列,如下图所示:字符代码:0x00~0x0F为用户自定义的字符图形RAM。0x20~0x7F为标准的ASCII码。0xA0~0xFF为日文字符和希腊文字符。1602液晶的存储器结构3.CGRAM:用户自定义字符发生存储器,共64字节,地址为0x00~0x3f,可存储8个5*8点阵图形,其中地址0x00~0x07存储字符代码为0x00的字符图形,0x08~0x0f存储字符代码为0x01的字符图形,以此类推。voidLCD_write_cmd(unsignedcharcmd){ LCD_check_busy(); delay(1); LCD_RS=0; LCD_RW=0; LCD_DATA=cmd; delay(50); LCD_EN=1; delay(50); LCD_EN=0; delay(50);}液晶显示
750x38E使能高电平命令选择DB0-DB7使能E开使能E关写命令子函数写数据子函数E使能高电平数据选择DB0-DB7使能E开使能E关段位都关上,关液晶0x380x0e=0000.11100x06=0000.0110初始化子函数初始化子函数ILIKEMCU!一共11位0X18左移一下
1602液晶总结:(1)写命令子函数(2)写数据子函数(3)初始化子函数(4)Main第一行显示,第二行显示,移动。【任务实施】#include<reg51.h>#include<intrins.h>#defineuintunsignedint//预定义一下#defineucharunsignedcharsbitrs=P3^5;//1602的数据/指令选择控制线sbitrw=P3^6;//1602的读写控制线sbiten=P3^7;//1602的使能控制线#defineDataPortP2/*P2口接1602的D0~D7,注意不要接错了顺序*/ucharcodetable[]="OK?";//要显示的内容1放入数组tableucharcodetable1[]="AT89C51";//要显示的内容2放入数组table1voiddelay(uintn)//延时函数{uintx,y;for(x=n;x>0;x--)for(y=110;y>0;y--);}voidLCD_Check_Busy(void){while(1){DataPort=0xff;rs=0;rw=1;en=0;_nop_();en=1;if(DataPort&0x80)break;}en=0;delay(2);} voidlcd_wcom(ucharcom)//1602写命令函数(单片机给1602写命令){LCD_Check_Busy();//1602接收到命令后,不用存储,直接由HD44780执行并产生相应动作
rs=0;//选择指令寄存器
rw=0;//选择写
P2=com;//把命令字送入P2en=1;//使能线电平变化,命令送入1602的8位数据口
en=0;}voidlcd_wdat(uchardat)//1602写数据函数{ LCD_Check_Busy();rs=1;//选择数据寄存器
rw=0;//选择写
P2=dat;//把要显示的数据送入P2en=1;//使能线电平变化,数据送入1602的8位数据口
en=0;}voidlcd_init()//1602初始化函数{lcd_wcom(0x38);//8位数据,双列,5*7字形
lcd_wcom(0x0c);//开启显示屏,关光标,光标不闪烁
lcd_wcom(0x06);//显示地址递增,即写一个数据后,显示位置右移一位
lcd_wcom(0x01);//清屏}voidmain()//主函数{ucharn,m=0;lcd_init();//液晶初始化
lcd_wcom(0x80);//显示地址设为80H(即00H,)上排第一位(也是执行一条命令)
for(m=0;m<4;m++)//将table[]中的数据依次写入1602显示
{lcd_wdat(table[m]);delay(200);}lcd_wcom(0x80+0x40);//重新设定显示地址为0xc4,即下排第一位
for(n=0;n<8;n++)//将table1[]中的数据依次写入1602显示
{lcd_wdat(table1[n]);delay(200);}while(1);//动态停机}【进阶提高】上面驱动液晶1602实际上没有判断液晶忙与否,直接用了延时函数延时达到单片机与液晶的同步,下面讨论下如何用判断忙的方法驱动液晶1602。读忙的时序为:RS=L,RW=H,E=H
,据此写判忙函数:voidLCD_Check_Busy(void){while(1){DataPort=0xff;rs=0;rw=1;en=0;_nop_();en=1;if(DataPort&0x80)break;}en=0;delay(2);}任务三单片机简易频率计设计【任务描述】使用如图4-12所示电路,用AT89C51设计一个数显频率计数器对0~300KHz的方波信号进行测量,信号从P3.5引脚输入,P1、P2口做输出口,接液晶1602,编写程序,测出从P3.5引脚输入的方波信号的频率并显示出来。【任务分析】在计数器工作方式下,加至外部引脚的待测信号发生从1到0的跳变时计数器加1。外部输入在每个机器周期被采样一次,这样检测一次从1到0的跳变至少需要2个机器周期(24个振荡周期),所以最大计数速率为时钟频率的1/24(使用12MHz时钟时,最大计数速率为500kHz),也就是说使用12MHz时钟的AT89C51单片机设计的频率计数器系统,所测的信号的频率不能大于500kHz,若大于则必须通过分频器分频才能测试,而本次任务的要求是对0~300KHz的信号进行测量,所以可以直接进行。利用AT89C51单片机的T0、T1的定时计数器功能,来完成对输入的信号进行频率计数。设置定时器0工作在定时方式1,定时1秒,并产生方波信号从P1.1引脚输出。设置定时器1工作在计数方式1,对输入脉冲进行计数,溢出产生中断。将定时器1中断定义为优先。由于16位二进制加法计数器的最大计数值为65535,1秒之内可能会产生多次溢出,所以需要在中断处理程序里对中断次数进行计数。1秒到后,将中断次数和计数器里的计数值取出进行综合数据处理,处理后的数据送显示。【相关知识】频率计计数原理:T1工作在计数方式时最大的计数值为216,若假设1S内溢出C1次,最后未溢出的计数值为C2,则F=C1*216+C2=C1*65536+(TH1*256+TL1)。【任务实施】本工程程序一共用了2个文件,一个是LCD1602.c和main.c。把这两个文件都要添加到工程中,然后再编译生成hex文件。下面分别给出LCD1602.c和main.c的代码:LCD1602.c源文件如下://-----------------------------------------------------------------//液晶控制与显示程序//-----------------------------------------------------------------#include<reg51.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintsbitRS=P2^0; //寄存器选择线sbitRW=P2^1; //读/写控制线sbitEN=P2^2; //使能控制线//sbitBF=P0^7; //LCD忙标记//-----------------------------------------------------------------//延时//-----------------------------------------------------------------voiddelay_ms(uintms){ uchari;while(ms--)for(i=0;i<120;i++);}//-----------------------------------------------------------------//忙检查//-----------------------------------------------------------------bitLCD_Busy_Wait(){bitresult;RS=0;RW=1;EN=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80);EN=0;returnresult;}//-----------------------------------------------------------------//写LCD命令//-----------------------------------------------------------------voidWrite_LCD_Command(ucharcmd){while(LCD_Busy_Wait());//判断LCD是否忙碌RS=0;RW=0;EN=0;_nop_();_nop_();P0=cmd;_nop_();_nop_();_nop_();_nop_();EN=1;_nop_();_nop_();_nop_();_nop_();EN=0;}//-----------------------------------------------------------------//发送数据//-----------------------------------------------------------------voidWrite_LCD_Data(uchardat){while(LCD_Busy_Wait());//判断LCD是否忙碌RS=1;RW=0;EN=0;P0=dat;_nop_();_nop_();_nop_();_nop_();EN=1;_nop_();_nop_();_nop_();_nop_();EN=0;}//-----------------------------------------------------------------//LCD初始化//-----------------------------------------------------------------voidInitialize_LCD(){ Write_LCD_Command(0x38);delay_ms(10);Write_LCD_Command(0x0c);delay_ms(10);Write_LCD_Command(0x06);delay_ms(10);Write_LCD_Command(0x01);delay_ms(10);}voidlcd_pos(unsignedcharpos)//写入显示控制位置命令{Write_LCD_Command(pos|0x80);}//-----------------------------------------------------------------main.c源文件代码如下:#include<reg51.h>//包含51单片机寄存器定义的头文件#defineucharunsignedchar#defineuintunsignedintexterndelay_ms(uintx);externvoidInitialize_LCD();externvoidWrite_LCD_Command(ucharcmd);externvoidWrite_LCD_Data(uchardat);externvoidlcd_pos(ucharpos);externvoidLCD_ShowString(uchar,uchar,uchar*);ucharOutputData[16]={0};//用于存放频率值的16进数组uchardisplay_data[8]={0,0,0,0,0,0,0,0};//定义数组存放显示数据的各位ucharc1,b1;sbitP1_1=P1^1;//延时程序
voidDelayMS(uintValMS){ uintuiVal,ujVal; for(uiVal=0;uiVal<ValMS;uiVal++) for(ujVal=0;ujVal<120;ujVal++);}/**************************************************函数功能:将数组转成字符,适合1602显示***************************************************/voidirwork(){uchari;for(i=0;i<8;i++){ if((display_data[i]%16+'0')==0x3a)//频率值为0,就对OutputData[i]赋为0,显示0OutputData[i]='0';
else{ OutputData[i]=display_data[i]%16+'0';//如果是10进数就转化为16进进数显示}} OutputData[8]='H';
OutputData[9]='z'; OutputData[10]='\0';}voidconvert()//转换程序{uchari,f2;longf,f1,k;f=c1*65536+TH1*256+TL1;f1=f-f%10; //此变量是为了让八位LED的高位为0时不显示而设置for(i=7;i>0;i--) //此循环将计数值转换为显示数组,从高位到低位依次存放在//display_data[0]至display_data[7]{display_data[i]=f%10;f=f/10;} display_data[0]=f;k=1e7; //从这开始到本子程序结束的语句完成让八位LED的高位为0时不显示for(i=0;i<7;i++){f2=f1/k;if(f2==0){display_data[i]=10;k=k/10;}}}voidtimer1(void)interrupt3//定时器1中断服务程序
{c1++; }voidtimer0(void)interrupt1//定时器0中断服务程序
{TH0=0xb1; //装入时间常数TL0=0xe0; P1_1=!P1_1; //P1.1取反,从P1.1引脚输出25Hz的方波信号,通过导线连接//到P3.5引脚输入,以方便调试程序。若使用其它信号源,则去掉即可。if(b1==49){convert();c1=0; //将计数值清零b1=0;TH1=0;TL1=0;}elseb1++;}/***************************************************函数功能:主函数***************************************************/main(void){uinti;P1_1=0;c1=0;b1=0;TH1=0;TL1=0;TMOD=0x51;TH0=0Xb1;TL0=0Xe0;IE=0x8a;TCON=0x50;Initialize_LCD();while(1){irwork();DelayMS(10);
lcd_pos(0x01);//设置显示位置在第一行
i=0;while(OutputData[i]!='\0')//显示到字符结束{Write_LCD_Data(OutputData[i]);//显示字符i++;}}}【进阶提高】综合运用单片机中断、定时器知识,设计一4位数码管抽奖器,如图4-13所示,按动抽奖按钮时,抽奖器自动产生4位随机数,当再一次按抽奖按钮时,表示抽奖停止,产生中奖号码抽奖器电路对应的程序如下:
#include"reg51.h" /*8051单片机资源说明*/#include<stdlib.h> /*包含rand()函数*/#defineucharunsignedchar#defineuintunsignedintucharcodeBitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};ucharcodeDispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x8
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 玩具设计师童心未泯创意无限
- 文化创意技术工作总结
- 整形外科护士全年工作总结
- 证券行业卫生规范
- 《爱劳动讲卫生》课件
- 2021年高考语文试卷(上海)(春考)(解析卷)
- 2024年濮阳职业技术学院单招职业技能测试题库标准卷
- 2024年美术的教案
- 农村房屋问题协议书(2篇)
- 出境游全程无忧旅游合同
- 微型顶管施工方案
- 湘教文艺版小学五年级音乐上册期末测试题
- 老化箱点检表A4版本
- 略说鲁迅全集的五种版本
- 2022年110接警员业务测试题库及答案
- 中联16T吊车参数
- DB44∕T 115-2000 中央空调循环水及循环冷却水水质标准
- 嵌入式软件架构设计
- 《石油天然气地质与勘探》第3章储集层和盖层
- 航道整治课程设计--
- 超星尔雅学习通《科学计算与MATLAB语言》章节测试含答案
评论
0/150
提交评论