精华内容
下载资源
问答
  • 单片机中断
    千次阅读
    2020-03-01 16:41:58

    一.中断的基本概念

    1.中断的概念:

    在单片机中,中断是指:对于CPU来说,当它在正常处理事件A时,突然发生了另一件事件B(中断发生)需要CPU去处理,这时CPU就会暂停处理事件A(中断响应),转而去处理事件B(中断服务)。当事件B处理完以后,再回到事件A原来中断的地方继续执行事件A(中断返回)。这一整个过程称为中断

    当中断过程B中,发生了另一个中断级别更高的中断事件C,则CPU又会中断当前的B转而去处理C,完毕后再回到B的断点继续处理。这称为中断的嵌套。中断的嵌套涉及到中断的优先级问题。

    2.中断源:

    请示CPU中断的源头称为中断源。中断源表示了单片机可以设置、发生中断的地方。51单片机内有3类基本的中断源:
    外部中断(INT0/1),定时中断(T0/1),串口中断(RXD,TXD)

    每个中断源都在P3口(附加功能)有相应的信号输入端:
    外部中断0(ITN0):P3.2
    外部中断1(INT1):P3.3
    定时中断0(T0):P3.4
    定时中断1(T1):P3.5
    串口中断0(RXD):P3.0
    串口中断1(TXD):P3.1

    二.中断相关的寄存器

    用来控制中断的开启与关闭、中断的请求、中断的条件与类型等等。若要使用中断,则要先配置相应的中断寄存器。这些寄存器及其各位都已经在reg52头文件中定义好了。

    1.中断允许寄存器(IE)

    在这里插入图片描述
    EX0(IE^0),外部中断 0 允许位;
    ET0(IE^1),定时/计数器 T0 中断允许位
    EX1(IE^2),外部中断1允许位;
    ET1(IE^3),定时/计数器 T1 中断允许位;
    ES(IE^4),串行口中断允许位;
    EA (IE^7), CPU 中断允许(总允许)位

    如果要用中断,首先要打开总中断位EA;需要使用哪一个中断,就让这个中断允许位=1。

    2.中断请求标志寄存器(TCON)

    低4位:外部中断请求标志位、外部中断触发条件
    高4位:定时中断请求标志位、定时中断是否启动
    在这里插入图片描述
    IT0(TCON^0),外部中断 0 触发方式控制位。用来控制外部中断的触发条件。
    当 IT0=0 时,为电平触发方式(低电平有效)。
    当 IT0=1 时,为边沿触发方式(下降沿有效)。

    IE0(TCON^1),外部中断 0 中断请求标志位。
    IT1(TCON^2),外部中断 1 触发方式控制位。
    IE1(TCON^3),外部中断 1 中断请求标志位。
    TR0(TCON^4),定时/计数器T0开启位。当TR0=1时,定时器开始工作。
    TF0(TCON^5),定时/计数器 T0 溢出中断请求标志位。
    TR1(TCON^6),定时/计数器T1开启位。当TR0=1时,定时器开始工作。
    TF1(TCON^7),定时/计数器 T1 溢出中断请求标志位。

    3.中断优先级寄存器(IP)

    在这里插入图片描述
    若将某一位设为1,则认为这一位的中断处于高优先级。
    优先级的考虑顺序:先考虑高低优先级别,再考虑序号排列。由此得到一整个优先级顺序。
    默认顺序:就是中断号的顺序

    三.中断的实际使用

    A.中断的3个条件:

    1.中断源有中断请求
    2.CPU允许中断(即EA)为1
    3.相应中断源的中断允许位为1

    以上3个条件缺一不可。当中断的发生不如意时,可以从这3点去进行考虑。

    B.如何使用中断:

    引用中断时,我们要考虑4个问题:
    1.为什么要用中断?
    2.你想要使用哪一个中断?它的中断号是什么?
    3.中断的触发条件是什么?
    4.中断以后做什么?

    C.中断服务程序的基本结构

    据上,我们可以编写程序来控制中断。这个程序最起码要包括三个模块

    1.中断配置函数
    设置需要的中断寄存器,来开启中断、选择它的类型和触发方式。
    由于所有的中断寄存器已经封装好,我们只需要给封装好的代号(如IE、EX0等)赋值。
    void Int0Init(){
    IT0=1;
    EX0=1;
    EA=1;
    }

    2.main函数
    主控,CPU执行的主程序。里面应该包含中断配置函数,以设置中断。
    当中断发生时,程序便从主程序马上跳出到中断服务函数。
    void main(){
    Int0Init();
    while(1); //主程序停在此处,等待中断的发生
    }

    3.中断服务函数
    写中断产生后要做什么。
    例:
    void int0() interrupt 0 using 1{
    //code
    }
    Int0是函数名,可以任取。
    Interrupt是一个关键字,后面的0是中断号(代表所使用的中断

    通常来说,在函数名中用int代表外部中断,Timer代表定时器中断

    附:中断号如下
    在这里插入图片描述

    四.中断的优点:

    随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与慢速 I/O
    设备的数据传送问题,而且还具有如下优点:
    ①分时操作。CPU 可以分时为多个 I/O 设备服务,提高了计算机的利用率;
    ②实时响应。CPU 能够及时处理应用系统的随机事件,系统的实时性大大增强;
    ③可靠性高。CPU 具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。

    更多相关内容
  • 单片机中断技术的应用设计——中断方式控制单片机输入输出
  • 说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。
  • 本文主要讲了51单片机的几个中断源,希望对你的学习有所帮助。
  • 说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。
  • 本文主要讲了PIC单片机中断程序实例,希望对你的学习有所帮助。
  • MCS—51系列单片机内部只有两个外部中断源输入端,当外部中断源多于两个时,就必须进行扩展,下面介绍几种简单的扩展方法。
  • 单片机中断原理

    2017-07-10 15:06:23
    本文档主要解释了51单片机内部中断的原理
  • 单片机中断嵌套实验 汇编语言设计 姓名:陈志强 班级通信1401 学校安徽工程大学机电学院 时间2016.4.6 实验内容 使用一个外部中断和定时器中断通过P1口连接的8个发光二极管来显示中断的作用 外部中断未发生时即引脚的...
  • 本文主要介绍了单片机中断服务程序中的变量应该如何使用。
  •  51单片机中断优先级的设置方法解析  PX0(IP.0),外部中断0优先级设定位;  PT0(IP.1),定时/计数器T0优先级设定位;  PX1(IP.2),外部中断0优先级设定位;  PT1(IP.3),定时/计数器T1优先级设定位...
  • 中断源 (1)外部中断0请求,由P3.2脚输入。通过IT0脚(TCON.0)来决定是低电平有效还是下跳变有效。一旦输入信号有效,就向CPU申请中断,并建立IE0标志。 (2)外部中断1请求,由P3.3脚输入。通过IT1脚TCON.2)来...
  • 本文为大家介绍了51单片机中断函数注意事项。
  • 中断装置和中断处理程序统称为中断系统。 中断系统是计算机的重要组成部分。实时控制、故障自动处理、计算机与外围设备间的数据传送往往采用中断系统。中断系统的应用大大提高了...这篇文章我们主要讲解单片机中断
  • 51单片机中断系统应用
  • C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。
  • 文章介绍了PIC单片机中断程序的设计技巧。
  • 基于Proteus的单片机中断电路的设计与仿真.pdf
  • 单片机 中断系统

    2018-09-03 17:56:36
    单片机课件,结合书本知识所融汇成的课件,是上课所讲内容全面
  • 浅谈MCS-51单片机中断系统逻辑控制图.pdf
  • 点击数码管加一,再次点击,数码管清零。还有0-999999计数效果,
  • 单片机中断系统讲解ppt,单片机中断系统讲解
  • 1.理解AT89C51单片机中断优先级和优先权。 2.用PROTEUS设计、仿真基于AT89C51单片机的中断优先级实验。 3.掌握中断编程。 优先级实验
  • 单片机 中断

    万次阅读 多人点赞 2018-05-30 23:03:30
    单片机 中断一、简述 中断,即CPU在正常执行程序的过程中,遇到外部/内部的紧急事件需要处理,暂时中断(中止)当前程序的执行,而转去为事件服务,待服务完毕,再返回到暂停处(断点)继续执行原来的程序。二、中断...

    单片机 中断

    一、简述

        中断,即CPU在正常执行程序的过程中,遇到外部/内部的紧急事件需要处理,暂时中断(中止)当前程序的执行,而转去为事件服务,待服务完毕,再返回到暂停处(断点)继续执行原来的程序。


    二、中断请求标志控制寄存器TCON


    三、中断请求标志控制寄存器SCON


    四、中断允许寄存器IE


    五、中断函数

    中断函数定义的格式为:
    函数类型 函数名 interrupt   n  using  m
    其中:
        interrupt 后面的n 是中断号。

        关键字using 后的m 是所选择的寄存器组,取值范围是0~3。

    using m这部分通常可以省略,由编译器自动选择一个寄存组。

    举例:

    void int0rupt() interrupt 0    
    {		
    	beep=0;//开蜂鸣器	
    	while(P3_2!=1);//当P3^2口一直是低电平时,就一直告警
    	beep=1;//关蜂鸣器
    }
    
    void 是函数类型表示空类型
    int0rupt是函数名

    interrupt 0中的0表示该函数是为外部中断0服务的处理函数(当外部申请中断0服务时调用此函数)

    六、完整例子

    文件打包:链接: https://pan.baidu.com/s/1Zuo1-bGvJV5YJU1Kq1Xh9w 密码: 195s

    1、效果:当按键按下时,蜂鸣器就会响,不松开就一直响,松开关闭。

        (主程序死循环,通过CPU中断可以暂时中断,先执行其他任务,然后再回来继续执行被中断的任务。例子中开启外部中断0,中断方式为下降沿触发,比如控制端口原来是高电平的,按下按钮使控制端口变为低电平,高电平到低电平有个下降过程,下降沿触发中断0,调用中断服务处理函数,蜂鸣器响。中断服务处理函数有个循环检测直到按钮释放才关闭蜂鸣器,退出中断服务处理函数,控制端口恢复为高电平。)

    2、Keil文件结构


    3、仿真电路


    4、alarm.c文件

    #include<reg51.h>
    #define uint unsigned int
    #define uchar unsigned char
    sbit P3_2=P3^2;//将P3^2定义为中断0控制口
    sbit beep=P3^3;//将P3^3定义为蜂鸣器控制口
    void main()
    {
    	EA=1;//开许总中断
      	EX0=1;//开外部中断0
     	IT0=0;//中断触发方式为低电平触发
    	while(1)  //主程序一直在死循环,外部中断可以暂时执行中断处理函数
    	{}
    }
    /**********************************************************/
    //函数名:int0rupt() interrupt 0
    //功能:外部中断0中断响应程序 
    //调用函数:
    //输入参数:
    //输出参数:
    //说明:当P3^2口为低电平时进入响应程序 
    /**********************************************************/
    void int0rupt() interrupt 0//当P3^2键口为低电平时
    {
    	beep=0;//开蜂鸣器
    	while(P3_2!=1);//当P3^2口置高检测,就是按钮不释放蜂鸣器就一直响
    	beep=1;//关蜂鸣器
    }
    展开全文
  • 中断是为单片机实时处理外部和内部随机机事情而设置的一项基本功能,中断功能的存在,极大的提高了单片机处理外部和内部事件的能力,目前几乎所有单片机都会配置的这一项基本功能,而中断功能的强弱也成为衡量一种...
  • 单片机中断系统概述

    2020-08-28 19:55:13
    计算机在执行程序的过程中,当出现CPU以外的某种情况时,由服务对象向CPU发出中断请求信号,要求CPU暂时中断当前程序的执行而转去执行相应的处理程序,待处理程序执行完毕后,再继续执行原来被中断的程序。...
  • 51单片机中断

    千次阅读 多人点赞 2021-01-27 23:59:10
    51单片机中断51单片机中断原理中断的概念:中断作用中断源及相关寄存器中断源及优先级定时器/计数器控制寄存器 TCON中断允许寄存器 IE中断优先寄存器 IP工作方式寄存器TMOD定时器初值寄存器THx 和 TLx计数器初值的...

    51单片机中断原理

    中断的概念:

    CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生),那么CPU就会暂停当前的工作(A事件),去执行B事件(中断响应和中断服务),然后B事件做完之后,再回到原来的事件(A事件)中继续工作。(中断的返回)。
    在这里插入图片描述

    中断作用

    随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与I/O设备的数据传送问题,而且还有具有如下的优点:

    1. 分时操作:CPU可以分时为多个I/O设备服务,提高了计算机的利用率。
    2. 实时操作:CPU能够及时处理应用系统的随机事件,系统的实时性大大增强。
    3. 可靠性高:CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性更高。

    中断源及相关寄存器

    中断源及优先级
    中断源符号名称中断标志中断引起原因中断号优先级
    /INT0外部中断0IE0低电平或下降沿信号0最高
    T0定时器中断0TF0定时/计数器0 计数回0溢出1
    /INT1外部中断1IE1定电平或下降沿信号2
    T1定时器中断1TF1定时/计数器1 计数回0溢出3
    TX/RX串行口中断TI/RI串行通信完成一帧数据发送或接收4最低
    定时器/计数器控制寄存器 TCON
    D7D6D5D4D3D2D1D0
    功能TF1TR1TF0TR0IE1IT1IE0IT0

    TF0、 TF1: 是定时器中断标志(定时器0溢出标志位、定时器1溢出标志位)
    TR0 、TR1: 打开相应的定时器(定时器0运行控制位,=1时启动定时器0、定时器1运行控制位,=1时启动定时器1)
    由软件清0关闭定时器0/1。当GATE=1,且INIT为高电平时,TR1置1启动定时器1;当GATE=0时,TR1置1启动定时器0/1。
    IT0、IT1: 是外部中断的触发方式。 =0时 低电平触发,=1时负跳变触发。
    IE0、IE1: 是外部中断的标志位

    中断允许寄存器 IE
    D7D6D5D4D3D2D1D0
    功能EA————ESET1EX1ET0EX0

    EA: 总中断允许。 EA=0;CPU屏蔽所有中断的请求 EA=1;开放所有中断。
    ES:串行口中断允许位。ES=0; 禁止串行中断。ES=1; 允许串口中断。
    ET0、ET1: 定时器/计数器0 和 定时器/计数器 1 中断允许位 =0时 禁止相应的定时器中断。 =1 允许相应的定时器中断
    EX0、EX1: 外部中断0 和 外部中断 1 中断允许位。=0时 禁止相应的外部中断。 =1时 允许相应的外部中断。
    ——:无效位

    中断优先寄存器 IP
    D7D6D5D4D3D2D1D0
    功能——————PSPT1PX1PT0PX0

    PS: 串行口中断优先级 PS = 1;(高) 。PS = 0; (低)。
    PT0:定时器0中断优先级 PT0 = 1;(高) PT0 = 0;(低)。
    PT1:定时器1中断优先级 PT1 = 1;(高) PT1 = 0;(低)。
    PX0:外部中断0中断优先级 PX0 = 1;(高) PX0 = 0;(低)。
    PX1:外部中断1中断优先级 PX1 = 1;(高) PX1 = 0;(低)。
    ——:无效位

    IP寄存器不做设置,上电复位后为00H,默认是为低优先级
    不设置默认优先级是(由高到低):
    外部中断0→定时器0→外部中断1→定时器1→串口

    如果我们把IP寄存器设置为:(IP = 0X10)
    PS = 1;
    PT1 = 0;
    PX1 = 0;
    PT0 = 0;
    PX0 = 0;
    如下表:

    D7D6D5D4D3D2D1D0
    功能——————10000

    那么优先级从高到低是:
    串口→外部中断0→定时器0→外部中断1→定时器1

    工作方式寄存器TMOD
    D7D6D5D4D3D2D1D0
    功能GATEC/TM1M0GATEC/TM1M0

    在这里插入图片描述
    GATE:门控制
    =0:仅有运行控制位TRx来控制定时/计数器的开启。
    =1:由TRx和外部中断脉冲计数。(用于计算外部中断 负跳变 的次数)
    C/T:计数器模式和定时器模式选择
    =0:选择定时器模式
    =1:选择计数器模式
    M1、M0:选择定时/计数器的工作方式

    M1M0工作方式
    00方式0:为13位定时/计数器
    01方式1:为16位定时/计数器
    10方式2:为8位初值自动重装定时/计数器
    11方式3:仅适用于T0,分成两个8位计数器,T1停止计数。

    方式0
    方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。
    在这里插入图片描述
    方式1
    方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器 。
    在这里插入图片描述
    方式2
    方式2为自动重装初值的8位计数方式。
    在这里插入图片描述
    方式3
    方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。
    在这里插入图片描述

    定时器初值寄存器THx 和 TLx

    首先先了解一下CPU时序有关知识:
    振荡周期: 为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)
    状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。
    机器周期:1个机器周期含6个状态周期,12个振荡周期。
    指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。

    例如:外接晶振为12MHz时,51单片机相关周期的具体值为:
    振荡周期=1/12us;
    状态周期=1/6us;
    机器周期=1us;
    指令周期=1~4us;

    计数器初值的计算:

    机器周期就是CPU完成一个基本操作所需要得时间。
    机器周期 = 1 /单片机的时钟频率
    51单片机内部时钟频率是外部时钟的12分频,也就是当外部晶振的频率输入到单片机里面
    的时候要进行12分频。

    比如:你用的是12MHZ的晶振,当你使用12MHZ的外部晶振的时候,
    机器周期 = 1 / 1M = 1us。
    (选择定时器工作方式1 16位)
    我们2的16次方等于65536,也就是最大值为65536(溢出)
    如果定时1ms
    初值就为:1ms / 1us = 1000。也就是要计数1000个数, 初值 = 65535-1000+1 = 64536,65536才会溢出。 所以初值即FC18H(十进制为64536)

    如果定时50ms
    50ms/1us=50000;
    初值 = 65535-50000+1=15536;
    定时为50ms 初值为15536 即3CB0(十六进制)

    对于每个不同的方式计算初值数有公式去计算的,但是我不会哈哈,我是用一个软件来计算的,软件名字 mcuelf这样也比较快
    在这里插入图片描述

    外部中断

    操作步骤(INT0 INT1)

    1 设置 外部中断中断源号及触发方式。设置IT0或IT1(TCON寄存器)
    2 打开相应的外部中断允许。设置EX0或EX1(IE寄存器)
    3 打开总中断。设置EA(IE寄存器)

    如何配置外部中断

    这里就用外部中断0开示例吧

    //配置外部中断0
    void initInterrupt0()
    {
    	IT0 = 1; //触发方式为负跳变触发
    	EX0 = 1; //打开外部中断0允许
    	EA  = 1; //总中断打开
    }
    

    中断服务函数(发生中断你想做什么?)

    无返回值 函数名(随意起) interrupt 中断号
    void interrupt0ServiceFun() interrupt 0
    {
    	//编写你要做的事情
    }
    

    外部中断1也是差不多的,这里就不写了。

    程序示例

    实现按键按下开灯/关灯

    #include "reg52.h"
    
    typedef unsigned char u8;
    typedef unsigned int u16; 
    typedef unsigned long int u32;
    						   
    
    sbit KEY = P3^2; //定义中断按键引脚  
    sbit LED = P2^0; //定义LED1引脚
    
    //配置中断0
    void initInterrupt0()
    {
    	EX0 = 1;
    	IT0 = 1;
    	EA  = 1;
    }
    //延时函数
    void delay(u8 i)
    {
    	while(i--);
    }
    void main()
    {
    
    	initInterrupt0();	//调用中断
    	while(1);
    
    }
    
    //发生中断执行函数
    void interruptHandler() interrupt 0
    {
    	delay(12000);  //延迟 因为当进入外部中断函数的时候按键时已经按下了这里是消抖作用
    	if(KEY == 0)	//再次确认是否真的按键被按下
    	{
    		LED = ~LED;	   //开灯/关灯
    	}
    }
    

    定时器/计数器中断

    需要了解的知识

    51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。

    定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

    51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

    有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情。同时可以实现精确定时作用。

    工作原理

    实质上是加1计数器,随着输入脉冲,计数器自动加1,
    溢出的时候会回0.,且计数器的溢出使相应的中断标志位 置1.
    向CPU发出中断请求。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
    可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

    定时器结构

    定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THx和TLx组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
    在这里插入图片描述

    操作步骤(T0 T1)

    1.选择工作方式。设置M1、M0 (TMOD寄存器)
    2.选择控制方式。设置GATE(TMOD寄存器)
    3.选择定时器还是计数器模式。设置C/T(TMOD寄存器)
    4.给定时/计数器赋初值。设置THx 和 TLx(定时器初值寄存器)
    5.开启总中断。设置EA(IE寄存器)
    6.打开相应定时器中断允许。 设置ET0或ET1(IE寄存器)
    7.启动定时器。设置TR1或TR0(TCON寄存器)

    如何配置定时器

    这里就选择定时器0吧 选择方式1(16位)进行定时示例吧
    1.选择工作方式1(16位)M1=0;M0=1;
    2.控制方式 :仅有运行控制位TRx来控制定时/计数器的开启。GATE=0;
    3.选择定时器模式 C/T=0;

    TMOD=0x01;
    

    4.赋初值 这里选择定时为50ms 我的板子晶振是11.0592 具体怎么算我不会,推荐跟我一样不会的用软件mcuelf计算出以下结果
    在这里插入图片描述

        TH0 = 0x4C;
        TL0 = 0x00;
    

    5.打开总中断(总开关)

    EA=1;
    

    6.打开T0中断开关

    ET0=1;
    

    7.启动定时器0

    TR0=1;
    
    //配置定时器函数
    void time0Config()
    {
    	TMOD=0x01; //设定T0定时器,选择工作方式1(16位),定时器模式 仅有运行控制位TRx来控制定时/计数器的开启。
    	TH0 = 0x4C;  //初值设定
    	TL0 = 0x00;	 //初值设定
    	EA=1;        //打开总中断开关
    	ET0=1;		 //打开T0中断开关
    	TR0=1;		 //启动定时器0
    }
    
    
    //发生中断执行函数(这样就是50ms)
    void time0() interrupt 1   //T0中断号为1
    {
    	/*要注意这里不会自动重装,所以要再次设置回初值(除工作方式2)*/
    	TH0 = 0x4C;  //初值重新设定
    	TL0 = 0x00;	 //初值重新设定
    	
    	//编写你要做的事
    }
    

    程序示例

    这里就写一个用定时器来做一个简单的时钟显示在LCD1602上
    LCD1602我昨天发布了一个LCD1602的使用和显示hello word。这里就是详细讲LCD1602具体的操作了。

    引脚定义

    //引脚定义
    #define LCD P0
    sbit E = P2^7;   //使能
    sbit RS = P2^6;  //数据/命令(H/L)
    sbit RW = P2^5; //读写(H/L)
    
    

    lcd1602.h

    void write_com(unsigned char command);	//写命令函数
    void write_data(unsigned char dat);		//写数据函数
    void init_lcd();  //初始化LCD1602函数
    void delay5ms();  //延时5ms函数	
    

    lcd1602.c

    #include <reg52.h>
    #include "lcd1602.h"
    
    #define LCD P0
    sbit E = P2^7; 
    sbit RS = P2^6;
    sbit RW = P2^5;
    
    /******延迟5毫秒函数********/
    void delay5ms()   //误差 -0.000000000001us
    {
        unsigned char a,b;
        for(b=15;b>0;b--)
            for(a=152;a>0;a--);
    }
    
    
    /******LCD1602写命令函数********/
    void write_com(unsigned char command)
    {
    	RS = 0; 
    	RW = 0; 	//高读低写
    	LCD = command;
    	delay5ms(); //这里延时最低要30纳秒 我们直接给5ms
    	E = 1;		//使能拉高 
    	delay5ms(); //最低要求延迟150纳秒 我们直接给5ms
    	E = 0;
    }
    
    /******LCD1602写数据函数********/
    void write_data(unsigned char dat)
    {
    	RS = 1;
    	RW = 0;
    	LCD = dat;
    	delay5ms(); //这里延时最低要30纳秒 我们直接给5ms
    	E = 1;		//使能拉高 
    	delay5ms(); //最低要求延迟150纳秒 我们直接给5ms
    	E = 0;
    }
    /******初始化LCD1602********/
    void init_lcd()
    {	
    	write_com(0x06); //写入数据后光标自动右移 整屏不移动。
    	write_com(0x0c); //开显示功能 无光标 不闪烁
    	write_com(0x38); //数据总线8位 16X2显示 5*7点阵
    	write_com(0x01); //清屏 0000 0001
    }
    

    main.c

    #include <reg52.h>
    #include "lcd1602.h"
    
    unsigned char t = 0; //用来计数时间
    unsigned char i=0;
    unsigned char hours = 23;  //小时
    unsigned char minutes = 59; //分钟
    unsigned char seconds = 0; //秒
    
    unsigned char date[16] = {"2021-01-27   WED"};
    unsigned char time[5] = {"time:"};
    
    //配置定时器函数
    void time0Config()
    {
    	TMOD=0x01; //设定T0定时器,选择工作方式1(16位),定时器模式 仅有运行控制位TRx来控制定时/计数器的开启。
    	TH0 = 0x4C;  //初值设定
    	TL0 = 0x00;	 //初值设定
    	EA=1;        //打开总中断开关
    	ET0=1;		 //打开T0中断开关
    	TR0=1;		 //启动定时器0
    }
    
    void main()
    {	
    	init_lcd();	 //1.初始化lcd1602
    	
    	write_com(0x80); //设置显示日期位置 (第一行第一个开始)
    	for(i=0;i<16;i++)
    	{
    		write_data(date[i]);	
    	}
    	
    	write_com(0xc0); //设置显示time:位置(第二行第一个开始)
    	for(i=0;i<5;i++)  
    	{
    		write_data(time[i]);		
    	}
    	
    	time0Config();//调用定时器中断
    
    	while(1)
    	{
    		write_com(0xc6); 	//设置显示小时的十位 位置
    		write_data(hours/10+'0');	//小时十位
    		write_com(0xc7); 	//设置显示小时的个位 位置
    		write_data(hours%10+'0');	//小时个位
    	
    		write_com(0xc8); //设置显示: 位置
    		write_data(':');			//显示 :
    	
    		write_com(0xc9); 	//设置显示分钟的十位 位置
    		write_data(minutes/10+'0');	//分钟十位
    		write_com(0xca); 	//设置显示分钟的个位 位置
    		write_data(minutes%10+'0');	//分值个位
    	
    		write_com(0xcb); 	//设置显示: 位置
    		write_data(':');			//显示 :
    	
    		write_com(0xcc); 	//设置显示秒的十位 位置
    		write_data(seconds/10+'0');	//秒十位
    		write_com(0xcd); 	//设置显示秒的 个位 位置
    		write_data(seconds%10+'0');	//秒个位
    						
    	}
    }
    
    //发生中断执行函数(一次就是50ms)
    void time0() interrupt 1   //T0中断号为1
    {
    	/*要注意这里不会自动重装,所以要再次设置回初值(除工作方式2)*/
    	
    	TH0 = 0x4C;  //初值重新设定
    	TL0 = 0x00;	 //初值重新设定	
    	t++;
    	if(t == 20) //证明够1秒了 20 X 50ms = 1000ms = 1s
    	{
    		seconds++;	//秒+1
    		t=0;   //够了1秒设置为0 重新计数
    	}
    	if(seconds == 60) //如果秒到60
    	{
    		minutes++;   //分钟+1
    		seconds = 0; //秒回0
    	}
    	if(minutes == 60) //如果分钟到60
    	{
    		hours++;     //小时+1
    		minutes = 0; //分钟回0
    	}
    	if(hours == 24 ) //如果小时到24
    	{
    		hours = 0;   //小时回0
    	}
    	
    }
    

    最终项目展示

    在这里插入图片描述

    展开全文
  • 本文主要对单片机中断请求源进行了简要分析,希望对你的学习有所帮助。
  • 那么,什么是单片机中断,它与CPU的轮询有什么区别?在本文中,单片机开发工程师将对单片机中断和CPU轮询做个简单的介绍。 中断: 中断是一种硬件机制,在这种机制中,设备会通知CPU它需要引起注意。中断可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,788
精华内容 25,515
关键字:

单片机中断