|
楼主 |
发表于 2020-6-5 15:51:25
|
显示全部楼层
附件关于处理串口的代码- static void vTaskComm(void *pvParameters)
- {
- uint16_t recvLen = 0;
- uint8_t buf[20] = {0};
- uint8_t crc = 0;
-
- ELEVATOR_BUFF_STRU *sendBuf = &gElevtorData;
- uint8_t defaultBuff[MAX_RS485_LEN+1] ={ 0x5A,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x5A };
- uint32_t i = 0;
-
- READER_BUFF_STRU *ptMsg = &gReaderMsg;
- BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdPASS */
- const TickType_t xMaxBlockTime = pdMS_TO_TICKS(10); /* 设置最大等待时间为200ms */
-
- //获取当前设备的ID
- uint16_t readID = bsp_dipswitch_read();
- memset(&gReaderMsg,0x00,sizeof(READER_BUFF_STRU));
- /* 清零 */
- ptMsg->authMode = 0; //默认为刷卡
- ptMsg->dataLen = 0;
- memset(ptMsg->data,0x00,sizeof(ptMsg->data));
- memset(sendBuf->data,0x00,sizeof(sendBuf->data));
-
- while (1)
- {
- memset(buf,0x00,sizeof(buf));
- recvLen = RS485_Recv(COM6,buf,sizeof(buf));
- if(buf[0] == 0x5A && buf[1] == readID)
- {
- crc= xorCRC(buf,4);
- if(crc != buf[4])
- {
- continue;
- }
- xReturn = xQueueReceive( xTransDataQueue, /* 消息队列的句柄 */
- (void *)&sendBuf, /*这里获取的是结构体的地址 */
- xMaxBlockTime); /* 设置阻塞时间 */
- if(pdTRUE == xReturn)
- {
- printf("2.%02x,%02x\r\n",sendBuf->data[11],sendBuf->data[36]);
- }
- else
- {
- //发送默认数据包
- memcpy(sendBuf->data,defaultBuff,MAX_RS485_LEN);
- }
- //BSP_DMAUsart6Puts(sendBuf->data,MAX_RS485_LEN);
- RS485_SendBuf(COM6,sendBuf->data,MAX_RS485_LEN);
- }
- /* 发送事件标志,表示任务正常运行 */
- xEventGroupSetBits(xCreatedEventGroup, TASK_BIT_1);
- vTaskDelay(5);
- }
- }
复制代码 关于串口部分的代码
- /*
- *********************************************************************************************************
- *
- * 模块名称 : 串口中断+FIFO驱动模块
- * 文件名称 : bsp_uart_fifo.c
- * 版 本 : V1.0
- * 说 明 : 采用串口中断+FIFO模式实现多个串口的同时访问
- * 修改记录 :
- * 版本号 日期 作者 说明
- * V1.0 2013-02-01 armfly 正式发布
- * V1.1 2013-06-09 armfly FiFo结构增加TxCount成员变量,方便判断缓冲区满; 增加 清FiFo的函数
- * V1.2 2014-09-29 armfly 增加RS485 MODBUS接口。接收到新字节后,直接执行回调函数。
- * V1.3 2015-07-23 armfly 增加 UART_T 结构的读写指针几个成员变量必须增加 __IO 修饰,否则优化后
- * 会导致串口发送函数死机。
- * V1.4 2015-08-04 armfly 解决UART4配置bug GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART1);
- * V1.5 2015-10-08 armfly 增加修改波特率的接口函数
- *
- * Copyright (C), 2015-2020
- *
- *********************************************************************************************************
- */
- #include "bsp_uart_fifo.h"
- #include "bsp_time.h"
- #include "sys.h"
- #if 1
- #pragma import(__use_no_semihosting)
- //标准库需要的支持函数
- struct __FILE
- {
- int handle;
- };
- FILE __stdout;
- //定义_sys_exit()以避免使用半主机模式
- void _sys_exit(int x)
- {
- x = x;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: fputc
- * 功能说明: 重定义putc函数,这样可以使用printf函数从串口1打印输出
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int fputc(int ch, FILE *f)
- {
- #if 0 /* 将需要printf的字符通过串口中断FIFO发送出去,printf函数会立即返回 */
- comSendChar(COM1, ch);
- return ch;
- #else /* 采用阻塞方式发送每个字符,等待数据发送完毕 */
- /* 写一个字节到USART1 */
- USART_SendData(USART2, (uint8_t) ch);
- /* 等待发送结束 */
- while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
- {}
- return ch;
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: fgetc
- * 功能说明: 重定义getc函数,这样可以使用getchar函数从串口1输入数据
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int fgetc(FILE *f)
- {
- #if 1 /* 从串口接收FIFO中取1个数据, 只有取到数据才返回 */
- uint8_t ucData;
- while(comGetChar(COM2, &ucData) == 0);
- return ucData;
- #else
- /* 等待串口1输入数据 */
- while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
- return (int)USART_ReceiveData(USART1);
- #endif
- }
- #endif
- /* 定义每个串口结构体变量 */
- #if UART1_FIFO_EN == 1
- static UART_T g_tUart1;
- static uint8_t g_TxBuf1[UART1_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf1[UART1_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- #if UART2_FIFO_EN == 1
- static UART_T g_tUart2;
- static uint8_t g_TxBuf2[UART2_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf2[UART2_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- #if UART3_FIFO_EN == 1
- static UART_T g_tUart3;
- static uint8_t g_TxBuf3[UART3_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf3[UART3_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- #if UART4_FIFO_EN == 1
- static UART_T g_tUart4;
- static uint8_t g_TxBuf4[UART4_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf4[UART4_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- #if UART5_FIFO_EN == 1
- static UART_T g_tUart5;
- static uint8_t g_TxBuf5[UART5_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf5[UART5_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- #if UART6_FIFO_EN == 1
- static UART_T g_tUart6;
- static uint8_t g_TxBuf6[UART6_TX_BUF_SIZE]; /* 发送缓冲区 */
- static uint8_t g_RxBuf6[UART6_RX_BUF_SIZE]; /* 接收缓冲区 */
- #endif
- static void UartVarInit(void);
- static void InitHardUart(void);
- static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen);
- static uint8_t UartGetChar(UART_T *_pUart, uint8_t *_pByte);
- static void UartIRQ(UART_T *_pUart);
- static void ConfigUartNVIC(void);
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_InitUart
- * 功能说明: 初始化串口硬件,并对全局变量赋初值.
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_InitUart(void)
- {
- UartVarInit(); /* 必须先初始化全局变量,再配置硬件 */
- InitHardUart(); /* 配置串口的硬件参数(波特率等) */
- RS485_InitTXE(); /* 配置RS485芯片的发送使能硬件,配置为推挽输出 */
- ConfigUartNVIC(); /* 配置串口中断 */
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ComToUart
- * 功能说明: 将COM端口号转换为UART指针
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * 返 回 值: uart指针
- *********************************************************************************************************
- */
- UART_T *ComToUart(COM_PORT_E _ucPort)
- {
- if (_ucPort == COM1)
- {
- #if UART1_FIFO_EN == 1
- return &g_tUart1;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM2)
- {
- #if UART2_FIFO_EN == 1
- return &g_tUart2;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM3)
- {
- #if UART3_FIFO_EN == 1
- return &g_tUart3;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM4)
- {
- #if UART4_FIFO_EN == 1
- return &g_tUart4;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM5)
- {
- #if UART5_FIFO_EN == 1
- return &g_tUart5;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM6)
- {
- #if UART6_FIFO_EN == 1
- return &g_tUart6;
- #else
- return 0;
- #endif
- }
- else
- {
- /* 不做任何处理 */
- return 0;
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ComToUart
- * 功能说明: 将COM端口号转换为 USART_TypeDef* USARTx
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * 返 回 值: USART_TypeDef*, USART1, USART2, USART3, UART4, UART5
- *********************************************************************************************************
- */
- USART_TypeDef *ComToUSARTx(COM_PORT_E _ucPort)
- {
- if (_ucPort == COM1)
- {
- #if UART1_FIFO_EN == 1
- return USART1;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM2)
- {
- #if UART2_FIFO_EN == 1
- return USART2;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM3)
- {
- #if UART3_FIFO_EN == 1
- return USART3;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM4)
- {
- #if UART4_FIFO_EN == 1
- return UART4;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM5)
- {
- #if UART5_FIFO_EN == 1
- return UART5;
- #else
- return 0;
- #endif
- }
- else if (_ucPort == COM6)
- {
- #if UART6_FIFO_EN == 1
- return USART6;
- #else
- return 0;
- #endif
- }
- else
- {
- /* 不做任何处理 */
- return 0;
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comSendBuf
- * 功能说明: 向串口发送一组数据。数据放到发送缓冲区后立即返回,由中断服务程序在后台完成发送
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * _ucaBuf: 待发送的数据缓冲区
- * _usLen : 数据长度
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void comSendBuf(COM_PORT_E _ucPort, uint8_t *_ucaBuf, uint16_t _usLen)
- {
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
- if (pUart == 0)
- {
- return;
- }
- if (pUart->SendBefor != 0)
- {
- pUart->SendBefor(); /* 如果是RS485通信,可以在这个函数中将RS485设置为发送模式 */
- }
- UartSend(pUart, _ucaBuf, _usLen);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comSendChar
- * 功能说明: 向串口发送1个字节。数据放到发送缓冲区后立即返回,由中断服务程序在后台完成发送
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * _ucByte: 待发送的数据
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void comSendChar(COM_PORT_E _ucPort, uint8_t _ucByte)
- {
- comSendBuf(_ucPort, &_ucByte, 1);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comGetChar
- * 功能说明: 从接收缓冲区读取1字节,非阻塞。无论有无数据均立即返回。
- * 形 参: _ucPort: 端口号(COM1 - COM5)
- * _pByte: 接收到的数据存放在这个地址
- * 返 回 值: 0 表示无数据, 1 表示读取到有效字节
- *********************************************************************************************************
- */
- uint8_t comGetChar(COM_PORT_E _ucPort, uint8_t *_pByte)
- {
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
- if (pUart == 0)
- {
- return 0;
- }
- return UartGetChar(pUart, _pByte);
- }
- uint8_t comRecvBuff(COM_PORT_E _ucPort,uint8_t *buf, uint16_t len)
- {
- uint8_t i = 0;
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
-
- if (pUart == 0)
- {
- return 0;
- }
-
- if(len > pUart->usRxCount) //指定读取长度大于实际接收到的数据长度时
- {
- len=pUart->usRxCount; //读取长度设置为实际接收到的数据长度
- }
-
- for(i=0;i<len;i++) //拷贝接收到的数据到接收指针中
- {
- UartGetChar(pUart,buf+i); //将数据复制到buf中
- }
- return len; //返回实际读取长度
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comClearTxFifo
- * 功能说明: 清零串口发送缓冲区
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void comClearTxFifo(COM_PORT_E _ucPort)
- {
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
- if (pUart == 0)
- {
- return;
- }
- pUart->usTxWrite = 0;
- pUart->usTxRead = 0;
- pUart->usTxCount = 0;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comClearRxFifo
- * 功能说明: 清零串口接收缓冲区
- * 形 参: _ucPort: 端口号(COM1 - COM6)
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void comClearRxFifo(COM_PORT_E _ucPort)
- {
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
- if (pUart == 0)
- {
- return;
- }
- pUart->usRxWrite = 0;
- pUart->usRxRead = 0;
- pUart->usRxCount = 0;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comSetBaud
- * 功能说明: 设置串口的波特率
- * 形 参: _ucPort: 端口号(COM1 - COM5)
- * _BaudRate: 波特率,0-4500000, 最大4.5Mbps
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void comSetBaud(COM_PORT_E _ucPort, uint32_t _BaudRate)
- {
- USART_TypeDef* USARTx;
-
- USARTx = ComToUSARTx(_ucPort);
- if (USARTx == 0)
- {
- return;
- }
-
- USART_SetBaudRate(USARTx, _BaudRate);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: USART_SetBaudRate
- * 功能说明: 修改波特率寄存器,不更改其他设置。如果使用 USART_Init函数, 则会修改硬件流控参数和RX,TX配置
- * 根据固件库中 USART_Init函数,将其中配置波特率的部分单独提出来封装为一个函数
- * 形 参: USARTx : USART1, USART2, USART3, UART4, UART5
- * BaudRate : 波特率,取值 0 - 4500000
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void USART_SetBaudRate(USART_TypeDef* USARTx, uint32_t BaudRate)
- {
- uint32_t tmpreg = 0x00, apbclock = 0x00;
- uint32_t integerdivider = 0x00;
- uint32_t fractionaldivider = 0x00;
- RCC_ClocksTypeDef RCC_ClocksStatus;
- /* Check the parameters */
- assert_param(IS_USART_ALL_PERIPH(USARTx));
- assert_param(IS_USART_BAUDRATE(BaudRate));
- /*---------------------------- USART BRR Configuration -----------------------*/
- /* Configure the USART Baud Rate */
- RCC_GetClocksFreq(&RCC_ClocksStatus);
- if ((USARTx == USART1) || (USARTx == USART6))
- {
- apbclock = RCC_ClocksStatus.PCLK2_Frequency;
- }
- else
- {
- apbclock = RCC_ClocksStatus.PCLK1_Frequency;
- }
- /* Determine the integer part */
- if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
- {
- /* Integer part computing in case Oversampling mode is 8 Samples */
- integerdivider = ((25 * apbclock) / (2 * (BaudRate)));
- }
- else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
- {
- /* Integer part computing in case Oversampling mode is 16 Samples */
- integerdivider = ((25 * apbclock) / (4 * (BaudRate)));
- }
- tmpreg = (integerdivider / 100) << 4;
- /* Determine the fractional part */
- fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
- /* Implement the fractional part in the register */
- if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
- {
- tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
- }
- else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
- {
- tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
- }
- /* Write to USART BRR register */
- USARTx->BRR = (uint16_t)tmpreg;
- }
- /* 如果是RS485通信,请按如下格式编写函数*/
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_InitTXE
- * 功能说明: 配置RS485发送使能口线 TXE
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_InitTXE(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- #if UART1_RS485_EN == 1
- #endif
- #if UART2_RS485_EN == 1
- #endif
- #if UART3_RS485_EN == 1
- #endif
- #if UART4_RS485_EN == 1
- #endif
- #if UART5_RS485_EN == 1
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* 打开GPIO时钟 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /* 设为输出口 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 设为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 无上拉电阻 */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; /* IO口最大速度 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- #endif
- #if UART6_RS485_EN == 1
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* 打开GPIO时钟 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /* 设为输出口 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 设为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 无上拉电阻 */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; /* IO口最大速度 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_SetBaud
- * 功能说明: 修改485串口的波特率。
- * 形 参: _baud : 波特率.0-4500000
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_SetBaud(COM_PORT_E _ucPort,uint32_t _baud)
- {
- comSetBaud(_ucPort, _baud);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_SendBefor
- * 功能说明: 发送数据前的准备工作。对于RS485通信,请设置RS485芯片为发送状态,
- * 并修改 UartVarInit()中的函数指针等于本函数名,比如 g_tUart2.SendBefor = RS485_SendBefor
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_SendBefor(void)
- {
-
- #if UART1_RS485_EN == 1
- #endif
- #if UART2_RS485_EN == 1
- #endif
- #if UART3_RS485_EN == 1
- #endif
- #if UART4_RS485_EN == 1
- #endif
- #if UART5_RS485_EN == 1
- RS485_U5_TX_EN();/* 切换RS485收发芯片为发送模式 */
- #endif
- #if UART6_RS485_EN == 1
- RS485_U6_TX_EN();
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_SendOver
- * 功能说明: 发送一串数据结束后的善后处理。对于RS485通信,请设置RS485芯片为接收状态,
- * 并修改 UartVarInit()中的函数指针等于本函数名,比如 g_tUart2.SendOver = RS485_SendOver
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_SendOver(void)
- {
-
- #if UART1_RS485_EN == 1
- #endif
- #if UART2_RS485_EN == 1
- #endif
- #if UART3_RS485_EN == 1
- #endif
- #if UART4_RS485_EN == 1
- #endif
- #if UART5_RS485_EN == 1
- RS485_U5_RX_EN(); /* 切换RS485收发芯片为接收模式 */
- #endif
- #if UART6_RS485_EN == 1
- RS485_U6_RX_EN();
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_SendBuf
- * 功能说明: 通过RS485芯片发送一串数据。注意,本函数不等待发送完毕。
- * 形 参: _ucaBuf : 数据缓冲区
- * _usLen : 数据长度
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_SendBuf(COM_PORT_E _ucPort,uint8_t *_ucaBuf, uint16_t _usLen)
- {
- comSendBuf(_ucPort, _ucaBuf, _usLen);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_SendStr
- * 功能说明: 向485总线发送一个字符串,0结束。
- * 形 参: _pBuf 字符串,0结束
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void RS485_SendStr(COM_PORT_E _ucPort,char *_pBuf)
- {
- RS485_SendBuf(_ucPort,(uint8_t *)_pBuf, strlen(_pBuf));
- }
- /*
- *********************************************************************************************************
- * 函 数 名: RS485_ReciveNew
- * 功能说明: 接收到新的数据
- * 形 参: _byte 接收到的新数据
- * 返 回 值: 无
- *********************************************************************************************************
- */
- //extern void MODBUS_ReciveNew(uint8_t _byte);
- void RS485_ReciveNew(uint8_t _byte)
- {
- // MODBUS_ReciveNew(_byte);
- }
- uint16_t RS485_Recv(COM_PORT_E _ucPort,uint8_t *buf, uint16_t len)
- {
- uint16_t i = 0;
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
-
- if (pUart == 0)
- {
- return 0;
- }
-
- if(len > pUart->usRxCount) //指定读取长度大于实际接收到的数据长度时
- {
- len=pUart->usRxCount; //读取长度设置为实际接收到的数据长度
- }
-
- for(i=0;i<len;i++) //拷贝接收到的数据到接收指针中
- {
- UartGetChar(pUart,buf+i); //将数据复制到buf中
- }
- return len; //返回实际读取长度
- }
- uint16_t RS485_RecvAtTime(COM_PORT_E _ucPort,uint8_t *buf, uint16_t len,uint32_t timeout)
- {
- //uint8_t i = 0;
- uint16_t recvSize = len;
- uint16_t recvLen = 0;
- //uint8_t tmp[1] = {0};
- UART_T *pUart;
- pUart = ComToUart(_ucPort);
-
- if (pUart == 0)
- {
- return 0;
- }
-
- if(recvSize > pUart->usRxCount) //指定读取长度大于实际接收到的数据长度时
- {
- recvSize=pUart->usRxCount; //读取长度设置为实际接收到的数据长度
- }
- g500usTimerRS485 = timeout;
- while (1)
- {
- if (g500usTimerRS485 == 0) return recvLen;
- UartGetChar(pUart,buf + recvLen);
- recvLen++;
- if (recvLen >= recvSize) return recvSize;
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: UartVarInit
- * 功能说明: 初始化串口相关的变量
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void UartVarInit(void)
- {
- #if UART1_FIFO_EN == 1
- g_tUart1.uart = USART1; /* STM32 串口设备 */
- g_tUart1.pTxBuf = g_TxBuf1; /* 发送缓冲区指针 */
- g_tUart1.pRxBuf = g_RxBuf1; /* 接收缓冲区指针 */
- g_tUart1.usTxBufSize = UART1_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart1.usRxBufSize = UART1_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart1.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart1.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart1.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart1.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart1.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart1.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart1.SendBefor = 0; /* 发送数据前的回调函数 */
- g_tUart1.SendOver = 0; /* 发送完毕后的回调函数 */
- g_tUart1.ReciveNew = 0; /* 接收到新数据后的回调函数 */
- #endif
- #if UART2_FIFO_EN == 1
- g_tUart2.uart = USART2; /* STM32 串口设备 */
- g_tUart2.pTxBuf = g_TxBuf2; /* 发送缓冲区指针 */
- g_tUart2.pRxBuf = g_RxBuf2; /* 接收缓冲区指针 */
- g_tUart2.usTxBufSize = UART2_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart2.usRxBufSize = UART2_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart2.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart2.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart2.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart2.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart2.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart2.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart2.SendBefor = 0; /* 发送数据前的回调函数 */
- g_tUart2.SendOver = 0; /* 发送完毕后的回调函数 */
- g_tUart2.ReciveNew = 0; /* 接收到新数据后的回调函数 */
- #endif
- #if UART3_FIFO_EN == 1
- g_tUart3.uart = USART3; /* STM32 串口设备 */
- g_tUart3.pTxBuf = g_TxBuf3; /* 发送缓冲区指针 */
- g_tUart3.pRxBuf = g_RxBuf3; /* 接收缓冲区指针 */
- g_tUart3.usTxBufSize = UART3_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart3.usRxBufSize = UART3_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart3.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart3.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart3.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart3.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart3.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart3.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart3.SendBefor = 0; /* 发送数据前的回调函数 */
- g_tUart3.SendOver = 0; /* 发送完毕后的回调函数 */
- g_tUart3.ReciveNew = 0; /* 接收到新数据后的回调函数 */
- #endif
- #if UART4_FIFO_EN == 1
- g_tUart4.uart = UART4; /* STM32 串口设备 */
- g_tUart4.pTxBuf = g_TxBuf4; /* 发送缓冲区指针 */
- g_tUart4.pRxBuf = g_RxBuf4; /* 接收缓冲区指针 */
- g_tUart4.usTxBufSize = UART4_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart4.usRxBufSize = UART4_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart4.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart4.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart4.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart4.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart4.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart4.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart4.SendBefor = 0; /* 发送数据前的回调函数 */
- g_tUart4.SendOver = 0; /* 发送完毕后的回调函数 */
- g_tUart4.ReciveNew = 0; /* 接收到新数据后的回调函数 */
- #endif
- #if UART5_FIFO_EN == 1
- g_tUart5.uart = UART5; /* STM32 串口设备 */
- g_tUart5.pTxBuf = g_TxBuf5; /* 发送缓冲区指针 */
- g_tUart5.pRxBuf = g_RxBuf5; /* 接收缓冲区指针 */
- g_tUart5.usTxBufSize = UART5_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart5.usRxBufSize = UART5_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart5.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart5.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart5.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart5.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart5.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart5.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart5.SendBefor = RS485_SendBefor; /* 发送数据前的回调函数 */
- g_tUart5.SendOver = RS485_SendOver; /* 发送完毕后的回调函数 */
- g_tUart5.ReciveNew = RS485_ReciveNew; /* 接收到新数据后的回调函数 */
- #endif
- #if UART6_FIFO_EN == 1
- g_tUart6.uart = USART6; /* STM32 串口设备 */
- g_tUart6.pTxBuf = g_TxBuf6; /* 发送缓冲区指针 */
- g_tUart6.pRxBuf = g_RxBuf6; /* 接收缓冲区指针 */
- g_tUart6.usTxBufSize = UART6_TX_BUF_SIZE; /* 发送缓冲区大小 */
- g_tUart6.usRxBufSize = UART6_RX_BUF_SIZE; /* 接收缓冲区大小 */
- g_tUart6.usTxWrite = 0; /* 发送FIFO写索引 */
- g_tUart6.usTxRead = 0; /* 发送FIFO读索引 */
- g_tUart6.usRxWrite = 0; /* 接收FIFO写索引 */
- g_tUart6.usRxRead = 0; /* 接收FIFO读索引 */
- g_tUart6.usRxCount = 0; /* 接收到的新数据个数 */
- g_tUart6.usTxCount = 0; /* 待发送的数据个数 */
- g_tUart6.SendBefor = RS485_SendBefor; /* 发送数据前的回调函数 */
- g_tUart6.SendOver = RS485_SendOver; /* 发送完毕后的回调函数 */
- g_tUart6.ReciveNew = RS485_ReciveNew; /* 接收到新数据后的回调函数 */
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: InitHardUart
- * 功能说明: 配置串口的硬件参数(波特率,数据位,停止位,起始位,校验位,中断使能)适合于STM32-F4开发板
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void InitHardUart(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- #if UART1_FIFO_EN == 1 /* 串口1 TX = PA9 RX = PA10 或 TX = PB6 RX = PB7*/
- /* 第1步: 配置GPIO */
- #if 1 /* TX = PA9 RX = PA10 */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- /* 将 PA9 映射为 USART1_TX */
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
- /* 将 PA10 映射为 USART1_RX */
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- #else /* TX = PB6 RX = PB7 */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- /* 将 PB6 映射为 USART1_TX */
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
- /* 将 PB7 映射为 USART1_RX */
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- #endif
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART1_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART1, &USART_InitStructure);
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(USART1, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(USART1, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- #if UART2_FIFO_EN == 1 /* 串口2 TX = PD5 RX = PD6 或 TX = PA2, RX = PA3 */
- /* 第1步: 配置GPIO */
- #if 1 /* 串口2 TX = PD5 RX = PD6 */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- /* 将 PD5 映射为 USART2_TX */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
- /* 将 PD6 映射为 USART2_RX */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- #else /* 串口2 TX = PA2, RX = PA3 */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- /* 将 PA2 映射为 USART2_TX. 在STM32-V5板中,PA2 管脚用于以太网 */
- //GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
- /* 将 PA3 映射为 USART2_RX */
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- //GPIO_Init(GPIOA, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- #endif
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART2_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* 选择发接收模式 */
- USART_Init(USART2, &USART_InitStructure);
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(USART2, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(USART2, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- #if UART3_FIFO_EN == 1
- #if 0 /* 串口3 TX = PB10 RX = PB11 */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
- /* 将 PB10 映射为 USART3_TX */
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
- /* 将 PB11 映射为 USART3_RX */
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- #else
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
- /* 将 PD8 映射为 USART3_TX */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
- /* 将 PD9 映射为 USART3_RX */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- #endif
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART3_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART3, &USART_InitStructure);
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(USART3, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(USART3, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- #if UART4_FIFO_EN == 1 /* 串口4 TX = PC10 RX = PC11 */
- /* 第1步: 配置GPIO */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
- /* 将 PC10 映射为 UART4_TX */
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
- /* 将 PC11 映射为 UART4_RX */
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
- /* 配置 USART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 配置 USART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART4_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(UART4, &USART_InitStructure);
- USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(UART4, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(UART4, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- #if UART5_FIFO_EN == 1 /* 串口5 TX = PC12 RX = PD2 */
- /* 第1步: 配置GPIO */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC |RCC_AHB1Periph_GPIOD, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
- /* 将 PC12 映射为 UART5_TX */
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
- /* 将 PD2 映射为 UART5_RX */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
- /* 配置 UART Tx 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 配置 UART Rx 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART5_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(UART5, &USART_InitStructure);
- USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(UART5, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(UART5, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- #if UART6_FIFO_EN == 1 /* PG14/USART6_TX , PC7/USART6_RX,PG8/USART6_RTS, PG15/USART6_CTS */
- /* 第1步: 配置GPIO */
- /* 打开 GPIO 时钟 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
- /* 打开 UART 时钟 */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
- /* 将 PC6 映射为 USART6_TX */
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
- /* 将 PC7 映射为 USART6_RX */
- GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
- /* 配置 PG14/USART6_TX 为复用功能 */
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 配置 PC7/USART6_RX 为复用功能 */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- /* 第2步: 配置串口硬件参数 */
- USART_InitStructure.USART_BaudRate = UART6_BAUD; /* 波特率 */
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- //USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; /* 选择硬件流控 */
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; /* 不要硬件流控 */
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART6, &USART_InitStructure);
- USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); /* 使能接收中断 */
- /*
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- 注意: 不要在此处打开发送中断
- 发送中断使能在SendUart()函数打开
- */
- USART_Cmd(USART6, ENABLE); /* 使能串口 */
- /* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
- 如下语句解决第1个字节无法正确发送出去的问题 */
- USART_ClearFlag(USART6, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ConfigUartNVIC
- * 功能说明: 配置串口硬件中断.
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void ConfigUartNVIC(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /* Configure the NVIC Preemption Priority Bits */
- /* NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); --- 在 bsp.c 中 bsp_Init() 中配置中断优先级组 */
- #if UART1_FIFO_EN == 1
- /* 使能串口1中断 */
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- #if UART2_FIFO_EN == 1
- /* 使能串口2中断 */
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- #if UART3_FIFO_EN == 1
- /* 使能串口3中断t */
- NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- #if UART4_FIFO_EN == 1
- /* 使能串口4中断t */
- NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- #if UART5_FIFO_EN == 1
- /* 使能串口5中断t */
- NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- #if UART6_FIFO_EN == 1
- /* 使能串口6中断t */
- NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #endif
- }
- /*
- *********************************************************************************************************
- * 函 数 名: UartSend
- * 功能说明: 填写数据到UART发送缓冲区,并启动发送中断。中断处理函数发送完毕后,自动关闭发送中断
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen)
- {
- uint16_t i;
-
- for (i = 0; i < _usLen; i++)
- {
- /* 如果发送缓冲区已经满了,则等待缓冲区空 */
- /* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */
- while (1)
- {
- __IO uint16_t usCount;
- // DISABLE_INT();
- usCount = _pUart->usTxCount;
- // ENABLE_INT();
- if (usCount < _pUart->usTxBufSize)
- {
- break;
- }
- else if(usCount == _pUart->usTxBufSize)/* 数据已填满缓冲区 */
- {
- if((_pUart->uart->CR1 & USART_CR1_TXEIE) == 0)
- {
- SET_BIT(_pUart->uart->CR1, USART_CR1_TXEIE);
- }
- }
- }
-
- /* 将新数据填入发送缓冲区 */
- _pUart->pTxBuf[_pUart->usTxWrite] = _ucaBuf[i];
- // DISABLE_INT();
- if (++_pUart->usTxWrite >= _pUart->usTxBufSize)
- {
- _pUart->usTxWrite = 0;
- }
- _pUart->usTxCount++;
- // ENABLE_INT();
- }
- USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: UartGetChar
- * 功能说明: 从串口接收缓冲区读取1字节数据 (用于主程序调用)
- * 形 参: _pUart : 串口设备
- * _pByte : 存放读取数据的指针
- * 返 回 值: 0 表示无数据 1表示读取到数据
- *********************************************************************************************************
- */
- static uint8_t UartGetChar(UART_T *_pUart, uint8_t *_pByte)
- {
- uint16_t usCount;
- /* usRxWrite 变量在中断函数中被改写,主程序读取该变量时,必须进行临界区保护 */
- // DISABLE_INT();
- usCount = _pUart->usRxCount;
- // ENABLE_INT();
- /* 如果读和写索引相同,则返回0 */
- //if (_pUart->usRxRead == usRxWrite)
- if (usCount == 0) /* 已经没有数据 */
- {
- return 0;
- }
- else
- {
- *_pByte = _pUart->pRxBuf[_pUart->usRxRead]; /* 从串口接收FIFO取1个数据 */
- /* 改写FIFO读索引 */
- // DISABLE_INT();
- if (++_pUart->usRxRead >= _pUart->usRxBufSize)
- {
- _pUart->usRxRead = 0;
- }
- _pUart->usRxCount--;
- // ENABLE_INT();
- return 1;
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: comGetBuff
- * 功能说明: 读取指字长度的字符
- * 形 参: _ucPort: 端口号(COM1 - COM5)
- * Buff: 接收到的数据存放在这个地址
- len:要读取的字符长度
- * 返 回 值: 0 读取失败; 非零为读取到的数据长度
- *********************************************************************************************************
- */
- uint16_t comGetBuff(COM_PORT_E _ucPort,uint8_t *Buff, uint16_t RecvSize,uint16_t timeout_MilliSeconds)
- {
- // uint16_t RecvLen = 0;
- // uint8_t ch[1] = {0};
- // if (len == 0 || Buff == NULL) return 0;
- // while (len--)
- // {
- // if (comGetChar (_ucPort,ch) == 1)
- // {
- // Buff[RecvLen++] = ch[0];
- // printf("push : %d\r\n",RecvLen);
- // }
- // if (RecvLen >= len) return RecvLen;
- // }
- // return RecvLen;
- uint16_t RecvLen = 0;
- uint8_t tmp[1] = {0};
- if (RecvSize == 0) return 0;
- g500usTimerUART = timeout_MilliSeconds;
- while (1)
- {
- if (g500usTimerUART == 0) return RecvLen;
- if (comGetChar (_ucPort,tmp) == 1)
- {
- Buff[RecvLen++] = tmp[0];
- }
- if (RecvLen >= RecvSize) return RecvLen;
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: UartIRQ
- * 功能说明: 供中断服务程序调用,通用串口中断处理函数
- * 形 参: _pUart : 串口设备
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void UartIRQ(UART_T *_pUart)
- {
- uint32_t ulReturn;
- /* 进入临界段,临界段可以嵌套 */
- ulReturn = taskENTER_CRITICAL_FROM_ISR();
-
- /* 处理接收中断 */
- if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
- {
- /* 从串口接收数据寄存器读取数据存放到接收FIFO */
- uint8_t ch;
- ch = USART_ReceiveData(_pUart->uart);
- _pUart->pRxBuf[_pUart->usRxWrite] = ch;
- if (++_pUart->usRxWrite >= _pUart->usRxBufSize)
- {
- _pUart->usRxWrite = 0;
- }
-
- if (_pUart->usRxCount < _pUart->usRxBufSize)
- {
- _pUart->usRxCount++;
- }
- /* 回调函数,通知应用程序收到新数据,一般是发送1个消息或者设置一个标记 */
- //if (_pUart->usRxWrite == _pUart->usRxRead)
- //if (_pUart->usRxCount == 1)
- {
- if (_pUart->ReciveNew)
- {
- _pUart->ReciveNew(ch);
- }
- }
- }
- /* 处理发送缓冲区空中断 */
- if (USART_GetITStatus(_pUart->uart, USART_IT_TXE) != RESET)
- {
- //if (_pUart->usTxRead == _pUart->usTxWrite)
- if (_pUart->usTxCount == 0)
- {
- /* 发送缓冲区的数据已取完时, 禁止发送缓冲区空中断 (注意:此时最后1个数据还未真正发送完毕)*/
- USART_ITConfig(_pUart->uart, USART_IT_TXE, DISABLE);
- /* 使能数据发送完毕中断 */
- USART_ITConfig(_pUart->uart, USART_IT_TC, ENABLE);
- }
- else
- {
- /* 从发送FIFO取1个字节写入串口发送数据寄存器 */
- USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
- if (++_pUart->usTxRead >= _pUart->usTxBufSize)
- {
- _pUart->usTxRead = 0;
- }
- _pUart->usTxCount--;
- }
- }
- /* 数据bit位全部发送完毕的中断 */
- else if (USART_GetITStatus(_pUart->uart, USART_IT_TC) != RESET)
- {
- //if (_pUart->usTxRead == _pUart->usTxWrite)
- if (_pUart->usTxCount == 0)
- {
- /* 如果发送FIFO的数据全部发送完毕,禁止数据发送完毕中断 */
- USART_ITConfig(_pUart->uart, USART_IT_TC, DISABLE);
- /* 回调函数, 一般用来处理RS485通信,将RS485芯片设置为接收模式,避免抢占总线 */
- if (_pUart->SendOver)
- {
- _pUart->SendOver();
- }
- }
- else
- {
- /* 正常情况下,不会进入此分支 */
- /* 如果发送FIFO的数据还未完毕,则从发送FIFO取1个数据写入发送数据寄存器 */
- USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
- if (++_pUart->usTxRead >= _pUart->usTxBufSize)
- {
- _pUart->usTxRead = 0;
- }
- _pUart->usTxCount--;
- }
- }
- /* 退出临界段 */
- taskEXIT_CRITICAL_FROM_ISR( ulReturn );
- }
- /*
- *********************************************************************************************************
- * 函 数 名: USART1_IRQHandler USART2_IRQHandler USART3_IRQHandler UART4_IRQHandler UART5_IRQHandler
- * 功能说明: USART中断服务程序
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- #if UART1_FIFO_EN == 1
- void USART1_IRQHandler(void)
- {
- UartIRQ(&g_tUart1);
- }
- #endif
- #if UART2_FIFO_EN == 1
- void USART2_IRQHandler(void)
- {
- UartIRQ(&g_tUart2);
- }
- #endif
- #if UART3_FIFO_EN == 1
- void USART3_IRQHandler(void)
- {
- UartIRQ(&g_tUart3);
- }
- #endif
- #if UART4_FIFO_EN == 1
- void UART4_IRQHandler(void)
- {
- UartIRQ(&g_tUart4);
- }
- #endif
- #if UART5_FIFO_EN == 1
- void UART5_IRQHandler(void)
- {
- UartIRQ(&g_tUart5);
- }
- #endif
- #if UART6_FIFO_EN == 1
- void USART6_IRQHandler(void)
- {
- UartIRQ(&g_tUart6);
- }
- #endif
-
- void RS485_U6_RX_EN(void)
- {
- int i=0;
- for(i=0;i<500;i++)
- {
- ;
- }
- // GPIOA->BSRRH = GPIO_Pin_8;
- GPIO_ResetBits(GPIOA,GPIO_Pin_8);
- for(i=0;i<500;i++)
- {
- ;
- }
- }
- void RS485_U6_TX_EN(void)
- {
- int i=0;
- for(i=0;i<500;i++)
- {
- ;
- }
- // GPIOA->BSRRL = GPIO_Pin_8;
- GPIO_SetBits(GPIOA,GPIO_Pin_8);
- for(i=0;i<500;i++)
- {
- ;
- }
- }
复制代码
|
-
串口数据处理流程
|