打印

求助 求助STM32中断优先级的问题

[复制链接]
578|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang575724771|  楼主 | 2017-6-26 17:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
串口中断和RTC定时器只设置了抢占优先级,且抢占优先级相同,当两个中断同时到来时会发生什么情况?现在出现个这样的情况,硬件上用ADM2483串口转485,用RTC定时1MS中断来处理串口数据,设备运行某段时间后会出现ADM2483的读写控制引脚一直会拉高成为写的状态(读写引脚电平是在串口数据读写中是改变的)这种现象是不是中断优先级相同造成的啊!!!!

相关帖子

沙发
wang575724771|  楼主 | 2017-6-26 17:40 | 只看该作者
/***************************************************************************************************
* º¯ÊýÃû³Æ: RTC_IRQHandler()
* º¯Êý¹¦ÄÜ: RTCÈ«¾ÖÖжϷþÎñ³ÌÐò£¬RTC´¦ÓÚ×ÔÔËÐÐģʽ£¬¶¨Ê±Ê±¼äΪ1mS
* Èë¿Ú²ÎÊý: ÎÞ
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£º½¨ÒéÔÚ¸ÃÖжϺ¯ÊýÖжÁÈ¡RTC->CNTHºÍRTC->CNTLµÄÖµ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
void RTC_IRQHandler(void)
{
        OSIntEnter();
        RTC->CRL &= ~RTC_CRL_SECF;                                                                                // Çå³ýÃëÖжϱêÖ¾
        wdg_clr_cnt ++;                                                 // ¿´ÃŹ·Çå³ý¼ÆÊýÆ÷

#if __USART1_SETUP
        USART1_RTCheck();                                                                                                // USART1ͨÐŽÓÊÕÊý¾Ý´¦Àí
#endif

#if __USART2_SETUP
        USART2_RTCheck();                                                                                                // USART2ͨÐŽÓÊÕÊý¾Ý´¦Àí
#endif

#if __USART3_SETUP
        USART3_RTCheck();                                                                                                // USART3ͨÐŽÓÊÕÊý¾Ý´¦Àí
#endif

#if __USART4_SETUP
        USART4_RTCheck();                                                                                                // USART4ͨÐŽÓÊÕÊý¾Ý´¦Àí
#endif

#if __USART5_SETUP
        USART5_RTCheck();                                                                                                // USART5ͨÐŽÓÊÕÊý¾Ý´¦Àí
#endif

#if __VCOM1_SETUP
//--------------------------------------------------------------------------------------------------
//                                         ÓëVCOM1ͨÐŽÓÊÕÊý¾Ý´¦Àí
//--------------------------------------------------------------------------------------------------
        if(vcom1_com_flag  == COM_FLAG_RXD)
        {
                vcom1_timerout_cnt ++;
                if(vcom1_timerout_cnt >= 10)                                                                // 10mS×÷ΪͨÐŽáÊøʱ¼ä
                {
                        vcom1_com_flag  = COM_FLAG_IDLE;                                                // ×÷Ϊ´Ó»úÇåÁãͨÐÅ״̬
                        vcom1_timerout_cnt = 0;
                        VCOM1_DataCheck();                                                                                // ½ÓÊÕÊý¾Ý´¦Àí
                }
        }
        else
        {
                vcom1_timerout_cnt = 0;
        }
#endif
#if __USART2_SETUP
#if USART2_MASTER
/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_CmdLoad()
* º¯Êý¹¦ÄÜ: USART2ÃüÁî×°ÔØ
* Èë¿Ú²ÎÊý: *buf£º´ý·¢Ë͵ÄÃüÁî
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
void USART2_CmdLoad(uint8* buf)
{
        uint16 cnt,len;

        if(buf[0] > USART2_CMD_LEN - 2)                                                                        // ·ÀÖ¹»º³åÇøÒç³ö
        {
                buf[0] = USART2_CMD_LEN - 2;
        }

        len = buf[0] + 2;
        for(cnt = 0;cnt < len;cnt ++)                                                                        // ×°ÔØÊý¾Ý
        {
                usart2_cmd_buf[usart2_cmd_index][cnt] = buf[cnt];
        }

        usart2_cmd_index ++;                                                                                        // Ö¸ÏòÏÂÒ»ÌõÃüÁî´æ´¢Î»ÖÃ
        if(usart2_cmd_index >= USART2_CMD_NUM)
        {
                usart2_cmd_index = 0;
        }

        STM32_IrqDisable();
        usart2_cmd_num ++;                                                                                                // ´ý·¢ËÍÃüÁîÊý¸üÐÂ
        STM32_IrqEnable();
}

/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_CmdSend()
* º¯Êý¹¦ÄÜ: USART2ÃüÁî×°ÔØ
* Èë¿Ú²ÎÊý: ÎÞ
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
__inline void USART2_CmdSend(void)
{
        uint16 cnt;
/*
        if(usart2_cmd_num == 0)                                                                                                        // ÃüÁ³åÇøûÓÐÃüÁî·¢ËÍ
        {
                return;
        }
*/
        usart2_master_addr = usart2_cmd_buf[usart2_cmd_start][1];                                // É豸µØÖ·

        for(cnt = 0;cnt < usart2_cmd_buf[usart2_cmd_start][0];cnt ++)                        // ¶ÁÈ¡Ö÷»úͨÐÅÃüÁîÊý¾Ý
        {
                usart2_cur_buf[cnt] = usart2_cmd_buf[usart2_cmd_start][2 + cnt];
        }

        USART2_DataWrite(usart2_cur_buf,usart2_cmd_buf[usart2_cmd_start][0]);        // ·¢ËÍÃüÁîÊý¾Ý
}

