micro_climate/App/Src/uart_dev.c

308 lines
6.6 KiB
C

#include "uart_dev.h"
#include <stdio.h>
#include <stdarg.h>
#include "timer.h"
#include "gpio.h"
#include "inflash.h"
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
static void uart_init(uartIndex_e uart_index, int baud);
static u_int8_t uart_putchar(device_handle device, char ch);
device_handle g_term_uart_handle;
device_handle g_rs485_uart_handle;
device_handle uart_dev_init(uartIndex_e uart_index, uint8_t *buff, int buff_size);
static u_int8_t term_in_buff[200];
static u_int8_t rs485_in_buff[300];
u_int8_t rs485_out_buff[100];
static u_int8_t term_out_buff[100];
/**
* @brief 串口信息初始化,串口号及波特率.
* @param uart_index 对应的硬件串口号
* @param uart_baudrate 波特率
*/
uart_device_info uart_devices[]={
[0] = {
.init = 0,
.uart_index = TERM_UART_INDEX,
.uart_baudrate = 9600,
},
[1] = {
.init = 0,
.uart_index = RS485_UART_INDEX,
.uart_baudrate = 9600,
},
};
/**
* @brief 初始化串口设备.
* @param uart_index 初始化串口号
* @param buff 串口循环buff地址
* @param buff_size 串口循环buff对应大小
* @retval 串口句柄
*/
device_handle uart_dev_init(uartIndex_e uart_index, uint8_t *buff, int buff_size)
{
int i = 0;
for(; i < ELEMENT_OF(uart_devices); i++){
if(uart_devices[i].uart_index == uart_index){
if(!uart_devices[i].init){
InitRingQueue(&uart_devices[i].uart_ring_queue, buff, buff_size);
uart_init(uart_index, uart_devices[i].uart_baudrate);
uart_devices[i].init = 1;
}
return (device_handle)(&uart_devices[i]);
}
}
return 0;
}
/**
* @brief 串口硬件初始化.
* @param uart_index 串口号
* @param baud 波特率
* @retval None
*/
static void uart_init(uartIndex_e uart_index, int baud)
{
if(uart_index == TERM_UART_INDEX){
// MX_USART1_UART_Init();
MX_USART1_UART_Init(baud);
}else if(uart_index == RS485_UART_INDEX){
MX_USART3_UART_Init(baud);
// MX_USART3_UART_Init();
}
}
/**
* @brief 关闭串口
* @param uart_index 串口号
* @retval None
*/
void uart_close(uartIndex_e uart_index)
{
if(uart_index == TERM_UART_INDEX){
HAL_UART_MspDeInit(&huart1);
}else if(uart_index == RS485_UART_INDEX){
HAL_UART_MspDeInit(&huart3);
}
}
/**
* @brief 发送一个字节.
* @param uart_index 串口号
* @param ch 待发送字符
* @retval 1 成功 0失败
*/
static u_int8_t uart_putchar(device_handle device, char ch)
{
int ret=HAL_ERROR;
uart_device_info *device_info = (uart_device_info *)device;
if((!device) || (!device_info->init))
return 0;
if(device_info->uart_index == TERM_UART_INDEX){
ret= HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,10);
}else if(device_info->uart_index == RS485_UART_INDEX){
ret= HAL_UART_Transmit(&huart3,(uint8_t*)&ch,1,10);
}
if(ret == HAL_OK){
return 1;
}else{
return 0;
}
}
/**
* @brief 发送字符串.
* @param uart_index 串口号
* @param str 待发送字符串地址
* @retval None
*/
void uart_sendstr(device_handle device,char *str)
{
while ((*str) != (char )0u) {
if (*str == ASCII_CHAR_LINE_FEED){
uart_putchar(device, (ASCII_CHAR_CARRIAGE_RETURN));
uart_putchar(device, ASCII_CHAR_LINE_FEED);
str++;
}else{
uart_putchar(device, *str++);
}
}
}
/**
* @brief 串口多字节发送.
* @param device 串口句柄
* @param data 待发送数据
* @param len 待发送数据长度
* @retval None
*/
void uart_dev_write(device_handle device, void *data, int len)
{
#if 0
if(device == g_rs485_uart_handle){
rs485_tx_enable();
}
#endif
for (int i = 0; i < len; i++){
uart_putchar(device, ((u_int8_t *)data)[i]);
}
#if 0
if(device == g_rs485_uart_handle){
rs485_rx_enable();
}
#endif
}
/**
* @brief 判断串口设备循环buff是否有数据.
* @param device 串口句柄
* @retval 0 空 1有数据
*/
int uart_dev_char_present(device_handle device)
{
uart_device_info *device_info = (uart_device_info *)device;
if((!device) || (!device_info->init))
return 0;
return !RingQueueEmpty(&device_info->uart_ring_queue);
}
/**
* @brief 从串口设备循环buff读取一个数据.
* @param device 串口句柄
* @retval 读取到的字符
*/
char uart_dev_in_char(device_handle device)
{
uart_device_info *device_info = (uart_device_info *)device;
char c = 0;
if (uart_dev_char_present(device))
OutRingQueue(&device_info->uart_ring_queue, (u_int8_t*)&c);
return c;
}
/**
* @brief 判断循环buff是否有数据.
* @param ring_queue 循环buff地址
* @retval 0 空 1有数据
*/
int ring_queue_dev_char_present(RingQueue *ring_queue)
{
return !RingQueueEmpty(ring_queue);
}
/**
* @brief 从循环buff读取一个数据.
* @param ring_queue 循环buff地址
* @retval 读取到的字符
*/
char ring_queue_dev_in_char(RingQueue *ring_queue)
{
char c = 0;
if (ring_queue_dev_char_present(ring_queue))
OutRingQueue(ring_queue, (u_int8_t*)&c);
return c;
}
/**999
* @brief 调试串口 .
* @param 可变参
* @retval Null
*/
void term_printf(char *format, ...)
{
memset(term_out_buff, 0, sizeof(term_out_buff));
va_list va_ptr;
va_start(va_ptr, format);
vsprintf((char*)term_out_buff, (char const *)format, va_ptr);
va_end(va_ptr);
uart_sendstr(g_term_uart_handle, (char*)term_out_buff);
}
#if 0
/**
* @brief 调试终端读取一行命令 .
* @param
* @param
* @param
* @retval 读取到的数据长度
*/
int term_uart_readln(u_int8_t *buff, int buff_size, u_int32_t timeout_ms)
{
int offset = 0;
char c = 0;
u_int32_t wait_timeout_flag = 0;
buff_size--;
if(timeout_ms){
set_flag_timeout(timeout_ms, &wait_timeout_flag);
}
for(offset = 0; offset<buff_size; offset++){
while((!uart_dev_char_present(g_term_uart_handle)) && (!wait_timeout_flag));
if(wait_timeout_flag){
break;
}else{
c = uart_dev_in_char(g_term_uart_handle);
buff[offset] = c;
// if(g_term_echo_on)
// out_char(c); //回显
if((c == '\n') || (c == '\r')){
offset++;
break;
}
}
}
if(timeout_ms)
stop_timout();
buff[offset] = '\0';
return offset;
}
#endif
/**
* @brief 初始化调试串口.
* @retval None
*/
void init_term_uart()
{
g_term_uart_handle = uart_dev_init(TERM_UART_INDEX, term_in_buff, sizeof(term_in_buff));
}
/**
* @brief 初始化RS485串口.
* @retval None
*/
void init_rs485_uart()
{
g_rs485_uart_handle = uart_dev_init(RS485_UART_INDEX, rs485_in_buff, sizeof(rs485_in_buff));
}