51单片机中断程序大全

在这里插入图片描述

实例 1:用定时器T1查询方式控制单片机发出1KHz音频

#include<reg51.h>        //  包含51单片机寄存器定义的头文件
sbit sound=P3^7;   //将sound位定义为P3.7引脚
void main(void)
{
    EA=1;                  //开总中断
	ET0=1;                 //定时器T0中断允许         
	TMOD=0x10;            //使用定时器T1的模式1
	TH1=(65536-921)/256;  //定时器T1的高8位赋初值
	TL1=(65536-921)%256;  //定时器T1的高8位赋初值
	TR1=1;                //启动定时器T1
	TF1=0;
	while(1)//无限循环等待查询
    {
	   while(TF1==0);
		 TF1=0;
		sound=~sound;  //将P3.7引脚输出电平取反
       TH1=(65536-921)/256;  //定时器T0的高8位赋初值
	    TL1=(65536-921)%256;  //定时器T0的高8位赋初值
	 }
 }

实例 2:将计数器T0计数的结果送P1口8位LED显示

#include<reg51.h>        //  包含51单片机寄存器定义的头文件

sbit S=P3^4;   //将S位定义为P3.4引脚

void main(void)
{
    EA=1;                  //开总中断
 	ET0=1;                 //定时器T0中断允许         
	TMOD=0x02;            //使用定时器T0的模式2
	TH0=256-156;  //定时器T0的高8位赋初值
	TL0=256-156;  //定时器T0的高8位赋初值
	TR0=1;                //启动定时器T0
	while(1)//无限循环等待查询
    {
	   while(TF0==0)  //如果未计满就等待
  	    {
           if(S==0)  //按键S按下接地,电平为0
			    P1=TL0; //计数器TL0加1后送P1口显示
        } 
	    TF0=0;  //计数器溢出后,将TF0清0
	 }
}

实例 3:用定时器T0的中断控制1位LED闪烁

#include<reg51.h>  //  包含51单片机寄存器定义的头文件

sbit D1=P2^0;  //将D1位定义为P2.0引脚

void main(void)
{
   	EA=1;                  //开总中断
	ET0=1;                 //定时器T0中断允许         
	TMOD=0x01;             //使用定时器T0的模式2
	TH0=(65536-46083)/256; //定时器T0的高8位赋初值
	TL0=(65536-46083)%256; //定时器T0的高8位赋初值
	TR0=1;                 //启动定时器T0
	while(1);
}

//函数功能:定时器T0的中断服务程序
**************************************************************/
void Time0(void) interrupt 1 using 0   //寄存器 
 {
   	D1=~D1;  //按位取反操作,将P2.0引脚输出电平取反
  	TH0=(65536-46083)/256; //定时器T0的高8位重新赋初值
	TL0=(65536-46083)%256; //定时器T0的高8位重新赋初值
 }

实例 4:用定时器T0的中断实现长时间定时

#include<reg51.h>  //  包含51单片机寄存器定义的头文件

sbit D1=P2^0;  //将D1位定义为P2.0引脚
unsigned char Countor; //设置全局变量,储存定时器T0中断次数

void main(void)
{
    EA=1;                  //开总中断
	ET0=1;                 //定时器T0中断允许         
	TMOD=0x01;             //使用定时器T0的模式2
	TH0=(65536-46083)/256; //定时器T0的高8位赋初值
	TL0=(65536-46083)%256; //定时器T0的高8位赋初值
	TR0=1;                 //启动定时器T0
	Countor=0;            //从0开始累计中断次数
	while(1);
}
/**************************************************************
函数功能:定时器T0的中断服务程序
**************************************************************/
void Time0(void) interrupt 1 using 0 
{
    Countor++;   //中断次数自加1
	if(Countor==20)  //若累计满20次,即计时满1s
	{
	   D1=~D1;     //按位取反操作,将P2.0引脚输出电平取反
		Countor=0;  //将Countor清0,重新从0开始计数
	}
  	TH0=(65536-46083)/256; //定时器T0的高8位重新赋初值
	TL0=(65536-46083)%256; //定时器T0的高8位重新赋初值
}

实例 5:用定时器T1中断控制两个LED以不同周期闪烁

#include<reg51.h>  //  包含51单片机寄存器定义的头文件

sbit D1=P2^0;  //将D1位定义为P2.0引脚
sbit D2=P2^1;  //将D2位定义为P2.1引脚
unsigned char Countor1; //设置全局变量,储存定时器T1中断次数
unsigned char Countor2; //设置全局变量,储存定时器T1中断次数