#endif

/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_DataRead()
* º¯Êý¹¦ÄÜ: USART2½ÓÊÕÊý¾Ý¶ÁÈ¡
* Èë¿Ú²ÎÊý: *buf£º´ý±£´æµÄÊý¾Ý»º³åÇø
*                        len        £º¶ÁÈ¡µ½µÄÊý¾Ý³¤¶È
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
void USART2_DataRead(uint8* buf,uint16* len)
{
        uint16 cnt;

        for(cnt = 0;cnt < usart2_rxd_len;cnt ++)                                                // ¶ÁÈ¡½ÓÊÕ»º³åÇøµÄÊý¾Ý
        {
                buf[cnt] = usart2_rxd_buf[cnt];
        }

        if(cnt != usart2_rxd_len)                                                                                // ´¦Àí֮ǰÊý¾Ý¶ÁÈ¡ºó¿ÉÄÜÊÕµ½µÄÊý¾Ý
        {
                buf[cnt] = usart2_rxd_buf[cnt];
                cnt ++;
        }

        usart2_rxd_len  = 0;                                                                                        // ¶ÁÈ¡ºóµ±Ç°½ÓÊÕÊý¾Ý³¤¶ÈÇåÁã
        *len = cnt;
}

/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_DataWrite()
* º¯Êý¹¦ÄÜ: USART2Êý¾Ý·¢ËÍ
* Èë¿Ú²ÎÊý: *buf£º´ý·¢ËÍÊý¾Ý»º³åÇø
*                        len        £º·¢ËÍÊý¾Ý³¤¶È
* ³ö¿Ú²ÎÊý: 0£º·¢ËÍʧ°Ü£»1£º·¢Ëͳɹ¦
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
uint8 USART2_DataWrite(uint8* buf,uint16 len)
{
        uint16 cnt;

        if(usart2_com_flag != COM_FLAG_IDLE)                                                        // ´®¿Ú²»¿ÕÏУ¬Ö±½Ó·µ»Ø0
        {
                //return 0;
        }

        USART2_CtrlPinSet(USART_TXD);                                                                         // ½ÓÊÕת·¢ËÍ
        usart2_com_flag  = COM_FLAG_TXD;                                                                 // ·¢ËÍ״̬
        usart2_txd_total = len;
        usart2_txd_len          = 0;

        for(cnt = 0;cnt < len;cnt ++)                                                                        // Êý¾Ý¸´ÖƵ½·¢ËÍ»º³åÇø
        {
                usart2_txd_buf[cnt] = buf[cnt];
        }

        //USART2->CR1 &= ~USART_CR1_RE;                                                                        // ½ÓÊÕ½ûÖ¹
        USART2->SR;                                                                                                                // Çå³ýTC±êÖ¾
        USART2->DR          = usart2_txd_buf[usart2_txd_len];                                        // ·¢Ë͵ÚÒ»¸öÊý¾Ý
        USART2->CR1 |= USART_CR1_TCIE;                                                                        // ·¢ËÍÍê³ÉÖжÏʹÄÜ

        return 1;
}

