STM32
直播中

而无返还

9年用户 1320经验值
擅长:光电显示
私信 关注
[问答]

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

如题,在使用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[10]; //
  • static uint8_t rxne_num; //
  • if((USART1->ISR   USART_FLAG_RXNE) == USART_FLAG_RXNE)
  • {
  •    data[rxne_num]=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[10]={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是否有问题?

回帖(1)

h1654155199.5148

2024-4-12 15:54:58
以下是您提供的代码片段:
```c
void USART_Configuration(void){
  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
}
```
这段代码仅仅是对USART进行了配置,并没有进行初始化和使能操作。所以在接收数据时,无法触发IDLE中断。您需要按照以下步骤进行配置和初始化:

1. 配置USART的GPIO引脚:
```c
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOx, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x; // 根据实际连接的GPIO引脚修改
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOx, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_x); // 根据实际连接的GPIO引脚修改
```
2. 配置USART的相关参数:
```c
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE);

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(USARTx, &USART_InitStructure);

USART_ITConfig(USARTx, USART_IT_IDLE, ENABLE); // 开启IDLE中断
USART_Cmd(USARTx, ENABLE); // 使能USART
```
3. 编写中断处理函数:
```c
void USARTx_IRQHandler(void){
  if(USART_GetITStatus(USARTx, USART_IT_IDLE) != RESET){
    // 在这里处理接收到的数据包
    // 可以通过USARTx->DR寄存器读取接收到的数据
    USART_ClearITPendingBit(USARTx, USART_IT_IDLE); // 清除IDLE中断标志位
  }
}
```
4. 在主函数中使能中断:
```c
NVIC_InitTypeDef NVIC_InitStructure;
// ...
NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
请注意替换代码中的GPIO和USART变量名与实际使用的引脚和USART编号。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分