[资料分享] 单片机编程_中断

fish001   2019-6-7 09:26 楼主

单片机三种中断 
1.外部中断 
2.定时中断 
3.串行口中断 
中断概念:CPU暂停当前工作A,转去处理其他工作B,处理完毕再回到中断处继续工作A。

52单片机中断优先级

中断源    序号(C语言用)
INT0    外部中断0
T0    定时器/计数器0中断
INT1    外部中断1
T1    定时器/计数器1中断
T1/RI    串行口中断
T2    定时器/计数器2中断
C51的中断函数格式

void 函数名() interrupt 中断号 using 工作组
{
    //中断服务程序内容
}

void T1_time() interrupt 3
{
    TH1 = (65536-10000)/256;
    TL1 = (65536-10000)%256;
}

外部中断程序示例 
使用数码管显示学号,按键中断显示,执行中断函数,让LED灯亮。

#include   <reg52.h>
#include <intrins.h>

#define  uchar unsigned  char
#define  uint  unsigned  int
sbit dula=P2^6;
sbit wela=P2^7;
sbit s20=P3^7;

uchar a = 0xfe;

uchar code table[]={
 0x3f, 0x4f, 0x3f, 0x5b, 0x3f, 0x7d,
 };

void delayms(uint ms)
{
 uint i,j;
    for(i=ms;i>0;i--)
        for(j=110;j>0;j--);
}
void display();
void LED();
void zhongduan();


void main()
{
    EA = 1;
    EX0 = 1;
    while(1)
    {
        display();  //数码管显示
     }

}

void zhongduan() interrupt 0  //外部中断0
{
    while(s20 == 0)
    {
        P1 = a;                 
        a=_cror_(a,1);
        delayms(200);
    }
}

void  LED()
{
    P1 = a;
    a=_crol_(a,1);
}

void display()
{
    int i = 0;
    wela=1;
    P0=0xc0;
    wela=0;

    for( i = 0; i < 6; i++)
    {
        dula=1;
        P0=table[i];
        dula=0;
        P0=0xff;
         P1 = a;                    
        a=_crol_(a,1);
        delayms(200);
    }
}

定时器中断 
数码管显示倒计时,流水灯每秒灭亮,60秒倒计时结束,蜂鸣器响

#include<reg52.h>
// #include<intrins.h>

 #define uchar unsigned char
 #define uint unsigned int

 sbit dula = P2^6;
 sbit wela = P2^7;

 sbit didi = P2^3;

 sbit LED_A = P1^0;

unsigned char TIME_BASE;        //基础累加
unsigned char MACT_ENDB;        //可重置
unsigned char Rece_Errp;        //定时计数
//
// bit close;
//
 uchar code table[] = {
    0x3f,0x06,0x5b,0x4f,0x66,        //0~4
    0x6d,0x7d,0x07,0x7f,0x6f         //5~9
 };

 void delayms(uint ms)           //延时
 {
    uint i,j;
    for(i = ms; i > 0; i--)
    {
        for(j = 110; j>0; j--)
            ;
    }
}

// 定时器初始化
void SystemInit(void)
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;    // 定时50ms //晶振:11.0592MHZ
TL0 = (65536 - 45872) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}

void main()
{
    SystemInit();
    while(1)                         //60秒
    {

        if(Rece_Errp < 60)
        {
            wela = 1;
            P0 =  0xef;  //5
            wela = 0;
            dula = 1;
            P0 = table[5 - Rece_Errp/10];
            dula = 0;
            P0 = 0xff;
            delayms(1);

            wela = 1;
            P0 =  0xdf;  //6
            wela = 0;
            dula = 1;
            P0 = table[9 - Rece_Errp%10];
            dula = 0;
            P0 = 0xff;
            delayms(1);
        }
        else
        {
                    //替换成蜂鸣器

              while(1)
              {
                didi=~didi;
                LED_A = ~LED_A;
                delayms(500);
              }        //程序终止在此
        }
    }
}
void Timer0_IRQ(void) interrupt 1
{
TH0 = (655365 - 45872) / 256;
TL0 = (655365 - 45872) % 256;

// 进入中断50ms +1次
TIME_BASE++;
if(TIME_BASE == 20) //  20ms * 50ms = 刚好等于1000ms 也就是1秒
{
TIME_BASE = 0;
MACT_ENDB++;    // 一秒加一次
if(MACT_ENDB == 1) // 等于刚好1秒时间到
{
MACT_ENDB = 0;
Rece_Errp++; // 用来切换LED A、B、C5秒灭
}
}
}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复