377 lines
10 KiB
C
377 lines
10 KiB
C
/****
|
||
*****串口通信模块
|
||
*****在中断中接收数据
|
||
*****数据存放环形缓冲队列中
|
||
*****创建串口接收任务
|
||
*****创建中断接收函数
|
||
*****创建串口发送函数
|
||
****/
|
||
|
||
#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://串口1,485
|
||
//使能端口时钟
|
||
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://串口2,422
|
||
//使能端口时钟
|
||
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://串口1,485
|
||
nvic_irq_enable(USART1_IRQn, 3, 0);//优先级配置为3,子优先及为1
|
||
break;
|
||
|
||
case UART_422://串口2,422
|
||
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");
|
||
|
||
}
|