你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F030 串口 用IDLE中断 接收不定长度数据包,中断异常

[复制链接]
lps402 提问时间:2017-5-18 17:22 /
本帖最后由 lps402 于 2017-5-18 17:22 编辑

      如题,在使用IDLE中断接收不定长度的数据包,发现程序一直处于IDLE中断中。程序如下
串口配置程序
  1. void USART_Configuration(void)
  2. {
  3.   USART_InitTypeDef USART_InitStructure;
  4.   USART_InitStructure.USART_BaudRate = 9600;                       //设定波特率
  5.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;        //设定传输数据位
  6.   USART_InitStructure.USART_StopBits = USART_StopBits_1;             //设定停止位
  7.   USART_InitStructure.USART_Parity = USART_Parity_No ;               //不用校验位
  8.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不用流量控制
  9.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //使用接收发送功能
  10.   USART_Init(USART1, &USART_InitStructure);                          //初始化USART1

  11.   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                     //使能USART1 接收中断
  12.   USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);                     //使能USART1空闲中断

  13.   USART1->CR1=USART1->CR1&~(1<<4);                             //清除IDLE中断。特意加的,未添加时,上电后,设备一直处于IDLE中断,
  14.                                                                                                    无法执行主程序
  15.   USART_Cmd(USART1, ENABLE);                                            //使能USART1
  16. }
复制代码
中断程序
  1. void USART1_IRQHandler(void)
  2. {
  3. static uint8_t data[10]; //
  4. static uint8_t rxne_num; //
  5. if((USART1->ISR & USART_FLAG_RXNE) == USART_FLAG_RXNE)
  6. {
  7.    data[rxne_num]=USART_ReceiveData(USART1);
  8.    rxne_num=rxne_num+1;
  9.    if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)==SET)
  10.     {
  11.      USART1->CR1=USART1->CR1&~(1<<4); //清楚IDLE中断
  12.       rxne_num=0;
  13.      }
  14. }
复制代码
主程序
  1. int main(void)
  2. {
  3.   static uint8_t   data[10]={0,0,0,0,0,0,0,0,0,0}; //全局变量,接收缓存数组
  4.   static uint8_t          rxne_num=0;                             //全局变量,接收缓存数组序号
  5.   System_Initializes();

  6.         USART1_Printf((uint8_t*)"系统启动");     //打印输出
  7.   while(1)
  8.   {
  9.     LED_STA_TOGGLE;                                  //LED变化
  10. TIMDelay_Nms(500);                           //延时500ms
  11.   }
  12. }
复制代码
         该程序在STM32F103上调试过(串口配置程序,未添加清楚IDLE中断标志位),没有问题,可以正常接收多个字节数据。
STM32F030:当串口调试工具,发送E1E2E3E4数据时,接收到第一个E1时,程序直接进入IDLE中断
  1. /*IDLE中断*/
  2. if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)==SET)
  3. {
  4. USART1->CR1=USART1->CR1&~(1<<4); //清除IDLE中断
  5. rxne_num=0;
  6. }
复制代码
STM32F103:当串口调试工具,发送E1E2E3E4数据时,接收到第四个字节E4时,程序直接才进入IDLE中断。

       请问各位,STM32F030的IDLE这样使用是否有问题?STM32F030的IDLE是否有问题?
收藏 1 评论9 发布时间:2017-5-18 17:22

举报

9个回答
lps402 回答时间:2017-5-18 17:32:35
补充说明
串口GPIO配置
  1. void USART_GPIO_Configuration(void)
  2. {
  3.   GPIO_InitTypeDef GPIO_InitStructure;

  4.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
  5.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

  6.   /* 定义USART TX/ RX引脚为复用输出 */
  7.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;            //引脚
  8.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                       //复用模式
  9.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  //高速
  10.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                     //推挽输出
  11.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                       //上拉
  12.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  13. }
复制代码
yyq006 回答时间:2017-9-7 09:27:18
楼主问题解决了没有,我也遇到这个问题了。
wanyisq 回答时间:2017-12-29 17:22:00
我也遇到这个问题了
JiNian_04 回答时间:2018-3-24 08:59:42
IDLE清标志位不是通过写CR寄存器,而是一个软件序列,先读SR,再读DR,这样才能清中断,可以看下手册上关于IDLE的介绍
sdtazzf 回答时间:2019-5-15 18:03:01
楼主:IDLE中断为什么一上电就IDLE中断中断一次啊?没有数据也搞一次,怎么解决啊?
edmundlee 回答时间:2019-5-15 18:25:27
if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)==SET)
{
USART1->CR1=USART1->CR1&~(1<<4); //清除IDLE中断
USART1->DR;
rxne_num=0;
}
要加红色这一句
浅色调123 回答时间:2019-6-18 08:57:42
sdtazzf 发表于 2019-5-15 18:03
楼主:IDLE中断为什么一上电就IDLE中断中断一次啊?没有数据也搞一次,怎么解决啊?
...

看我的回复
浅色调123 回答时间:2019-6-18 09:03:44
多年已过,楼主肯定解决了,但是一直没有说一下怎么解决的,我说一下吧附上f030的代码1、初始化千万不要初始化就打开IDLE中断
2、在串口接收中断中打开IDLE中断
3、正确清楚IDLE中断。

void USART1_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //使能GPIOA的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能USART的时钟
    /* USART1的端口配置 */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);//配置PA9成第二功能引脚        TX
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);//配置PA10成第二功能引脚  RX

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    /* USART1的基本配置 */
    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;

    /* USART1的NVIC中断配置 */
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 0x02;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);


    USART_Init(USART, &USART_InitStructure);
    USART_ITConfig(USART, USART_IT_RXNE, ENABLE);         //使能接收中断      
//    USART_ITConfig(USART,USART_IT_IDLE,ENABLE);           //初始化的时候千万不要打开IDLE中断   
    USART_Cmd(USART, ENABLE);                             //使能USART1
}

void USART1_IRQHandler(void)
{
    uint8_t Res;
    if(USART_GetITStatus(USART, USART_IT_RXNE) != RESET) {        //接收中断
        if(!(USART->CR1 & USART_CR1_IDLEIE)) {         
            USART_ITConfig(USART,USART_IT_IDLE,ENABLE);//当没有开启IDLE中断的时候再开,不然上电会进去一次
            USART_ClearFlag(USART, USART_FLAG_IDLE);
        }
        Res = USART_ReceiveData(USART);        //读取接收到的数据
    }
    if(USART_GetFlagStatus(USART,USART_FLAG_IDLE) == SET) //空闲中断
    {        
        USART_ClearFlag(USART, USART_FLAG_IDLE);
        USART->RDR;   
        USART_ITConfig(USART,USART_IT_IDLE,DISABLE);//不用的时候关闭串口空闲中断,防止意外进入
        }
    }


lingdingyang 回答时间:2020-6-9 15:15:41
浅色调123 发表于 2019-6-18 09:03
多年已过,楼主肯定解决了,但是一直没有说一下怎么解决的,我说一下吧附上f030的代码1、初始化千万不要初 ...

——“多年已过,楼主肯定解决了”,其实也不一定,也可能是没解决,但是楼主已经死了,所以帖子才一直晾在这里。。。

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版