/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_RTCheck()
* º¯Êý¹¦ÄÜ: USART2¾ßÌåÊÕ·¢´¦Àí
* Èë¿Ú²ÎÊý: ÎÞ
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
__inline void USART2_RTCheck(void)
{
/*
#if USART2_MASTER
        usart2_master_cnt ++;
        if(usart2_master_cnt >= USART2_POLL_TIME)
        {
                usart2_master_cnt = 0;
                if((usart2_com_flag != COM_FLAG_IDLE) && (usart2_master_addr != 0))        // ´Ó»úûÓзµ»ØÊý¾Ý
                {
                        usart2_com_flag = COM_FLAG_IDLE;
                        usart2_error_cnt ++;
                        if(usart2_error_cnt >= USART2_ERROR_NUM)                                // ¶à´Î·ÃÎʳö´í£¬ÉèÖÃͨÐÅ´íÎó±êÖ¾
                        {
                                usart2_error_cnt = 0;
                                usart2_master_flag[usart2_master_addr] = 1;
                        }
                        else
                        {
                                USART2_CmdSend();                                                                        // Æô¶¯Êý¾Ý·¢ËÍ
                        }
                }
                else
                {
                        usart2_error_cnt = 0;
                        usart2_master_flag[usart2_master_addr] = 0;
                }

                if(usart2_error_cnt == 0)                                                                        // ·ÃÎÊÏÂÒ»¸öÉ豸
                {
                        usart2_cmd_start ++;                                                                        // Ö¸ÏòÏÂÒ»ÌõÃüÁî´æ´¢Î»ÖÃ
                        if(usart2_cmd_start >= USART2_CMD_NUM)
                        {
                                usart2_cmd_start = 0;
                        }

                        if(usart2_cmd_num)
                        {
                                STM32_IrqDisable();
                                usart2_cmd_num --;                                                                        // ´ý·¢ËÍÃüÁîÊý¸üÐÂ
                                STM32_IrqEnable();
                               
                                USART2_CmdSend();                                                                        // Æô¶¯Êý¾Ý·¢ËÍ
                        }
                }
        }

#endif
*/
        if(usart2_com_flag  == COM_FLAG_RXD)
        {
                usart2_timerout_cnt ++;
                if(usart2_timerout_cnt >= USART2_TIMEOUT)                                        // 10mS×÷ΪͨÐŽáÊøʱ¼ä
                {
                        usart2_timerout_cnt = 0;
                        USART2_DataCheck();                                                                                // ½ÓÊÕÊý¾Ý´¦Àí
                }
        }
        else
        {
                usart2_timerout_cnt = 0;
        }
}

