佛大深夜学习 2023-02-04 14:55 采纳率: 60%
浏览 37
已结题

51单片机 串口中断 定时器中断

芯片型号:STC89C52RC
问题描述:我同时使用串口中断和定时器0中断时,如果写没有定时器0的中断服务函数,也会影响串口中断接受不正常
我的想法与疑问:按理来说串口中断使用的是定时器1提供时钟信号,应该与定时器1你没有关系
具体代码

#include <STC89C5xRC.H>
#define u8 unsigned char
#define u16 unsigned int    
//数码管段码表
code unsigned char SEG_Table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};

u8 r_sign;
u8 r_data;
void Serial_Init();
void Timer0_Init(u16 time);
void main()
{
    Timer0_Init(1000);//1ms
    Serial_Init();
    while(1)
    {
        if(r_sign == 1)
        {
            r_sign = 0;
            SBUF = r_data;
            while(TI == 0);
            TI = 0;
        }
    }
}

/*********串口***************/
/*
    初始化串口
*/
void Serial_Init()
{
    /*开启定时器1*/
    //8位自动重装载定时器
    TMOD |= 0x20;
    //定时器初值
    TH1 = 0xfa;
    TL1 = TH1;
    /*开启串口*/
    //方式1
    SM0 = 0;
    SM1 = 1;
    //允许串行接受
    REN = 1;
    //波特率加倍
    PCON |= 0x80;
    //开启中断
    ES = 1;
    EA = 1;
    //开启定时器
    TR1 = 1;
}

void Serial_IT() interrupt 4
{
    if(RI == 1)
    {
        RI = 0;
        r_sign = 1;
        r_data = SBUF;
    }
}

/**************数码管****************/
/*
    将字符串转化成数码管代码
*/
void SEG_TSL(u8 *input,u8 *output)
{
    u8 i=0,j=0;
    for(i=0;i<8;i++,j++)
    {
        switch(input[j])
        {
            case '0':output[i] = SEG_Table[0];break;
            case '1':output[i] = SEG_Table[1];break;
            case '2':output[i] = SEG_Table[2];break;
            case '3':output[i] = SEG_Table[3];break;
            case '4':output[i] = SEG_Table[4];break;
            case '5':output[i] = SEG_Table[5];break;
            case '6':output[i] = SEG_Table[6];break;
            case '7':output[i] = SEG_Table[7];break;
            case '8':output[i] = SEG_Table[8];break;
            case '9':output[i] = SEG_Table[9];break;
            case '-':output[i] = 0x40;break;
            case ' ':output[i] = 0x00;break;
            default:output[i] = 0x00;
        }
        if(input[j+1] == '.')
        {
            output[i] |= 0x80;
            j++;
        }
    }
}

void SEG_Show(u8 COD,u8 PSI)
{
    //消影
    P0 = 0x00;
    //位选
    P2 = P2 & (0xf8<<2) | (PSI<<2);
    //段选
    P0 = COD;
}

/**********定时器*****************/
void Timer0_Init(u16 time)
{
    //16位定时器
    TMOD |= 0x01;
    //定时器初值
    TH0 = (65536-time)/256;
    TL0 = (65536-time)%256;
  //开启定时器
    TR0 = 1;
    //开启中断
    ET0 = 1;
    EA = 1;
}

//void Timer0_IT() interrupt 1
//{
//    
//}

  • 写回答

2条回答 默认 最新

  • qllaoda 2023-02-04 15:04
    关注

    你开启了定时器0的中断,但不写中断定时0的服务程序,定时器0发生中断的时候就飞了,当然就不正常了。要想正常,你应该连定时器0的初始化也不写。

    另外,中断里改变的全局变量,声明的时候加上volatile

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 2月13日
  • 已采纳回答 2月5日
  • 创建了问题 2月4日

悬赏问题

  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵
  • ¥15 cfx离心泵非稳态计算