打印
[STM32F3]

外部中断对串口中断接受数据的影响

[复制链接]
3216|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
辛楠不菲|  楼主 | 2015-5-22 10:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大侠,最近我在尝试着编写STM32F103C8T6的中断和串口的程序,两个外部中断用来接受外部的信息,也就是用外部中断来采集序列号,而一个串口1(通过IO映射到PB6--PB7)通过发送字符命令到PC,然后PC返回一个固定的字符串序列号 (串口1通过中断接受序列号),但是当其中一个外部中断有中断时,偶尔会出现串口接受数据错误的现象,但是另外一个中断却不会影响串口接受的数据,这是为什么?函数介绍:
中断初始化以及优先级函数定义:
static void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        //
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //in group_2 style,Preemption and Sub no larger than 3
        //
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        //
        NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

}


中断线定义:
static void EXTILine_Configulation(void)
{       
        EXTI_InitTypeDef EXTI_InitStructure;      
       
        GPIO_EXTILineConfig(WG1D0_PortSource, WG1D0_PinSource);  
        EXTI_ClearITPendingBit(EXTI_WG1D0);   
        EXTI_InitStructure.EXTI_Line = EXTI_WG1D0;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);     
        //EXTI_GenerateSWInterrupt(EXTI_WG1D0);

        GPIO_EXTILineConfig(WG1D1_PortSource, WG1D1_PinSource);
        EXTI_ClearITPendingBit(EXTI_WG1D1);
        EXTI_InitStructure.EXTI_Line = EXTI_WG1D1;
        EXTI_Init(&EXTI_InitStructure);
        //EXTI_GenerateSWInterrupt(EXTI_WG1D1);

        GPIO_EXTILineConfig(WG2D0_PortSource, WG2D0_PinSource);
        EXTI_ClearITPendingBit(EXTI_WG2D0);
        EXTI_InitStructure.EXTI_Line = EXTI_WG2D0;
        EXTI_Init(&EXTI_InitStructure);
        //EXTI_GenerateSWInterrupt(EXTI_WG2D0);

        GPIO_EXTILineConfig(WG2D1_PortSource, WG2D1_PinSource);
        EXTI_ClearITPendingBit(EXTI_WG2D1);
        EXTI_InitStructure.EXTI_Line = EXTI_WG2D1;
        EXTI_Init(&EXTI_InitStructure);
        //EXTI_GenerateSWInterrupt(EXTI_WG2D1);
}


串口函数定义:
void COM_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

       
        RCC_APB2PeriphClockCmd(COM1M_GPIO_RCC | COM2S_GPIO_RCC | RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB2PeriphClockCmd(COM1M_RCC, ENABLE);
        RCC_APB1PeriphClockCmd(COM2S_RCC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

        // -通讯端口- //
        // 内部通讯端口1(母版和子板通讯端口)
        GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE); // USART1 重映射
        GPIO_InitStructure.GPIO_Pin = COM1M_TX_PIN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(COM1M_PORT, &GPIO_InitStructure);       
        GPIO_InitStructure.GPIO_Pin = COM1M_RX_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(COM1M_PORT, &GPIO_InitStructure);


        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
        USART_Init(COM1M, &USART_InitStructure);       
        // Enable the USART1 Receive Interrupt
        USART_ITConfig(COM1M, USART_IT_RXNE, ENABLE);       
        USART_Cmd(COM1M, ENABLE);



        NVIC_InitStructure.NVIC_IRQChannel = COM1M_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}


串口1中断接受函数:
void COM1M_IRQHandler(void)
{
        if(USART_GetITStatus(COM1M, USART_IT_RXNE) != RESET)
        {                               
                if(Com1mRxIdx == 0)
                {
                        ComStatus |= 0x01;
                        ComStatus &= 0xFD;
                //        TIM_ClearFlag(TIM2, TIM_FLAG_Update);
                //        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //启动COM1M超时定时器TIM2
                }
        //        TIM_SetCounter(TIM2, 0);// 重置定时器初值
                Com1mRxBuf[Com1mRxIdx++] = USART_ReceiveData(COM1M);
                if(Com1mRxIdx>=50)
                {
                        Com1mRxIdx = 0;
                }               
                COM1M_TimeCnt = 0;
                Flag=0x00;               
                /*if(Com1mRxIdx==Com1mRxBuf[2]+5)
                {
                        Flag=0x00;
                }*/
        }
}


