lps402 发表于 2017-5-18 17:22:01

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

本帖最后由 lps402 于 2017-5-18 17:22 编辑

      如题,在使用IDLE中断接收不定长度的数据包,发现程序一直处于IDLE中断中。程序如下
串口配置程序
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;                     //设定波特率
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(USART1, &USART_InitStructure);                        //初始化USART1

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

USART1->CR1=USART1->CR1&~(1<<4);                           //清除IDLE中断。特意加的,未添加时,上电后,设备一直处于IDLE中断,
                                                                                                   无法执行主程序
USART_Cmd(USART1, ENABLE);                                          //使能USART1
}
中断程序
void USART1_IRQHandler(void)
{
static uint8_t data; //
static uint8_t rxne_num; //
if((USART1->ISR & USART_FLAG_RXNE) == USART_FLAG_RXNE)
{
   data=USART_ReceiveData(USART1);
   rxne_num=rxne_num+1;
   if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)==SET)
    {
   USART1->CR1=USART1->CR1&~(1<<4); //清楚IDLE中断
      rxne_num=0;
   }
}主程序
int main(void)
{
static uint8_t   data={0,0,0,0,0,0,0,0,0,0}; //全局变量,接收缓存数组
static uint8_t          rxne_num=0;                           //全局变量,接收缓存数组序号
System_Initializes();

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

       请问各位,STM32F030的IDLE这样使用是否有问题?STM32F030的IDLE是否有问题?

lps402 发表于 2017-5-18 17:32:35

补充说明
串口GPIO配置
void USART_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

/* 定义USART TX/ 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);
}

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、初始化千万不要初 ...

——“多年已过,楼主肯定解决了”,其实也不一定,也可能是没解决,但是楼主已经死了,所以帖子才一直晾在这里。。。
页: [1]
查看完整版本: STM32F030 串口 用IDLE中断 接收不定长度数据包,中断异常