void main(void)
{
    EA=1;                  //开总中断
	ET1=1;                 //定时器T1中断允许         
	TMOD=0x10;             //使用定时器T1的模式1
	TH1=(65536-46083)/256; //定时器T1的高8位赋初值
	TL1=(65536-46083)%256; //定时器T1的高8位赋初值
	TR1=1;                 //启动定时器T1
	Countor1=0;            //从0开始累计中断次数
	Countor2=0;            //从0开始累计中断次数 
	while(1);
}

// 定时器1
void Time1(void) interrupt 3 using 0 
{
    Countor1++;   //Countor1自加1
	Countor2++;   //Countor2自加1
	if(Countor1==2)  //若累计满2次,即计时满100ms
	{
		D1=~D1;     //按位取反操作,将P2.0引脚输出电平取反
	    Countor1=0;  //将Countor1清0,重新从0开始计数
	}
	if(Countor2==8)  //若累计满8次,即计时满400ms
	{
	   D2=~D2;     //按位取反操作,将P2.1引脚输出电平取反
	   Countor2=0;  //将Countor1清0,重新从0开始计数
	}		
  	TH1=(65536-46083)/256; //定时器T1的高8位重新赋初值
	TL1=(65536-46083)%256; //定时器T1的高8位重新赋初值
}

实例 6:输出50个矩形脉冲

#include<reg51.h>   //包含51单片机寄存器定义的头文件

sbit u=P1^4;    //将u位定义为P1.4

/*************************************************
函数功能:延时约30ms (3*100*100=30 000μs =30m
*************************************************/
void delay30ms(void)
{ 
    unsigned char m,n;
 for(m=0;m<100;m++)
     for(n=0;n<100;n++);
}

void main(void)
{
    unsigned char i;
    u=1;    //初始化输出高电平
    for(i=0;i<50;i++) //输出50个矩形脉冲
    { 
        u=1;
     delay30ms();
     u=0;
     delay30ms(); 
    }
    while(1) :
} 

实例 7:计数器T0统计外部脉冲数

#include<reg51.h>   //包含51单片机寄存器定义的头文件

void main(void)
  {
 	  TMOD=0x06;    // TMOD=0000 0110B,使用计数器T0的模式2
     EA=1;         //开总中断
	  ET0=0;        //不使用定时器T0的中断     
	  TR0=1;        //启动T0
	  TH0=0;       //计数器T0高8位赋初值
	  TL0=0;       //计数器T0低8位赋初值
	  while(1)  //无限循环,不停地将TL0计数结果送P1口
     P1=TL0;		
}

实例 8:定时器T0的模式2测量正脉冲宽度

#include<reg51.h>   //包含51单片机寄存器定义的头文件

sbit ui=P3^2;  //将ui位定义为P3.0(INT0)引脚,表示输入电压

void main(void)
{
    TMOD=0x0a;   // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1
    EA=1;         //开总中断
    ET0=0;        //不使用定时器T0的中断     
    TR0=1;        //启动T0
    TH0=0;        //计数器T0高8位赋初值
    TL0=0;        //计数器T0低8位赋初值
    while(1)       //无限循环,不停地将TL0计数结果送P1口
    {
        while(ui==0) : //INT0为低电平,T0不能启动
        TL0=0;       //INT0为高电平,启动T0计时,所以将TL0清0
        while(ui==1): //在INT0高电平期间,等待,计时
        P1=TL0;    //将计时结果送P1口显示		
    } 
}

实例 9:输出负脉宽为200微秒的方波

#include<reg51.h>   //包含51单片机寄存器定义的头文件

sbit u=P1^4;    //将u位定义为P1.4

void main(void)
  {
   TMOD=0x02;            //TMOD=0000 0010B,使用定时器T0的模式2
   EA=1;                    //开总中断
	ET0=1;                  //定时器T0中断允许         
	TH0=256-200;   //定时器T0的高8位赋初值
	TL0=256-200;  //定时器T0的高8位赋初值
	TR0=1;                 //启动定时器T0
	while(1) : 
}             //无限循环,等待中断
void Time0(void) interrupt 1 using 0 //"interrupt"声明函数为中断服务函数
{
    u=~u;  //将P1.4引脚输出电平取反,产生方波
}

实例 10:测量负脉冲宽度

#include<reg51.h>   //包含51单片机寄存器定义的头文件

sbit u=P3^2;    //将u位定义为P3.2

