USART _ 两串口同时使用,冲突问题

本文探讨了在使用串口通信时遇到的一个问题:当在串口2的接收中断函数中调用串口1的发送函数时,串口2DMA发送的数据无法被正确接收。文章详细记录了问题现象,并通过实验对比,发现在任务中调用串口1发送函数时,两串口数据均可正常接收。问题的焦点在于中断函数中调用串口发送的影响。

1、使用外设情况:

              1、初始化了两个串口 :串口1以及串口2,使用串口2DMA发送数据,接收中断 接收数据;

                                                          使用串口1发送函数发送数据,接收中断接收数据;

2、问题出现的形式: 

                                         在串口2的中断接收函数中,使用串口1发送函数发送数据;

                                        串口1发送的数据能在串口接收到,但是在任务中,使用串口2DMA发送的数据在串口2上接收不到;

3、解决方法探索 :

                                  第一步探索: 把串口1发送函数放在任务中,两个串口上的数据都接收的到;             

                                                            一旦把串口1发送函数放在 串口2接收中断函数中,串口2DMA发送数据就收不到。     

   

                              第二步探索: 把串口1发送函数放在任务中,两个串口上的数据都接收的到;             

                                                            一旦把串口1发送函数放在 串口2接收中断函数中,串口2DMA发送数据就收不到。     

                                  