/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_IRQHandler()
* º¯Êý¹¦ÄÜ: USART2È«¾ÖÖжϷþÎñ³ÌÐò
* Èë¿Ú²ÎÊý: ÎÞ
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷£ºÎÞ
* ´´½¨ÈÕÆÚ: 2015Äê10ÔÂ23ÈÕ
***************************************************************************************************/
void USART2_IRQHandler(void)
{
    volatile uint32 iir;

        OSIntEnter();
//**************************************************************************************************
//                                         ½ÓÊÕÖжÏÊý¾Ý´¦Àí
//**************************************************************************************************
    iir = USART2->SR;
    if(iir & USART_SR_RXNE)                                                      // ¶ÁÊý¾Ý¼Ä´æÆ÷·Ç¿Õ
    {
            usart2_timerout_cnt = 0;
            usart2_com_flag  = COM_FLAG_RXD;

            if(usart2_rxd_len >= sizeof(usart2_rxd_buf))
        {
                usart2_rxd_len = 0;
        }
        usart2_rxd_buf[usart2_rxd_len] = USART2->DR;
        usart2_rxd_len ++;
    }
//**************************************************************************************************
//                                         ·¢ËÍÖжÏÊý¾Ý´¦Àí
//**************************************************************************************************
    else if(iir & USART_SR_TC)                                                                                 // ·¢ËÍÊý¾Ý¼Ä´æÆ÷¿Õ
    {
            usart2_timerout_cnt = 0;
        usart2_txd_len ++;

                if((usart2_txd_len < usart2_txd_total) && (usart2_txd_len < sizeof(usart2_txd_buf)))
                {
                        usart2_com_flag = COM_FLAG_TXD;
                    USART2->DR = usart2_txd_buf[usart2_txd_len];
                }
                else
                {
                #if (!USART2_MASTER)
                        usart2_com_flag = COM_FLAG_IDLE;
                #endif
                    usart2_txd_len  = 0;

                        USART2_CtrlPinSet(USART_RXD);                                // ½ÓÊÕ״̬
                    USART2->SR         &= ~USART_SR_TC;
                    USART2->CR1 |= USART_CR1_RE;
                }
    }
    OSIntExit();
}
#endif
#if __USART2_SETUP
/***************************************************************************************************
* º¯ÊýÃû³Æ: USART2_DataCheck()
* º¯Êý¹¦ÄÜ: Modbus-RTUЭÒéУÑé³ÌÐò£¬ÓëÊý¾Ý²É¼¯Æ÷ͨÐÅ
* Èë¿Ú²ÎÊý: ÎÞ
* ³ö¿Ú²ÎÊý: ÎÞ
* ʹÓÃ˵Ã÷: ×÷ΪÖ÷»úʱ£¬Èç¹ûͨÐÅÊý¾ÝÕýÈ·ÐèÒª½«Í¨ÐűêÖ¾ÉèÖÃΪCOM_FLAG_IDLE
* ´´½¨ÈÕÆÚ: 2014Äê02ÔÂ20ÈÕ
***************************************************************************************************/
void USART2_DataCheck(void)
{
        uint8  com_buf[200],broad_flag;
        uint16 com_len,cnt,temp_data,temp_addr,*com_ptr,*temp_ptr;

        usart2_com_flag  = COM_FLAG_IDLE;                                                                // Èç¹û×÷Ϊ´Ó»ú£¬Ê¹ÄܸÃÓï¾ä£¬·ñÔò½ûÖ¹
        USART2_DataRead(com_buf,&com_len);                                                                // ¶ÁÈ¡½ÓÊÕ»º³åÇøµÄÊý¾Ý

        if(com_len == 0)                                                                                                // ÅжÏÊý¾Ý³¤¶È
        {
                return;
        }

        if((com_buf[0] != disp.idu_com_addr) && (com_buf[0] != 0x00) && (com_buf[0] != 0xFF))        // ÅжϵØÖ·ÊÇ·ñÕýÈ·
        {
                return;
        }

        if((com_buf[0] == 0x00) || (com_buf[0] == 0xFF))                                // ÅжϹ㲥µØÖ·
        {
                broad_flag = 1;
        }
        else
        {
                broad_flag = 0;
        }

        if(CRC16(com_buf,com_len))                                                                                // ÅжÏУÑéÂëÊÇ·ñÕýÈ·
        {
                return;
        }

        //usart2_com_flag = COM_FLAG_IDLE;                                                                // ×÷ΪÖ÷»úʹÄܸÃÓï¾ä£¬·ñÔò½ûÖ¹
        temp_addr = ((uint16)com_buf[2] << 8) + com_buf[3];
        temp_data = ((uint16)com_buf[4] << 8) + com_buf[5];

        switch(com_buf[1])
        {
//**************************************************************************************************
//                                        Êý²ÉÆ÷¶ÁÈ¡¿ØÖÆ°å²ÎÊý£¬¼Ä´æÆ÷µØÖ·£º0 ~ 21
//**************************************************************************************************
                case 0x03:
                {
                        if(com_len != 8)
                        {
                                return;
                        }

                        if((temp_addr >= SAMP_RD_ADDR) && (temp_addr + temp_data <= SAMP_RD_ADDR + SAMP_RD_NUM))
                        {
                                com_ptr = (uint16*)&samp.indoor_temp + temp_addr - SAMP_RD_ADDR;
                        }
                        else
                        {
                                return;
                        }

                        com_buf[2] = temp_data << 1;
                        for(cnt = 0;cnt < temp_data;cnt ++)                                                // С¶Ë¸ñʽ£¬µÍ×Ö½ÚÔÚÇ°
                        {
                                com_buf[(cnt << 1) + 3] = com_ptr[cnt] >> 8;
                                com_buf[(cnt << 1) + 4] = com_ptr[cnt] & 0xFF;
                        }

                        temp_data = CRC16(com_buf,com_buf[2] + 3);                                // ¼ÆËãCRCУÑéÂë
                        com_buf[(cnt << 1) + 3] = temp_data >> 8;
                        com_buf[(cnt << 1) + 4] = temp_data & 0xFF;

                        USART2_DataWrite(com_buf,com_buf[2] + 5);                                // ·µ»ØÊý¾Ý

                        break;
                }

//**************************************************************************************************
//                                        Êý²ÉÆ÷дÈë¿ØÖÆ°å²ÎÊý£¬¼Ä´æÆ÷µØÖ·£º11 ~ 21
//**************************************************************************************************
                case 0x06:
                {
                        if(com_len != 8)
                        {
                                return;
                        }

                        if((temp_addr >= SAMP_WR_ADDR) && (temp_addr < SAMP_WR_ADDR + SAMP_WR_NUM))
                        {
                                com_ptr  = (uint16*)&samp.power_status + temp_addr - SAMP_WR_ADDR;
                                temp_ptr = (uint16*)&disp.power_status + temp_addr - SAMP_WR_ADDR;
                        }
                        else
                        {
                                return;
                        }

                        *com_ptr = temp_data;                                                                        // ¸üÐÂSAMP¶ÔÓ¦Êý¾Ý
                        if((temp_addr >= 11) && (temp_addr <= 16))                                // ÉèÖô洢±êÖ¾
                        {
                                *temp_ptr = temp_data + 0x8000;                                                // ¸üÐÂDISP¶ÔÓ¦Êý¾Ý
                        }

                        if(!broad_flag)                                                                                        // ¹ã²¥ÃüÁî²»·µ»Ø
                        {
                                CRC16Load(com_buf,6);
                                USART2_DataWrite(com_buf,8);
                        }

                        break;
                }

//**************************************************************************************************
//                                        Êý²ÉÆ÷дÈë¿ØÖÆ°å²ÎÊý£¬¼Ä´æÆ÷µØÖ·£º11 ~ 23
//**************************************************************************************************
                case 0x10:
                {
                        if(com_len != (temp_data * 2 + 9))
                        {
                                return;
                        }

                        if((temp_addr >= SAMP_WR_ADDR) && (temp_addr + temp_data <= SAMP_WR_ADDR + SAMP_WR_NUM))
                        {
                                com_ptr  = (uint16*)&samp.power_status + temp_addr - SAMP_WR_ADDR;
                                temp_ptr = (uint16*)&disp.power_status + temp_addr - SAMP_WR_ADDR;
                        }
                        else
                        {
                                return;
                        }

                        for(cnt = 0;cnt < temp_data;cnt ++)
                        {
                                com_ptr[cnt] = ((uint16)com_buf[7 + cnt * 2] << 8) + com_buf[8 + cnt * 2];        // ¸üÐÂSAMPÇøÓòÊý¾Ý

                                if(temp_addr + cnt < SAMP_WR_ADDR + 6)                                // ¸üÐÂDISPÇøÓòÊý¾Ý
                                {
                                        temp_ptr[cnt] = com_ptr[cnt] + 0x8000;
                                }
                        }

                        if(!broad_flag)                                                                                        // ¹ã²¥ÃüÁî²»·µ»Ø
                        {
                                CRC16Load(com_buf,6);
                                USART2_DataWrite(com_buf,8);
                        }

                        break;
                }

                default:break;
        }
}
#endif

使用特权

评论回复
板凳
airwill| | 2017-6-27 07:39 | 只看该作者
如果是相同的抢占优先级, 如果有一个正在中断服务, 那么另外的中断到来时, 得等前面那个中断服务退出后才会进入后来中断的服务.  所谓咬尾方式.

你的 RTC 里在处理 UART 的状态, 相同的优先级可能不太合适

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

17

帖子

0

粉丝