51单片机外部中断使用求助

2020-01-24 11:57发布

大家好
   本人近期在把玩51单片机,在工程里实现一些简单的功能,用到了定时器0中断,串口中断以及外部中断0和外部中断1,现在将详细解释一下:
(问题;在外没有触发外部中断0或者是外部中断1时,串口通信正常,但是当外部一旦触发了外部中断0或者是外部中断1的操作时,串口通信就不正常了,我用串口调试助手发送数据,没有返回。请问各位大神,这个问题出现在哪了?)
   定时器0:用于定时刷新数码管显示,并作1秒计数加1后放在数码管上显示;
   串口中断:用于和外部通信,
   外部中断0:触发方式为低电平,检测到低电平信号时,打开蜂鸣器;
   外部中断1:触发方式为低电平,检测到低电平信号时,关闭蜂鸣器;
   //main.c
#include <reg51.h>
#include "uart.h"
#include "delay.h"
#include "crc.h"
sbit LED_G1 = P2^0;
sbit LED_G2 = P2^1;
sbit LED_G3 = P2^2;
sbit LED_G4 = P2^3;
sbit LED_G5 = P2^4;
sbit LED_G6 = P2^5;
sbit LED_G7 = P2^6;
sbit LED_G8 = P2^7;
sbit SPK    = P1^4;
sbit SMG1 = P1^0;
sbit SMG2 = P1^1;
sbit SMG3 = P1^2;
sbit SMG4 = P1^3;
//共阳段码编码表0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F(本程序中用共阳)
unsigned char code SMG_TabV[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};  
//共阴段码编码表0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F
unsigned char code SMG_TabG[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char qian,bai,shi,ge;
unsigned int  smg_count;
unsigned int t0_count;
unsigned char next_c;
extern unsigned char rx_buf[20];
extern unsigned char rx_count;
unsigned char tx_buf[20]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

void timer0_init(void);
void SMG_data(void);
void exit_int01_init(void);
int main()
{
        timer0_init();
        exit_int01_init();
        uart_init();
        EA = 1;//开全局总中断         
        while(1)
        {                 
                 if((rx_buf[0]==2)&&(usMBCRC16(rx_buf,rx_count)==0))
                 {
                         tx_buf[8] = rx_count;
                        data8_send(tx_buf,9);
                        rx_buf[0] = 0;
                        rx_count  = 0;
                 }
        }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//定时器0中断入口函数
void timer0_isr(void) interrupt 1 using 1
{
         t0_count++;
         next_c++;
         TH0  = 0XF8; //定时2ms,装置数据高8位
         TL0  = 0X30; //定时2ms,装置数据低8位
         if(next_c == 1)
         {
                  SMG_data();
                 P0 = SMG_TabV[qian];
                 SMG1 = 1;
                 SMG2 = 1;
                 SMG3 = 1;
                 SMG4 = 0;
         }
         else if(next_c == 2)
         {
                 SMG_data();
                 P0 = SMG_TabV[bai];
                 SMG1 = 1;
                 SMG2 = 1;
                 SMG3 = 0;
                 SMG4 = 1;
         }
         else if(next_c == 3)
         {
                 SMG_data();
                 P0 = SMG_TabV[shi];
                 SMG1 = 1;
                 SMG2 = 0;
                 SMG3 = 1;
                 SMG4 = 1;
         }
         else if(next_c == 4)
         {
                 SMG_data();
                 P0 = SMG_TabV[ge];       
                 SMG1 = 0;
                 SMG2 = 1;
                 SMG3 = 1;
                 SMG4 = 1;
         }
         if(next_c == 4)
         {
                 next_c = 0;
         }
}

//定时器0 实现10ms定时初始化
void timer0_init(void)
{
        TMOD = 0X01; //使能定时器0,工作方式1,16位计数
        TH0  = 0XF8; //定时2ms,装置数据高8位
        TL0  = 0X30; //定时2ms,装置数据低8位
        TR0  = 1;         //使能定时器0
        ET0  = 1;         //允许定时器0中断
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void exit_int01_init(void)
{
        EX0 = 1;//允许外部中断0开
    IT0 = 0;//电平触发方式,低电平有效,若为1,则为脉冲触发方式,下降沿有效

        EX1 = 1;//允许外部中断1开
    IT1 = 0;//电平触发方式,低电平有效,若为1,则为脉冲触发方式,下降沿有效
}

void int0_isr(void) interrupt 0 using 0
{
        IE0 = 0;
        SPK = 0;//打开蜂鸣器
}

void int1_isr(void) interrupt 2 using 1
{
        IE1 = 0;
        SPK = 1;//关闭蜂鸣器
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SMG_data(void)
{
        if(t0_count == 500)
        {
                t0_count = 0;
                LED_G1 = ~LED_G1;
                LED_G2 = ~LED_G2;
                LED_G3 = ~LED_G3;
                LED_G4 = ~LED_G4;
                LED_G5 = ~LED_G5;
                LED_G6 = ~LED_G6;
                LED_G7 = ~LED_G7;
                LED_G8 = ~LED_G8;
                //数码管显示计数,1秒累加一次
                smg_count++;
                ge   = smg_count%10;
                shi  = (smg_count/10)%10;
                bai  = (smg_count/100)%10;
                qian = smg_count/1000;
        }
}

以下部分为串口中断//////////////////////////////////////////////////////////////////////////////////////////
unsigned char rx_buf[20]={0};
unsigned char rx_count=0;

void uart_init(void)
{
        SCON  = 0X50;//8位UART,波特率可变
        TMOD |= 0X20;//定时器1工作方式2,产生9600 baudrate
        TH1   = 0XFD;//装置波特率参数
        TR1   = 1;         //使能定时器1工作
        ES    = 1;   //便能串口中断         
}

void uart_isr() interrupt 4 using 1
{
        if(RI == 1)                        //判断是接收中断产生
        {
                RI = 0;                        //标志位清零
                rx_buf[rx_count++] = SBUF;     //读缓冲区的值                  
        }
    if(TI == 1)                        //如果是发送标志位,清零
        {
                TI=0;
        }
}

void data8_send(unsigned char *tx_dat,unsigned char len)
{
        unsigned char i;
        for(i=0;i<len;i++)
        {
                SBUF = *(tx_dat+i);
                delay_ms(1);
        }
}
问题;
       在外没有触发外部中断0或者是外部中断1时,串口通信正常,但是当外部一旦触发了外部中断0或者是外部中断1的操作时,串口通信就不正常了,我用串口调试助手发送数据,没有返回。请问各位大神,这个问题出现在哪了?

      真的是非常感谢了哦。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
zyyn123
1楼-- · 2020-01-24 15:59
中断分级别的,外中断0最高,T0第二,外中断1第三,T1第四,串口中断最低。
NemoGu
2楼-- · 2020-01-24 17:55
外部中斷使用電平觸發方式,低電平維持時間有多久?
dongfengge555
3楼-- · 2020-01-24 19:59
 精彩回答 2  元偷偷看……
dongfengge555
4楼-- · 2020-01-24 21:06
zyyn123 发表于 2014-4-13 12:58
中断分级别的,外中断0最高,T0第二,外中断1第三,T1第四,串口中断最低。 ...

恩是的,分了级别的。呵呵
ourAVR_m16
5楼-- · 2020-01-25 02:27
建议设置中断优先级管理寄存器IP,将串行口中断优先级设置为最高后观察效果

一周热门 更多>