void main(void)
{
    TMOD=0x02;  //TMOD=0000 0010B,使用定时器T0的模式2
    EA=1;   //开放总中断
    EX0=1;  //允许使用外中断
    IT0=1;  //选择负跳变来触发外中断
    ET0=1;  //允许定时器T0中断
    TH0=0;  //定时器T0赋初值0
    TL0=0;   //定时器T0赋初值0
    TR0=0;   //先关闭T0
    while(1)    ; //无限循环, 不停检测输入负脉冲宽度
}

void int0(void) interrupt 0 using 0 //外中断0的中断编号为0
{   
    TR0=1;   //外中断一到来,即启动T0计时
    TL0=0;  //从0开始计时
    while(u==0)  //低电平时,等待T0计时
        ;
    P1=TL0; //将结果送P1口显示
    TR0=0;  //关闭T0
}

实例 11:方式0控制流水灯循环点亮

#include<reg51.h>   //包含51单片机寄存器定义的头文件
#include<intrins.h> //包含函数_nop_()定义的头文件

unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码,该数组被定义为全局变量
sbit P17=P1^7;

/**************************************************************
函数功能:延时约150ms
**************************************************************/
void delay(void)   
{
    unsigned char m,n;
    for(m=0;m<200;m++)
        for(n=0;n<250;n++);    
}

/**************************************************************
函数功能:发送一个字节的数据
**************************************************************/
void Send(unsigned char dat)
{
    P17=0;     //P1.7引脚输出清0信号,对74LS164清0
    _nop_();   //延时一个机器周期
    _nop_();  //延时一个机器周期,保证清0完成
    P17=1;    //结束对74LS164的清0
    SBUF=dat;  //将数据写入发送缓冲器,启动发送
    while(TI==0)  //若没有发送完毕,等待
        ;
    TI=0;   //发送完毕,TI被置“1”,需将其清0
}

/*******************************************
函数功能:主函数
******************************************/	
void main(void)
{
    unsigned char i;
    SCON=0x00;  //SCON=0000 0000B,使串行口工作于方式0   
    while(1)  
    {
        for(i=0;i<8;i++)
        {
            Send(Tab[i]);  //发送数据
            delay();       //延时
        }
    }
}
51单片机中,串口中断函数可以用来接收字符串。下面是一个简单的例子: ```c #include <reg52.h> #define FOSC 11059200L #define BAUD 9600 #define TIMER_1MS (65536-FOSC/12/1000) // 1ms定时器初值 typedef unsigned char BYTE; typedef unsigned int WORD; sbit LED = P1^0; BYTE RxBuf[11]; // 用于存放接收到的字符串 BYTE RxCount = 0; // 接收计数器 void InitUart(void); void SendByte(BYTE dat); void SendString(char *s); void main() { InitUart(); // 初始化串口 TMOD |= 0x10; // 设置定时器1为定时器模式 TH1 = TL1 = TIMER_1MS; // 定时1ms TR1 = 1; // 启动定时器1 EA = ET1 = ES = 1; // 开启总中断、定时器1中断和串口中断 while(1); } void InitUart(void) { PCON |= 0x80; SCON = 0x50; TMOD &= 0x0F; TMOD |= 0x20; TH1 = TL1 = -(FOSC/12/32/BAUD); TR1 = 1; } void SendByte(BYTE dat) { SBUF = dat; while(!TI); TI = 0; } void SendString(char *s) { while(*s) { SendByte(*s++); } } void Uart_Isr() interrupt 4 { if(RI) { RI = 0; RxBuf[RxCount] = SBUF; if(RxBuf[RxCount] == '\r') { RxBuf[RxCount] = '\0'; // 字符串结束符 RxCount = 0; // 接收计数器清零 SendString(RxBuf); // 回显接收到的字符串 SendString("\r\n"); if(RxBuf[0] == '1') // 如果接收到的字符串是“1”,则点亮LED { LED = 0; } else if(RxBuf[0] == '0') // 如果接收到的字符串是“0”,则熄灭LED { LED = 1; } } else { RxCount++; if(RxCount >= 10) // 如果接收到的字符串长度超过10,则清零接收计数器 { RxCount = 0; } } } } void Timer1_Isr() interrupt 3 { TH1 = TL1 = TIMER_1MS; } ``` 上述代码中,串口中断函数 `Uart_Isr()` 判断接收到的字符是否为回车符 `\r`,如果是,则将接收到的字符串存入 `RxBuf` 数组中,并在串口回显接收到的字符串。同时,根据接收到的字符串内容控制LED的状态。需要注意的是,接收到的字符串长度不能超过 `RxBuf` 数组的长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行走的皮卡丘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值