外部中断1接受函数
void EXTI15_10_IRQHandler(void)
{       
        if(WG1RxIdx        ==        0)
        {
                WeiGenFlag        |= 0x01;
                WeiGenFlag        &= 0xFD;       
        }
       
        if(EXTI_GetITStatus(EXTI_Line10) != RESET )
        {
                WeiGen1Buf[WG1RxIdx] = 0x00;
                WG1RxIdx++;
                EXTI_ClearITPendingBit(EXTI_Line10);        //清除中断标志
        }
        if(EXTI_GetITStatus(EXTI_Line11) != RESET )
        {
                WeiGen1Buf[WG1RxIdx] = 0x01;
                WG1RxIdx++;
                EXTI_ClearITPendingBit(EXTI_Line11);  //清楚中断标志                       
        }
        WG1_TimeCnt = 0;
}


外部中断2接受函数
void EXTI9_5_IRQHandler(void)
{
        if(WG2RxIdx        ==        0)
        {
                WeiGenFlag        |= 0x04;
                WeiGenFlag        &= 0xF7;       
        }

        if(EXTI_GetITStatus(EXTI_Line8) != RESET)
        {
                WeiGen2Buf[WG2RxIdx] = 0x00;
                WG2RxIdx++;
                EXTI_ClearITPendingBit(EXTI_Line8);        //清除中断标志
        }
        if(EXTI_GetITStatus(EXTI_Line9) != RESET)
        {
                WeiGen2Buf[WG2RxIdx] = 0x01;
                WG2RxIdx++;
                EXTI_ClearITPendingBit(EXTI_Line9);        //清除中断标志
        }
        WG2_TimeCnt = 0;
}


当然还有其他的定时器定义,这里没给出

请各位大侠解答,谢谢大家!!!!!


沙发
s_f_tan| | 2015-5-22 15:36 | 只看该作者
看是不是中断优先等级不对,外部触发的等级太高了,导致串口的被耽搁了,几个数据来而只相应其中一个了

使用特权

评论回复
板凳
309030106| | 2015-5-22 17:40 | 只看该作者
两个中断的话,需要中断嵌套

使用特权

评论回复
地板
airwill| | 2015-5-24 11:05 | 只看该作者
我怀疑的问题不在中断上, 而是在 IO 口设置上。
借助调试器到运行中验证一下 AFIO 的配置是否正确。

使用特权

评论回复
5
辛楠不菲|  楼主 | 2015-5-25 09:07 | 只看该作者
s_f_tan 发表于 2015-5-22 15:36
看是不是中断优先等级不对,外部触发的等级太高了,导致串口的被耽搁了,几个数据来而只相应其中一个了 ...

谢谢,这个我也是优先考虑的问题,可经过测试,可以排除这个方案了,因为两个中断程序起始是一样的,只是优先级不同,我修改他们的优先级以及其他串口定时器的优先级,问题也还没有解决!

使用特权

评论回复
6
辛楠不菲|  楼主 | 2015-5-25 09:08 | 只看该作者
309030106 发表于 2015-5-22 17:40
两个中断的话,需要中断嵌套

谢谢,你是说还有设置不同抢占优先级吗?

使用特权

评论回复
7
辛楠不菲|  楼主 | 2015-5-25 09:17 | 只看该作者
airwill 发表于 2015-5-24 11:05
我怀疑的问题不在中断上, 而是在 IO 口设置上。
借助调试器到运行中验证一下 AFIO 的配置是否正确。 ...

谢谢,这个我也考虑过,因为串口是通过映射到B6-7的,而且也开启的时钟先,而串口原来的复用功能是用来做串口是,现在串口被映射到其他地方了,现在其只是普通的IO用来做中断使用。因为在排除问题的过程中,我也将映射取消,采用原来的端口的复用功能(原串口PA9-10),然后将其中哪个有问题的中断端口转移到其他的IO口上,可还是没有解决问题!

使用特权

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

本版积分规则

5

主题

16

帖子

1

粉丝