精华内容
下载资源
问答
  • 应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长(详见2013年9月29日博文《MSP430和AT89C51单片机4x4键盘C程序》),如果用中断编写,设置中断响应在下降沿时执行中断,则程序编写不用去抖动...

    应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长(详见2013年9月29日博文《MSP430和AT89C51单片机4x4键盘C程序》),如果用中断编写,设置中断响应在下降沿时执行中断,则程序编写不用去抖动判断,所以相比较要简单很多!下面用汇编和C语言两种方式编写4X4键盘程序!

    一、汇编程序

    ORG 0000H

    LJMP MAIN

    ORG 0003h

    Ljmp ZD0

    ORG 000Bh

    LJMP TZD0

    ORG 0013h

    Ljmp ZD1

    ORG 001Bh

    LJMP TZD1

    ORG 0040H

    MAIN: Mov TMOD,#66h

    MOV TH0,#0ffh

    MOV TL0,#0ffh

    MOV TH1,#0ffh

    MOV TL1,#0ffh

    SETB EA

    SETB ET0

    SETB TR0

    SETB ET1

    SETB TR1

    SETB IT0

    SETB IT1

    SETB EX0

    SETB EX1

    xh:      mov P1,#0feh

    Lcall Delay

    mov P1,#0fdh

    Lcall Delay

    mov P1,#0fbh

    Lcall Delay

    mov P1,#0f7h

    Lcall Delay

    SJMP xh

    ZD0:  JNB P1.0,dat1

    JNB P1.1,dat2

    JNB P1.2,dat3

    JNB P1.3,dat4

    dat1: mov P2,#06h  ;1

    sjmp ZD0R

    dat2: mov P2,#5bh  ;2

    sjmp ZD0R

    dat3: mov P2,#4fh  ;3

    sjmp ZD0R

    dat4: mov P2,#66h  ;4

    ZD0R: reti

    ZD1:  JNB P1.0,dat5

    JNB P1.1,dat6

    JNB P1.2,dat7

    JNB P1.3,dat8

    dat5: mov P2,#6dh  ;5 0110

    sjmp ZD1R

    dat6: mov P2,#7dh  ;6

    sjmp ZD1R

    dat7: mov P2,#07h  ;7

    sjmp ZD1R

    dat8: mov P2,#7fh  ;8

    ZD1R: reti

    TZD0: JNB P1.0,dat9

    JNB P1.1,dat0

    JNB P1.2,dat10

    JNB P1.3,dat11

    dat9:   mov P2,#6fh  ;9

    sjmp ZD0R

    dat0:   mov P2,#3fh  ;0

    sjmp ZD0R

    dat10: mov P2,#77h  ;A

    sjmp ZD0R

    dat11: mov P2,#7ch  ;B

    TZD0R:reti

    TZD1: JNB P1.0,dat12

    JNB P1.1,dat13

    JNB P1.2,dat14

    JNB P1.3,dat15

    dat12: mov P2,#39h  ;C

    sjmp TZD1R

    dat13:mov P2,#5eh  ;D

    sjmp TZD1R

    dat14:mov P2,#79h  ;E

    sjmp TZD1R

    dat15:mov P2,#71h  ;F

    TZD1R:reti

    Delay:mov r7,#10d

    djnz r7,$

    ret

    end

    3016cfb072aa9e98e81d7f9cac590b44.png

    二、C语言程序(扫描P1)

    #include"reg51.h"

    int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

    int i,j,k,time,temp,dat;

    void delay(time)

    {

    while(time--)

    for(i=0;i<120;i++);

    }

    void main()

    {

    P2=0x40;

    TMOD=0x66;  //设定定时计数器T0、T1为方式2计数模式

    TH0=0xFF;

    TL0=0xFF;

    TH1=0xFF;

    TL1=0xFF;

    IE=0x8F;    //开总中断和定时计数器两个中断,两个外中断

    IT0=1;

    IT1=1;      //设置外中断为下降沿触发

    TR0=1;

    TR1=1;       //打开定时计数器开始计数

    while(1)

    {

    P1=0xfe;

    delay(1);

    P1=0xfd;

    delay(1);

    P1=0xfb;

    delay(1);

    P1=0xf7;

    delay(1);

    }

    }

    void intsvr0(void) interrupt 0  using 1

    {

    temp=P1;

    switch(temp)

    {

    case 0xfe:key=0;break;

    case 0xfd:key=1;break;

    case 0xfb:key=2;break;

    case 0xf7:key=3;break;

    default:break;

    }

    P2=yu[dat];

    }

    void timer0(void) interrupt 1 using 1

    {

    temp=P1;

    if(temp==0xfe)  dat=4;

    if(temp==0xfd) dat=5;

    if(temp==0xfb) dat=6;

    if(temp==0xf7) dat=7;

    P2=yu[dat];

    }

    void intsvr1(void) interrupt 2 using 1

    {

    temp=P1;

    if(temp==0xfe) dat=8;

    if(temp==0xfd) dat=9;

    if(temp==0xfb) dat=10;

    if(temp==0xf7) dat=11;

    P2=yu[dat];

    }

    void timer1(void) interrupt 3 using 1

    {

    int dat;

    temp=P1;

    switch(temp)

    {

    case 0xfe:key=12;break;

    case 0xfd:key=13;break;

    case 0xfb:key=14;break;

    case 0xf7:key=15;break;

    default:break;

    }

    P2=yu[dat];

    }

    /*************************************************************/[page]

    三、C语言(扫描P3的P3.0、P3.1、P3.6、P3.7)

    从这个程序也可以看出51单片机I/O口没有方向性,输入输出都可读写,而且在一个寄存器中。注意该程序对应电路图与上图的区别。

    5e5aefe75692be268b9a782c86e5ff71.png

    #include"reg51.h"

    sbit pp0=P3^0;

    sbit pp1=P3^1;

    sbit pp2=P3^6;

    sbit pp3=P3^7;

    int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

    int i,j,k,time,temp,dat;

    void delay(time)

    {

    while(time--)

    for(i=0;i<120;i++);

    }

    void main()

    {

    P2=0x40;

    TMOD=0x66;  //设定定时计数器T0、T1为方式2计数模式

    TH0=0xFF;

    TL0=0xFF;

    TH1=0xFF;

    TL1=0xFF;

    IE=0x8F;    //开总中断和定时计数器两个中断,两个外中断

    IT0=1;

    IT1=1;      //设置外中断为下降沿触发

    TR0=1;

    TR1=1;       //打开定时计数器开始计数

    while(1)

    {

    pp0=0;

    delay(5);

    pp0=1;

    pp1=0;

    delay(5);

    pp1=1;

    pp2=0;

    delay(5);

    pp2=1;

    pp3=0;

    delay(5);

    pp3=1;

    /*以上可用下列这段代替

    P3=0xfe;

    delay(5);

    P3=0xfd;

    delay(5);

    P3=0xbf;

    delay(5);

    P3=0x7f;

    delay(5);*/

    }

    }

    void intsvr0(void) interrupt 0  using 1

    {

    temp=P3;

    switch(temp)

    {

    case 0xfa:dat=0;break;

    case 0xf9:dat=1;break;

    case 0xbb:dat=2;break;

    case 0x7b:dat=3;break;

    default: break;

    }

    P2=yu[dat];

    }

    void timer0(void) interrupt 1 using 1

    {

    temp=P3;

    if(temp==0xee) dat=8;

    if(temp==0xed) dat=9;

    if(temp==0xaf) dat=10;

    if(temp==0x6f) dat=11;

    P2=yu[dat];

    }

    void intsvr1(void) interrupt 2 using 3

    {

    temp=P3;

    if(temp==0xf6) dat=4;

    if(temp==0xf5) dat=5;

    if(temp==0xb7) dat=6;

    if(temp==0x77) dat=7;

    P2=yu[dat];

    }

    void timer1(void) interrupt 3 using 1

    {

    int dat;

    temp=P3;

    switch(temp)

    {

    case 0xde:dat=12;break;

    case 0xdd:dat=13;break;

    case 0x9f:dat=14;break;

    case 0x5f:dat=15;break;

    default: break;

    }

    P2=yu[dat];

    }

    展开全文
  • Q:c语言编写51单片机中断程序,执行过程是怎样的?例如程序:#includevoid main(void){EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断P0=0xff; //关闭所有P0口的LED灯while(1); //无限...

    Q:c语言编写51单片机中断程序,执行过程是怎样的?

    例如程序:

    #include

    void main(void)

    {

    EA=1;      //开放总中断

    EX0=1;     //允许使用外中断

    IT0=1;    //选择负跳变来触发外中断

    P0=0xff;         //关闭所有P0口的LED灯

    while(1); //无限循环,

    }

    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0

    {

    P0=~P0;  //每产生一次中断请求,P0取反一次。

    }

    当有中断时,这个程序的执行过程是怎样的???

    A1:从main开始,开放总中断,允许使用外中断,选择负跳变来触发外中断,到这时负跳变没来没就一直while(1),等待。来了后执行

    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0

    {

    P0=~P0;  //每产生一次中断请求,P0取反一次。

    }

    A2:有中断时直接跑到中断服务去

    A3:CPU会一直在检测是否有中断请求的。当收到中断请求EX 时,进行软件设置,开启总中断EA ,再设置中断的触发方式IT。

    转载自:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=220199

    外部中断定时器c语言程序详解

    利用外部中断0,定时器0从数码管到流水灯显示

    #include "reg52.h"//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

    #include "intrins.h"

    11708ac0bd8fd17d6f0ac8cd38f0e5bb.png

    #define uint unsigned int

    #define uchar unsigned char

    997853afc823fcd6a47bb944b8ec29b2.png

    uchar led,n,i,count=0;

    uchar smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f

    ,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F

    uchar sm[]={0x00,0x01};//数码管扫描

    uchar str[2];//显示两位数码管

    2ba733233b5defdd85bc45a48eae908c.png

    /******************************************************************/

    /*                    延时函数声明                                */

    /******************************************************************/

    /*void mdelay(uint t)

    {

    uchar n;

    for(;t>0;t--)

    for(n=0;n<125;n++)

    {;}

    }*/

    /*大约一毫秒的延时函数*/

    void mdelay(uint t)

    {

    uchar n;

    while(t--)

    {

    for(n=0;n<123;n++)

    {;}

    }

    }

    0a75fbc79a73218d2d5496fd0616e3fe.png

    /******************************************************************/

    /*                   主函数 1                                      */

    /******************************************************************/

    void main()

    {

    EA=1;//开总中断开关

    EX0=1;//打开外部中断0

    INT0=1;//触发方式为下降沿触发

    TH0=0x3c;//设置初值

    TL0=0xb0;

    ET0=1;//打开定时器中断

    TR0=1;//启动定时器

    TMOD=0x01;//设置定时器0为工作方式1

    044815c63a4bd32db99052b03c17bad6.png

    while(1)

    {

    for(i=0;i<2;i++)//数码管显示数据

    {

    P1=0xff;

    P2=sm[i];

    P0=smg[str[i]];

    mdelay(5);

    }

    }

    }

    1141d66e712c64a0bfcddfb096e1a68b.png

    void int0() interrupt 0

    {

    uchar c;

    led=0xfe;

    P2=0x00;

    for(c=0;c<8;c++)//流水灯循环一次

    {

    P1=led;

    led=_crol_(led,1);//左移函数

    mdelay(1000);

    }

    }

    3825912233bb1c6402a7236613f2839f.png

    void time0() interrupt 1

    {

    TH0=0x3c;

    TL0=0xb0;

    count++;

    if(count==20)//延时一秒0-60显示

    {

    count=0;

    str[0]=n/10;

    str[1]=n%10;

    n++;

    if(n==60)

    {

    n=0;

    }

    }

    }

    10

    本经验只供参考,如有不足,还请见谅。。。

    转载自:https://jingyan.baidu.com/article/870c6fc304cff6b03ee4be45.html

    51单片机中断interrupt……using……

    51单片机中断细节的一些问题. interrupt0:外部中断0interrupt1:定时器中断0interrupt2:外部中断interrupt3:定时器中断1interrupt4:串口 using ...

    C语言编写的bmp读写程序

    C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下 #include "Windows ...

    Windows程序执行过程

    Windows应用程序: WinMain函数(入口函数): 1. 设计窗体类,注冊窗体类.WNDCLASS 2. 创建窗体,显示及更新窗体. 3. 消息循环. 窗体过程函数(回调函数):WindowP ...

    MFC程序执行过程剖析

    一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...

    MFC程序执行过程剖析(转)

    一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...

    Java程序执行过程及内存机制

    本讲将介绍Java代码是如何一步步运行起来的,其中涉及的编译器,类加载器,字节码校验器,解释器和JIT编译器在整个过程中是发挥着怎样的作用.此外还会介绍Java程序所占用的内存是被如何管理的:堆.栈和 ...

    ET 与RETI 基于51单片机中断跳出指令&OpenCurlyDoubleQuote;RETI”浅议

    最近在基于51单片机编程的过程中出现了个很奇怪的问题“程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”.在有过单片机中断编程经历者都知道当EA=1,ET0=1的 ...

    Leaf - 一个由 Go 语言编写的开发效率和执行效率并重的开源游戏服务器框架

    转自:https://toutiao.io/posts/0l7l7n/preview Leaf 游戏服务器框架简介 Leaf 是一个由 Go 语言(golang)编写的开发效率和执行效率并重的开源游戏 ...

    Android入门学习:Android 系统框架及应用程序执行过程

    Android基础知识学习 新手上路,还请多多帮助.由于初学,博客内容难免有不正确的地方,还请各位多多指教,相互学习! 主要内容: 1.Android层次架构及主要功能 2.Android编程模型,程 ...

    随机推荐

    myeclipse 无法启动

    1.对项目中的一个文件重新命名,导致卡死,结束myeclipse进程不管用,重启不管用. 删除工程下的文件  以  .markers.snap 和  marker开头的两个文件   位置: 工作空间\ ...

    Sharepoint学习笔记—习题系列--70-573习题解析 -&lpar;Q85-Q87&rpar;

    Question 85You create a Microsoft .NET Framework console application that uses a Representational St ...

    Codeforces Gym 100231G Voracious Steve 记忆化搜索

    Voracious Steve 题目连接: http://codeforces.com/gym/100231/attachments Description 有两个人在玩一个游戏 有一个盆子里面有n个 ...

    LeetCode&lowbar;Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 很挫的一个想 ...

    dbgrid数据显示和数据源不同

    dbgrid数据显示和数据源不同,在ODBC配置时如下设置,去掉勾

    如何探测网络设备ACL规则

    探测网络设备ACL规则 背景:在互联网企业的生产网络中,往往在网络入口处的网络设备上会有成千上万条ACL策略,这么多的ACL导致了网络管理员很难彻底梳理清楚其中的逻辑关系,从而不知道到底对外开放了哪些 ...

    文件系统及程序的限制关系: ulimit

    想像一个状况:我的 Linux 主机里面同时登陆了十个人,这十个人不知怎么搞的, 同时打开了 100 个文件,每个文件的大小约 10MBytes ,请问一下, 我的 Linux 主机的内存要有多大才够 ...

    webpack打包优化

    https://www.cnblogs.com/vvjiang/p/9327903.html

    vscode &plus; gradle 创建 java 项目 - java language server无法启动

    1.在系统上安装一个版本的gradle,用`gradle init --type java-application`创建一个默认的java项目,假设项目目录是hellojava 2.vscode写ja ...

    ABP框架系列之二十九:&lpar;Hangfire-Integration-延迟集成&rpar;

    Introduction Hangfire is a compherensive background job manager. You can integrate ASP.NET Boilerpla ...

    展开全文
  • 应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长,如果用中断编写,设置中断响应在下降沿时执行中断,则程序编写不用去抖动判断,所以相比较要简单很多!下面用汇编和C语言两种方式编写4X4...
  • 51 单片机中断编写的 4x4 键盘程序 应用查询扫描编写键盘程序由于要给按键去抖动程序变 得比较复杂和冗长详见 2013 年 9 月 29 日博文MSP430 和 AT89C51 单片机 4x4 键盘 C 程序如果用中断编写设置中断响应在下降...
  • Q:c语言编写51单片机中断程序,执行过程是怎样的? 例如程序:#include<reg52.h>void main(void){ EA=1; //开放总中断 EX0=1; //允许使用外中断 IT0=1; //选择负跳变来触发外中断 P0=0xff; //关闭所有P0口...

    Qc语言编写51单片机中断程序,执行过程是怎样的?

     

    例如程序:
    #include<reg52.h>  
    void main(void)
      {
       EA=1;      //开放总中断
       EX0=1;     //允许使用外中断
       IT0=1;    //选择负跳变来触发外中断 
       P0=0xff;         //关闭所有P0口的LED灯
            while(1); //无限循环,
    }
    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0
    {

      P0=~P0;  //每产生一次中断请求,P0取反一次。
      
    }
    当有中断时,这个程序的执行过程是怎样的???

     

     

     

    A1main开始,开放总中断,允许使用外中断,选择负跳变来触发外中断,到这时负跳变没来没就一直while(1),等待。来了后执行
    void it0(void) interrupt 0 using 0 //外中断0的中断编号为0
    {

      P0=~P0;  //每产生一次中断请求,P0取反一次。
      
    }

     

     

     

     

    A2有中断时直接跑到中断服务去

     

     

     

    A3:CPU会一直在检测是否有中断请求的。当收到中断请求EX 时,进行软件设置,开启总中断EA ,再设置中断的触发方式IT。

    转载自:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=220199

     

     

     

     

    外部中断定时器c语言程序详解

    1. 利用外部中断0,定时器0从数码管到流水灯显示

    2.  

      #include "reg52.h"//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

      #include "intrins.h"

      外部中断定时器c语言程序详解(1)
    3.  

      #define uint unsigned int

      #define uchar unsigned char

      外部中断定时器c语言程序详解(1)
    4.  

      uchar led,n,i,count=0;

      uchar smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f

                ,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F

      uchar sm[]={0x00,0x01};//数码管扫描

      uchar str[2];//显示两位数码管

      外部中断定时器c语言程序详解(1)
    5.  

      /******************************************************************/

      /*                    延时函数声明                                */

      /******************************************************************/

      /*void mdelay(uint t)

      {

        uchar n;

      for(;t>0;t--)

       for(n=0;n<125;n++)

        {;}

      }*/

      /*大约一毫秒的延时函数*/

      void mdelay(uint t)

      {

        uchar n;

      while(t--)

      {

      for(n=0;n<123;n++)

        {;}

        }  

      }

      外部中断定时器c语言程序详解(1)
    6.  

      /******************************************************************/

      /*                   主函数 1                                      */

      /******************************************************************/

      void main()

      {

      EA=1;//开总中断开关

      EX0=1;//打开外部中断0

      INT0=1;//触发方式为下降沿触发

      TH0=0x3c;//设置初值

      TL0=0xb0;

      ET0=1;//打开定时器中断

      TR0=1;//启动定时器

      TMOD=0x01;//设置定时器0为工作方式1

      外部中断定时器c语言程序详解(1)
    7.  

      while(1)

      {

      for(i=0;i<2;i++)//数码管显示数据

      {

      P1=0xff;

      P2=sm[i];

      P0=smg[str[i]];

      mdelay(5);

      }

      }

      }

      外部中断定时器c语言程序详解(1)
    8.  

      void int0() interrupt 0

      {

        uchar c; 

      led=0xfe;

        P2=0x00;

      for(c=0;c<8;c++)//流水灯循环一次

      {

      P1=led;

      led=_crol_(led,1);//左移函数

      mdelay(1000);

      }

      }

      外部中断定时器c语言程序详解(1)
    9.  

      void time0() interrupt 1

      {

      TH0=0x3c;

      TL0=0xb0;

      count++;

        if(count==20)//延时一秒0-60显示

        {

      count=0;

      str[0]=n/10;

      str[1]=n%10;

      n++;

      if(n==60)

      {

       n=0;

          }

        }

      }

    10. 10

      本经验只供参考,如有不足,还请见谅。。。

       

      转载自:https://jingyan.baidu.com/article/870c6fc304cff6b03ee4be45.html

    转载于:https://www.cnblogs.com/chengqi521/p/7649105.html

    展开全文
  • 实现51单片机的外部中断,下降沿触发中断,实现中断功能。
  • 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
    	}
    	
    }
    

    最终项目展示

    在这里插入图片描述

    展开全文
  • 51单片机上的检测外部中断程序,分别由汇编和C编写.经验证,能成功运行
  • 51单片机中断

    2013-03-27 21:53:17
    51中断程序,我在protues和stc的单片机上都下载试过了,可以实现,使用汇编编写的,我自己编的,注释很详细,适合初学者
  • 51定时器中断程序编写 [李园7舍_404]

    千次阅读 2012-12-01 08:17:45
    上篇笔记记录到51单片机中断允许寄存器、定时器/计数器工作方式寄存器(TMOD)、定时器/计数器控制寄存器(TCON)各位的作用。这些寄存器都是用来为编写定时器中断程序编写的初始化部分而服务的。然后今天再这里补填...
  • 本文主要介绍了关于MCS-51单片机中断函数的几点注意事项,希望对你的学习有所帮助。
  • 单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。概括的讲:一块芯片就成了一台计算机。它的体积...
  • C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。
  • 1、51单片机定时中断C语言的写法步骤程序说明:51单片机定时器0工作于方式一,定时50ms中断一次晶振为12M#includevoid mainTOMD = 0X01;/配置定时器0工作于方式一TH1 = (65536-50000)/256; /高八位装...
  • 51单片机中断系统实验 一、实验内容 INT0端接单次脉冲发生器。按一次脉冲产生一次中断,CPU使P1.0状态发生一次反转,P1.0接LED灯,以查看信号反转。 根据实验内容编写一个程序,并在实验系统上调试和验证。 二、仿真...
  • 51单片机外部中断例子程序

    热门讨论 2009-02-16 18:10:27
    很好的单片机外部中断例程,看了就知道了,中断里计数,并显示到数码管上
  • 51单片机中断设置

    千次阅读 2015-09-16 23:57:56
    外部中断系统框图: 这些中断请求源的中断请求标志位分别有特殊功能寄存器TCON和SCON的响应位锁存 1、TCON寄存器 与中断有关的是低四位。 1)IT0和 IT1——外中断请求触发标志位:  0——为低电平触发; ...
  • 51单片机中断基本概念

    千次阅读 多人点赞 2020-07-31 10:11:47
    中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的,中断功能的存在,很大程度上提高了单片机处理外部或内部事件的能力。 中断系统特点: ①分时操作。CPU 可以分时为多个 I/O 设备服务,提高了...
  • ARM处理器与51单片机程序编写的区别

    千次阅读 2017-06-12 20:59:12
    51单片机中占2个字节;在ARM处理器中占4个字节。 (2)结构体对齐 在51单片机中按照一个字节对齐;在ARM中按照结构体默认对齐规则对齐。 (3)字节在内存的排列顺序 在51单片机中是大端;在ARM中,大多数是小端...
  • 51单片机中断嵌套,定时器延时前言一、如何做到定时器延时?二、如何做到外部中断?三、如何合并1.引入库2.读入数据总结 前言 这里讲的是中断嵌套,具体的话是用定时器延时,外部中断触发,不断切换 提示:以下是...
  • 51单片机的5大中断源:串行口中断、定时中断1、外部中断1、定时中断0、外部中断0;下面一起来学习一下
  • 基于MCS-51用汇编语言编写一个时钟显示程序,使用定时器0的方式1实现。内含思路、程序框图、源代码等。
  • 写了一个 51单片机外部中断程序

    千次阅读 2016-07-11 18:12:15
    /*以下是能在keilC 中变异的源码,直接粘贴过去就行,外部中断0(INT0)和外部中断1都有(INT1)*/ /*程序很简单,但是对新手来说还是很实用的*/ /****************************************************************...
  • 入门有针对性的解决一些简单的实际问题,边理论边实践学一样会一样基本实验:LED流水灯,数码管显示,键盘控制,音乐播放,继电器控制I2C通信实验,串口通信实验,红外线遥控信号解码实验等单片机的定义分类和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,392
精华内容 2,156
关键字:

51单片机中断程序编写