rs485收发数据:
//rs485.c
#include "string.h"
#include "rs485.h"
#include "main.h"
#include <stdio.h> // 添加标准输入输出库
#include <stdarg.h> // 用于 va_list, va_start, va_end
#include <string.h>
#define RS485_TX_BUFFER_SIZE 128 // 发送缓冲区大小
volatile uint8_t rs485_tx_buf[128];
volatile uint8_t rs485_tx_busy = 0;
uint8_t rxBuffer[50];
volatile uint8_t usart2_tx_complete = 0; // 发送完成标志
extern DMA_HandleTypeDef hdma_usart2_rx;
extern UART_HandleTypeDef huart2;
重定向printf到USART2
//int __io_putchar(int ch) {
// HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
// return ch;
//}
可选:如果需要scanf,重定向输入
//int __io_getchar(void) {
// uint8_t ch;
// HAL_UART_Receive(&huart2, &ch, 1, HAL_MAX_DELAY);
// return ch;
//}
void RS485_Printf(const char *format, ...) {
if (rs485_tx_busy) {
return; // 或加入队列等待
}
va_list args;
va_start(args, format);
int len = vsnprintf((char *)rs485_tx_buf, sizeof(rs485_tx_buf), format, args);
va_end(args);
if (len > 0) {
rs485_tx_busy = 1;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 发送模式
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)rs485_tx_buf, len); // DMA发送
}
}
uint8_t RS485_IsBusy(void) {
return rs485_tx_busy;
}
void RS485_Send(uint8_t *data, uint16_t size) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 发送模式
usart2_tx_complete = 0;
HAL_UART_Transmit_DMA(&huart2, data, size); // 非阻塞发送
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart == &huart2) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // 发送完成后切接收模式
usart2_tx_complete = 1; rs485_tx_busy = 0; // 标记发送完成
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart == &huart2) {
RS485_Send(rxBuffer, 3); // 回传数据
HAL_UART_Receive_DMA(&huart2, rxBuffer, 3); // 重启接收
}
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if (huart == &huart2) {
RS485_Send(rxBuffer, Size); // 回传数据
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rxBuffer, sizeof(rxBuffer));
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
}
}
//rs485.h
#ifndef __RS485_H
#define __RS485_H
#include "stdint.h"
void RS485_Printf(const char *format, ...);
uint8_t RS485_IsBusy(void);
void RS485_Send(uint8_t *data, uint16_t size) ;
#endif
使用测试:
while (1) {
RS485_Printf("Temperature: %.1f\r\n", 25.5f);
HAL_Delay(1000); // 避免频繁发送
}
现象:调试助手显示收到 Temperature: 25.5