Proteus仿真实例:C51中断函数应用

实现目标

要求外部中断INT0和INT1为低电平触发,相应引脚分别接一按钮,按钮按下接地输入低电平,产生中断信号;定时器/计数器T0和定时器/计数器T1设置为外部计数输入,相应引脚接1khz的方波信号,T0每满2000个脉冲产生1次中断,T1每满4000产生一次中断

Proteus仿真图

Proteus仿真:C51中断函数实例_C51

C51代码

登录后复制

#include <REG52.H>    /* special function register declarations */#include <stdio.h>    /* prototype declarations for I/O functions */#define byte unsigned char#define uchar unsigned char#define word unsigned int#define uint unsigned int#define ulong unsigned long#define BYTE    unsigned char#define WORD    unsigned int#define TRUE  1#define FALSE 0 void initUart(void);/*初始化串口*/ void time(unsigned int ucMs);//延时单位:ms/******** main 函数 *********/void main (void) {      initUart();/* 初始化串口 */          TMOD=0x55; /* 工作在方式1,外部引脚计数 */    TH0=-2000>>8;TL0=-2000 % 256;/* 定时器0每2000计数脉冲发生1次中断 */        TH1=-4000>>8;TL1=-4000 % 256;/* 定时器1每4000计数脉冲发生1次中断 */    TCON=0x55; /* 电平触发外部中断,开始计数 */    IE=0x8f;   /*打开出串口中断外其它所有中断*/    while (TRUE) {              time(1);/* 延时1ms */    }}/***********  中断0服务程序***************/void exint0(void) interrupt 0{    EA=0;/* 关总中断 */    /* 可在此处插入外部中断0服务程序 */       printf ("external interrupt 0 happened\n");    EA=1;/* 开总中断 */}/***********  中断1服务程序***************/void exint1(void) interrupt 2{    EA=0;/* 关总中断 */    /* 可在此处插入外部中断1服务程序 */    printf ("external interrupt 1 happened\n");    EA=1;/* 开总中断 */}/******* 定时器/计数器0中断服务程序 ***/void timer0int(void) interrupt 1{       EA=0;/* 关总中断 */    TR0=0;/*停止计数*/    /* 可在此处插入定时器/计数器0中断服务程序 */    TH0=-2000>>8;TL0=-2000 % 256;/* 重置计数初值 */         printf ("timer0 interrupt happened\n");    TR0=1;/*启动计数*/    EA=1;/* 开总中断 */}/******* 定时器/计数器1中断服务程序 ***/void timer1int(void) interrupt 3{       EA=0;/* 关总中断 */    TR1=0;/*停止计数*/    /* 可在此处插入定时器/计数器1中断服务程序 */    TH1=-4000>>8;TL1=-4000 % 256;/* 重置计数初值 */    printf ("timer1 interrupt happened\n");    TR1=1;/*启动计数*/    EA=1;/* 开总中断 */}/********** 初始化串口波特率 ************/void initUart(void)/*初始化串口波特率,使用定时器2*/{/* Setup the serial port for 9600 baud at 11.0592MHz */    SCON = 0x50;  //串口工作在方式1    RCAP2H=(65536-(3456/96))>>8;    RCAP2L=(65536-(3456/96))%256;    T2CON=0x34;    TI  = 1;     /* 置位TI*/}/*********** 延时单位:ms *******************/void time(unsigned int ucMs)//延时单位:ms{    unsigned char j;        while(ucMs>0){        for(j=0;j<10;j++) delay_100us();        ucMs--;    }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.

笔记

TCON:定时器/计数器控制
TMOD:定时器/计数器方式控制
TH0:定时器/计数器0高字节
TL0:定时器/计数器0低字节
TH1:定时器/计数器1高字节
TL1:定时器/计数器1低字节
IE:中断允许控制
EA:CPU中断允许控制位

注1:

TH0=-2000>>8;TL0=-2000 % 256;/* 定时器0每2000计数脉冲发生1次中断 */ 上面代码定义定时器0每2000计数脉冲发生1次中断 -2000>>8 表示 -2000/256,因为定时器/计数是16位,除以256表示取高8位 -2000%256表示取低8位

注2:

每2000计数脉冲,在程序中写的的-2000,而不是2000。 为什么呢? 这是因为计时器是向上计数,为了得到2000个计数脉冲后定时器溢出, 则必须给计时器赋初值为65536-2000(65536=2的16次方) 其实也就是-2000(取反再+1) emm 举个例子就会懂了 假设计数器是4位,最大溢出时为1111(15) 我们需求是7个脉冲产生一个中断 那么计数器初始值就是16-7(9) 9=1001 -7=-(0111)=1001(取反再+1) ==》16-7=-7 所以是-2000/256 和 -2000%256

运行结果


C51中断实例

Proteus仿真:C51中断函数实例_中断_02


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空