static void AIChat_NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable the USARTy Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = AIChat_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void AIChat_USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHB1PeriphClockCmd(AIChat_USART_GPIO_CLK, ENABLE); /* config USART clock */ RCC_APB1PeriphClockCmd(AIChat_USART_CLK, ENABLE); /* 连接 PXx 到 USARTx_Tx*/ GPIO_PinAFConfig(AIChat_USART_TX_PORT,AIChat_USART_TX_SOURCE,AIChat_USART_TX_AF); /* 连接 PXx 到 USARTx__Rx*/ GPIO_PinAFConfig(AIChat_USART_RX_PORT,AIChat_USART_RX_SOURCE,AIChat_USART_RX_AF); /* USARTconfig */ GPIO_InitStructure.GPIO_Pin = AIChat_USART_TX_PIN; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(AIChat_USART_TX_PORT, &GPIO_InitStructure); /* Configure USART as input floating */ GPIO_InitStructure.GPIO_Pin = AIChat_USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(AIChat_USART_RX_PORT, &GPIO_InitStructure); /* USART mode config */ 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(AIChat_USARTx, &USART_InitStructure); /* 配置中断优先级 */ AIChat_NVIC_Configuration(); /* 使能串口接收中断 */ USART_ITConfig(AIChat_USARTx, USART_IT_TXE, ENABLE); USART_ITConfig(AIChat_USARTx, USART_IT_RXNE, ENABLE); USART_Cmd(AIChat_USARTx, ENABLE); USART_ClearFlag(AIChat_USARTx, USART_FLAG_TC); } 我用标准库配置的uart4,请帮我找出问题在哪?程序进入到AIChat_USART_Config函数就卡住了
11-10
void usart_init(USART_TypeDef* usartPort) { USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; /* USART1 configured as follow: - BaudRate = 9600 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled - USART Clock disabled - USART CPOL: Clock is active low - USART CPHA: Data is captured on the middle - USART LastBit: The clock pulse of the last data bit is not output to the SCLK pin */ // Configure the USART synchronous paramters USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_ClockInit(usartPort, &USART_ClockInitStructure); // Configure usartPort basic and asynchronous paramters USART_InitStructure.USART_BaudRate = UART_BPS; USART_InitStructure.USART_WordLength = USART_WordLength_9b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_Odd ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(usartPort, &USART_InitStructure); /* Enable usartPort */ USART_Cmd(usartPort, ENABLE); /* Enable the DMA transfer on Rx and Tx action for USART1 */ if(usartPort == USART1) { USART_DMACmd(usartPort, USART_DMAReq_Rx , ENABLE); } }解释一下这个代码的逻辑,要求详细
08-22
#include "stm32f10x.h" // 定义使用串口及引脚 #define USART_PORT USART1 #define USART_TX_PORT GPIOA #define USART_TX_PIN GPIO_Pin_9 #define USART_RX_PORT GPIOA #define USART_RX_PIN GPIO_Pin_10 // 定义RS485方向控制引脚(DE/RE) #define RS485_CTRL_PORT GPIOA #define RS485_CTRL_PIN GPIO_Pin_0 // 函数声明 void USART_Config(uint32_t baudrate); void RS485_SendData(uint8_t *buf, uint16_t len); void delay_us(uint32_t us); void USART1_IRQHandler(void); /** * 串口初始化函数 * 配置USART1为8N1模式,启用接收中断,并设置方向控制引脚为输出 */ void USART_Config(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 使能串口和GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置TX引脚为复用推挽输出 GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USART_TX_PORT, &GPIO_InitStructure); // 配置RX引脚为浮空输入 GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USART_RX_PORT, &GPIO_InitStructure); // 配置RS485方向控制引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = RS485_CTRL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(RS485_CTRL_PORT, &GPIO_InitStructure); GPIO_ResetBits(RS485_CTRL_PORT, RS485_CTRL_PIN); // 默认为接收模式 // 配置串口参数 USART_InitStructure.USART_BaudRate = baudrate; 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_Tx | USART_Mode_Rx; USART_Init(USART_PORT, &USART_InitStructure); // 启用接收中断 USART_ITConfig(USART_PORT, USART_IT_RXNE, ENABLE); // 配置中断优先级 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART_PORT, ENABLE); // 启动串口 } /** * RS485发送数据函数 * 切换方向为发送,发送完成后切换回接收 */ void RS485_SendData(uint8_t *buf, uint16_t len) { if (len == 0) return; // 切换为发送模式 GPIO_SetBits(RS485_CTRL_PORT, RS485_CTRL_PIN); delay_us(2); // 等待方向切换稳定 // 关闭接收中断以避免冲突 USART_ITConfig(USART_PORT, USART_IT_RXNE, DISABLE); // 发送数据 for (uint16_t i = 0; i < len; i++) { while (USART_GetFlagStatus(USART_PORT, USART_FLAG_TXE) == RESET); USART_SendData(USART_PORT, buf[i]); } // 等待最后一个字节发送完成 while (USART_GetFlagStatus(USART_PORT, USART_FLAG_TC) == RESET); // 切换回接收模式 GPIO_ResetBits(RS485_CTRL_PORT, RS485_CTRL_PIN); // 恢复接收中断 USART_ITConfig(USART_PORT, USART_IT_RXNE, ENABLE); } /** * 串口接收中断处理函数 * 接收数据并缓存至recv_buf,可扩展为环形缓冲区 */ void USART1_IRQHandler(void) { static uint8_t recv_buf[100]; static uint16_t recv_len = 0; if (USART_GetITStatus(USART_PORT, USART_IT_RXNE) != RESET) { // 读取接收数据 recv_buf[recv_len++] = USART_ReceiveData(USART_PORT); // 可添加接收完成判断逻辑,如检测帧尾 if (recv_len >= sizeof(recv_buf)) { recv_len = 0; // 缓冲区溢出处理 } USART_ClearITPendingBit(USART_PORT, USART_IT_RXNE); } } /** * 微秒级延时函数 * 基于SysTick实现,适用于方向切换等短延时场景 */ void delay_us(uint32_t us) { SysTick->LOAD = 72 * us; // 72MHz主频下,1us对应72个时钟周期 SysTick->VAL = 0x00; SysTick->CTRL = 0x01; while (!(SysTick->CTRL & (1 << 16))); SysTick->CTRL = 0x00; } 将上述代码按照引脚初始化以及发送接收数据代码进行顺序排列,看起来更加清晰
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值