MW22-02A/BSP/Driver/usart/Usart.c

377 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****
*****串口通信模块
*****在中断中接收数据
*****数据存放环形缓冲队列中
*****创建串口接收任务
*****创建中断接收函数
*****创建串口发送函数
****/
#include "Usart.h"
#include "ptz_struct.h"
#include "gd32f4xx_it.h"
device_handle uart_485_handle = 0;
device_handle uart_422_handle = 0;
BSP_OS_SEM ser_mutex;//用于锁调用发生一个字节函数
uart_device_info uart_devices[6]={
// init index
{ 0, 0,},
{ 0, 1,},
{ 0, 2,},
{ 0, 3,},
{ 0, 4,},
{ 0, 5,}
};
RingQueue ring_que;
u_int8_t ptz_uart_buff[10];
//串口
//RS422
u_int8_t ptz_uart_422_buff[PTZ_UART_422_BUFF_SIZE];
char uart_422_state = 0;
//RS485
u_int8_t ptz_uart_485_buff[PTZ_UART_485_BUFF_SIZE];
char uart_485_state = 0;
int bata;
char uart_data;
/// @brief 初始化串口引脚、波特率
/// @param[in] usart_periph:USARTx(x=0,1,2)
/// @param[in] baud:波特率
/// @return none
/// @note 修改日志
/// LH于2022-05-20
static void usart_config(uint32_t usart_periph, int baud)
{
switch(usart_periph)
{
case TEST://串口0调试端口
//使能端口时钟
rcu_periph_clock_enable(RCU_GPIOA);
//使能串口时钟
rcu_periph_clock_enable(RCU_USART0);
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);//TX
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);//RX
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
break;
case UART_485://串口1485
//使能端口时钟
rcu_periph_clock_enable(RCU_GPIOD);
//使能串口时钟
rcu_periph_clock_enable(RCU_USART1);
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);//TX
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);//RX
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_5);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_6);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
///收发模式选择
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_7);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
break;
case UART_422://串口2422
//使能端口时钟
rcu_periph_clock_enable(RCU_GPIOD);
//使能串口时钟
rcu_periph_clock_enable(RCU_USART2);
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_8);//TX
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_9);//RX
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_8);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_9);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
break;
default:
break;
}
///串口配置使能
usart_deinit(usart_periph);//时钟复位
usart_baudrate_set(usart_periph,baud);//设置波特率默认9600
usart_receive_config(usart_periph, USART_RECEIVE_ENABLE);//接收使能
usart_transmit_config(usart_periph, USART_TRANSMIT_ENABLE);//发送使能
usart_enable(usart_periph);//串口使能
//使能接收中断
usart_interrupt_enable(usart_periph, USART_INT_RBNE);
}
/// @brief 中断嵌套向量配置
/// @param[in] usart_periph:USARTx(x=0,1,2)
/// @return none
/// @note 修改日志
/// LH于2022-05-20
static void Usart_Nvic_config(uint32_t usart_periph)
{
switch(usart_periph)
{
case TEST://串口0调试端口
//使能串口中断请求
nvic_irq_enable(USART0_IRQn, 4, 0);//抢占优先级配置为3子优先及为0比以太网低以太网为2
break;
case UART_485://串口1485
nvic_irq_enable(USART1_IRQn, 3, 0);//优先级配置为3子优先及为1
break;
case UART_422://串口2422
nvic_irq_enable(USART2_IRQn, 3, 1);//优先级配置为3子优先及为2
break;
default:
break;
}
}
/// @brief 初始化环形队列、资源锁
/// @param[in] usart_periph:USARTx(x=0,1,2)
/// @param[in] index:设备端口
/// @param[in] *buff:队列地址
/// @param[in] buff_size:队列长度
/// @return device_handle设备地址
/// @note 修改日志
/// LH于2022-05-20
device_handle uart_init(uint32_t usart_periph, uint32_t index, u_int8_t *buff, int buff_size)
{
if(!uart_devices[index].init)
{//没有初始化
InitRingQueue(&uart_devices[index].uart_ring_queue, buff, buff_size); //初始化环形队列缓存
BSP_OS_SemCreate(&uart_devices[index].port_mutex,1u,"port mutex");
BSP_OS_SemCreate(&uart_devices[index].ser_mutex,1u,"serial mutex");
BSP_OS_SemCreate(&uart_devices[index].sem_recv_data,0u,"sem recv data");
uart_devices[index].init = 1;
}
return (device_handle)(&uart_devices[index]);
}
/// @brief 串口设备初始化
/// @param[in] none
/// @return none
/// @note 修改日志
/// LH于2022-05-20
static void Uart_Init(void)
{
///485串口设备初始化UART_485
usart_config(UART_485, g_ptz.uart_485_baud);//串口初始化
Usart_Nvic_config(UART_485);//中断配置
uart_485_handle = uart_init(UART_485, PTZ_UART_485_INDEX, ptz_uart_485_buff, sizeof(ptz_uart_485_buff));
BSP_IntVectSet(54,USART1_IRQHandler);
BSP_IntEn(54);
///422串口设备初始化
usart_config(UART_422, g_ptz.uart_422_baud);//串口初始化
Usart_Nvic_config(UART_422);//中断配置
uart_422_handle = uart_init(UART_422, PTZ_UART_422_INDEX, ptz_uart_422_buff, sizeof(ptz_uart_422_buff));
BSP_IntVectSet(55,USART2_IRQHandler);
BSP_IntEn(55);
}
/// @brief 485接收中断处理数据
/// @param[in] data:
/// @return none
/// @note 修改日志
/// LH于2022-05-20
void IRQHandler_485_process(u_int8_t data)
{
uart_device_info *dev = (uart_device_info *)uart_485_handle;//终端交互
if(!RingQueueFull(&dev->uart_ring_queue))
{
InRingQueue(&dev->uart_ring_queue, data);
}
}
/// @brief 422接收中断处理数据
/// @param[in] data
/// @return none
/// @note 修改日志
/// LH于2022-05-20
void IRQHandler_422_process(u_int8_t data)
{
uart_device_info *dev = (uart_device_info *)uart_422_handle;//终端交互
if(!RingQueueFull(&dev->uart_ring_queue))
{
InRingQueue(&dev->uart_ring_queue, data);
}
}
///串口设备发送数据
void ptz_uart_dev_send(device_handle device, void *data, int len)
{
unsigned char buff;
uart_device_info *device_info = (uart_device_info *)device;
if((!device) || (!device_info->init))
{
return;
}
BSP_OS_SemWait(&device_info->ser_mutex, 0u);
if(device == uart_485_handle)
{
PTZ_UART_485_TX;
OSTimeDlyHMSM(0u, 0u, 0u, 10u);
for (int i = 0; i<len; i++)
{
buff = ((u_int8_t *)data)[i];
//等待发送缓冲区位空
while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)){}
//写寄存器
usart_data_transmit(USART1, buff);
//等待发送完成
while(RESET == usart_flag_get(USART1, USART_FLAG_TC)){}
if((i % 100) == 0 && i > 0)
{
OSTimeDlyHMSM(0u, 0u, 0u, 2u);
}
}
OSTimeDlyHMSM(0u, 0u, 0u, 10u);
PTZ_UART_485_RX;
}
if(device == uart_422_handle)
{
for (int i = 0; i<len; i++)
{
buff = ((u_int8_t *)data)[i];
//等待发送缓冲区位空
while(RESET == usart_flag_get(USART2, USART_FLAG_TBE)){}
//写寄存器
usart_data_transmit(USART2, buff);
//等待发送完成
while(RESET == usart_flag_get(USART2, USART_FLAG_TC)){}
if((i % 100) == 0 && i > 0)
{
OSTimeDlyHMSM(0u, 0u, 0u, 2u);
}
}
}
BSP_OS_SemPost(&device_info->ser_mutex);
}
/*******************************************************************************
** 函数名称:
** 功 能:串口设备缓冲区是否有数据
** 入口参数:
** 出口参数:
********************************************************************************/
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);
}
/*******************************************************************************
** 函数名称:
** 功 能:串口设备从缓冲区读入一个数据
** 入口参数:
** 出口参数:
********************************************************************************/
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;
}
//串口设备从缓冲区读入一个数据
char ptz_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;
}
//串口设备缓冲区是否有数据
int ptz_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);
}
void Usart_init_module()
{
Uart_Init();
}
//初始化终端串口
void init_term_uart()
{
//使能端口时钟
rcu_periph_clock_enable(RCU_GPIOA);
//使能串口时钟
rcu_periph_clock_enable(RCU_USART0);
/* connect port to USARTx_Tx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
/* connect port to USARTx_Rx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);
/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
/* USART configure */
usart_deinit(USART0);//时钟复位
usart_baudrate_set(USART0,9600U);//设置波特率
usart_receive_config(USART0, USART_RECEIVE_ENABLE);//接收使能
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//发送使能
usart_enable(USART0);//串口使能
// BSP_OS_SemCreate(&ser_mutex,0u,"udp_send_data_mutex");
}