串口最高中断优先级,串口中断调用持续大约4秒的播报函数时想执行定时器的中断,怎么解决

51单片机+SYN6288模块,串口被设置最高中断优先级,在串口中断中调用了个播报温度的程序,大概有5秒左右,我想在播报的时候继续定时器中断,这种怎么解决?
我想在调用时在中间延时那里关闭串口,但听说这样好像会锁死,能不能帮忙解决一下。

void TempSyn()//播报温度
{
    P0=0XFF;
    SYN_FrameInfo(0, "[v8][t5]当前温度是");
      Delay1000ms();
      Delay1000ms();
  switch(temp/10)
    {
        case 0:
            break;
        case 1:
            SYN_FrameInfo(0, "[v8][t5]十");
            break;        
        case 2:         
            SYN_FrameInfo(0, "[v8][t5]二十");Delay500ms();
            break;        
        case 3:         
            SYN_FrameInfo(0, "[v8][m0][t5]三十");Delay500ms();
            break;        
        case 4:         
            SYN_FrameInfo(0, "[v8][m0][t5]四十");Delay500ms();
            break;        
        case 5:         
            SYN_FrameInfo(0, "[v8][m0][t5]五十");Delay500ms();
            break;        
        case 6:         
            SYN_FrameInfo(0, "[v8][m0][t5]六十");Delay500ms();
            break;        
        case 7:         
            SYN_FrameInfo(0, "[v8][m0][t5]七十");Delay500ms();
            break;        
        default: break; 
    }                     
    Delay500ms();  
    switch(temp%10)     
    {                 
        case 0:         
            break;        
        case 1:         
            SYN_FrameInfo(0, "[v8][t5]一");
            break;        
        case 2:         
            SYN_FrameInfo(0, "[v8][t5]二");
            break;        
        case 3:         
            SYN_FrameInfo(0, "[v8][t5]三");
            break;        
        case 4:         
            SYN_FrameInfo(0, "[v8][t5]四");
            break;        
        case 5:         
            SYN_FrameInfo(0, "[v8][t5]五");
            break;        
        case 6:         
            SYN_FrameInfo(0, "[v8][t5]六");
            break;        
        case 7:         
            SYN_FrameInfo(0, "[v8][t5]七");
            break;
        case 8:
            SYN_FrameInfo(0, "[v8][t5]八");
            break;
        case 9:
            SYN_FrameInfo(0, "[v8][t5]九");
            break;
    }
    Delay500ms();
  SYN_FrameInfo(0, "[v8][t5]点");
    Delay500ms();
    switch(xs)     
    {                 
        case 0:
      SYN_FrameInfo(0, "[v8][t5]零");            
            break;        
        case 1:         
            SYN_FrameInfo(0, "[v8][t5]一");
            break;        
        case 2:         
            SYN_FrameInfo(0, "[v8][t5]二");
            break;        
        case 3:         
            SYN_FrameInfo(0, "[v8][t5]三");
            break;        
        case 4:         
            SYN_FrameInfo(0, "[v8][t5]四");
            break;        
        case 5:         
            SYN_FrameInfo(0, "[v8][t5]五");
            break;        
        case 6:         
            SYN_FrameInfo(0, "[v8][t5]六");
            break;        
        case 7:         
            SYN_FrameInfo(0, "[v8][t5]七");
            break;
        case 8:
            SYN_FrameInfo(0, "[v8][t5]八");
            break;
        case 9:
            SYN_FrameInfo(0, "[v8][t5]九");
            break;
    }
    Delay500ms();
    SYN_FrameInfo(0, "[v8][t5]度");
}

  • 以下回答由chatgpt基于相关博客总结生成:

    解决方案: 在串口中断中调用耗时操作会影响定时器中断的执行,可以采用开启另一个中断的方式来解决这个问题。

    具体步骤如下: 1. 在主程序中定义一个全局变量flag, 初始化为0。 2. 在定时器中断服务函数中加入如下代码:

    void timer_interrupt() {
        // 先处理定时器中断的代码
    
        if(flag == 0) {
            // 调用播报温度的函数
            // 在该函数中开启另一个定时器中断
            // 并将flag置为1,表示已经调用了播报温度的函数
        }
    }
    
    1. 在播报温度的函数中也开启定时器中断,并设置中断优先级较低,以便定时器中断能够持续执行。
    2. 在播报温度的函数执行完毕后,将flag置为0,表示已经执行完播报温度的操作。此时定时器中断会继续执行。

    总体思路是在定时器中断中判断是否已经执行了播报温度的函数,在第一次执行时调用播报温度的函数,并将flag置为1。在播报温度的函数中,开启定时器中断,并设置优先级较低。在函数执行完毕后,将flag置为0,表示已经执行完播报温度的操作。此时定时器中断会继续正常执行。

    代码示例:

    // 定义全局变量flag
    int flag = 0;
    
    void timer_interrupt() {
        // 先处理定时器中断的代码
    
        if(flag == 0) {
            // 调用播报温度的函数
            // 在该函数中开启另一个定时器中断
            // 并将flag置为1,表示已经调用了播报温度的函数
        }
    }
    
    void temperature_broadcast() {
        // 关闭主串口中断
        // 执行播报温度的操作
        // 开启另一个定时器中断,并设置优先级较低
        // 打开主串口中断
        flag = 0; // 将flag置为0,表示已经执行完播报温度的操作
    }