搜索
查看: 10693|回复: 9

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

[复制链接]

该用户从未签到

1

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2018-11-19
发表于 2017-5-18 17:22:01 | 显示全部楼层 |阅读模式
本帖最后由 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

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2018-11-19
 楼主| 发表于 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. }
复制代码
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

45

帖子

0

蝴蝶豆

高级会员

最后登录
2018-6-27
发表于 2017-9-7 09:27:18 | 显示全部楼层
楼主问题解决了没有,我也遇到这个问题了。
回复 支持 反对

使用道具 举报

该用户从未签到

30

主题

579

帖子

12

蝴蝶豆

金牌会员

最后登录
2020-3-22
发表于 2017-12-29 17:22:00 | 显示全部楼层
我也遇到这个问题了
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

3

帖子

0

蝴蝶豆

初级会员

最后登录
2018-3-24
发表于 2018-3-24 08:59:42 | 显示全部楼层
IDLE清标志位不是通过写CR寄存器,而是一个软件序列,先读SR,再读DR,这样才能清中断,可以看下手册上关于IDLE的介绍
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

12

帖子

0

蝴蝶豆

中级会员

最后登录
2021-8-14
发表于 2019-5-15 18:03:01 | 显示全部楼层
楼主:IDLE中断为什么一上电就IDLE中断中断一次啊?没有数据也搞一次,怎么解决啊?
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

246

帖子

172

蝴蝶豆

金牌会员

最后登录
2021-3-26
发表于 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;
}
要加红色这一句
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

4

帖子

0

蝴蝶豆

中级会员

最后登录
2020-9-28
发表于 2019-6-18 08:57:42 | 显示全部楼层
sdtazzf 发表于 2019-5-15 18:03
楼主:IDLE中断为什么一上电就IDLE中断中断一次啊?没有数据也搞一次,怎么解决啊?
...

看我的回复
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

4

帖子

0

蝴蝶豆

中级会员

最后登录
2020-9-28
发表于 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);//不用的时候关闭串口空闲中断,防止意外进入
        }
    }


回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

4

帖子

0

蝴蝶豆

初级会员

最后登录
2020-7-24
发表于 2020-6-9 15:15:41 | 显示全部楼层
浅色调123 发表于 2019-6-18 09:03
多年已过,楼主肯定解决了,但是一直没有说一下怎么解决的,我说一下吧附上f030的代码1、初始化千万不要初 ...

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

评分

参与人数 1ST金币 +1 收起 理由
arm91 + 1 赞一个!

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-7 08:10 , Processed in 0.188453 second(s), 43 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表