rs485接收中断函数使能_关于STM32串口调试RS485时自动进入接收中断

在使用STM32C8T6进行RS485通信时,遇到发送数据后立即进入接收中断的问题。解决方法是在初始化时仅使能接收中断,关闭发送中断,发送时才打开。当硬件无上拉电阻时,将接收端口设置为上拉输入,问题得到解决。提供初始化代码供参考。
摘要由CSDN通过智能技术生成

先说一下软硬件:

硬件:主控stm32c8t6、485芯片为隔离型芯片ADM2483,调试工具是usb转485接到PC端。

软件:采用库函数开发,开发工具为IAR 7.10,485接的是stm32的串口1(收发都是用中断方式),半双工模式, 协议是MODBUS RTU。

先说明本人是菜鸟,在不断得学习中,欢迎指出错误。

最近在调试RS485时发现一个问题,如果在串口初始化时就使能了发送中断和接收的话,那么在发送一个字节后就会自动进入接收中断。可能是收发的机制没有定好,所以后面采用的方式是在初始化时使能了接收中断,关闭发送中断,在需要发送数据的时候再开启发送中断,发送的时候关闭接收中断,发送完一帧再使能接收中断。这样就可以完整地发送一帧数据出去了。

但是随之而来的问题就是,板子没有接收到数据的时候也会进入接收中断,通常是00、F0、C0、FE、80这样的数据,让我觉得很奇怪,心想是不是串口工具有干扰,于是我就把串口工具拔了,结果还是会进入接收中断,收到的数据还是之前那些。初步判定是硬件问题,因为硬件是之前的同事留下的,所以硬件我也不清楚能不能用;在查阅了许多网友的问题后,有一点给我提示了,就是“485电路的接收端是否有上拉电阻,如果没有,你配置成上拉输入就可以了” 我看了一下板子,是没有接上拉电阻的,而我在初始化的时候设置接收端的模式为 “浮空输入”,按照网友的想法,把输入模式修改为“上拉输入”GPIOInit.GPIO_Mode = GPIO_Mode_IPU 问题果然解决了。

总结:在调

以下是基于STM32F103的中断实现RS485数据接收和发送的示例代码: ```c #include "stm32f10x.h" // 定义RS485相关的引脚和串口 #define RS485_DE_GPIO GPIOA #define RS485_DE_PIN GPIO_Pin_8 #define RS485_USART USART1 // 定义接收缓冲区大小 #define RX_BUFFER_SIZE 256 // 定义全局变量 volatile uint8_t rxBuffer[RX_BUFFER_SIZE]; volatile uint16_t rxBufferIndex = 0; // 初始化RS485串口 void RS485_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; // 使能GPIOA钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置RS485 DE引脚为输出模式 GPIO_InitStruct.GPIO_Pin = RS485_DE_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(RS485_DE_GPIO, &GPIO_InitStruct); // 使能USART1钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 配置USART1引脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // TX引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // RX引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置USART1 USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(RS485_USART, &USART_InitStruct); // 使能USART1接收中断 USART_ITConfig(RS485_USART, USART_IT_RXNE, ENABLE); // 使能USART1 USART_Cmd(RS485_USART, ENABLE); } // RS485发送数据 void RS485_SendData(uint8_t *data, uint16_t length) { // 设置RS485为发送模式 GPIO_ResetBits(RS485_DE_GPIO, RS485_DE_PIN); // 发送数据 for (uint16_t i = 0; i < length; i++) { USART_SendData(RS485_USART, data[i]); while (USART_GetFlagStatus(RS485_USART, USART_FLAG_TXE) == RESET); } // 等待发送完成 while (USART_GetFlagStatus(RS485_USART, USART_FLAG_TC) == RESET); // 设置RS485接收模式 GPIO_SetBits(RS485_DE_GPIO, RS485_DE_PIN); } // 处理接收中断 void USART1_IRQHandler(void) { if (USART_GetITStatus(RS485_USART, USART_IT_RXNE) != RESET) { rxBuffer[rxBufferIndex++] = USART_ReceiveData(RS485_USART); if (rxBufferIndex >= RX_BUFFER_SIZE) { rxBufferIndex = 0; } } } int main(void) { // 初始化RS485串口 RS485_Init(); while (1) { // 接收到数据后行处理 if (rxBufferIndex > 0) { // 处理接收到的数据,例如打印到终端 for (uint16_t i = 0; i < rxBufferIndex; i++) { printf("%c", rxBuffer[i]); } // 清空接收缓冲区 rxBufferIndex = 0; } // 发送数据 uint8_t sendData[] = "Hello, RS485!"; uint16_t sendLength = sizeof(sendData); RS485_SendData(sendData, sendLength); // 延一段间 for (uint32_t i = 0; i < 1000000; i++); } } ``` 以上代码是一个简单的示例,实现了RS485的数据接收和发送功能。在主循环中,我们通过判断接收缓冲区中是否有数据,如果有则行处理(例如打印到终端),然后清空接收缓冲区。然后我们通过RS485_SendData()函数发送数据。 需要注意的是,以上代码仅是一个示例,实际应用中可能需要根据具体的需求行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值