從新建工程開始使用C++開發單片機(以STM32為例):五、串口篇(1)UART收發接口(附代碼)

SiO2愛上HF 2022-01-07 16:22:37 阅读数:103

新建 建工 工程 使用 c++

一、STM32 串口UART簡單介紹:

串口通信應該是單片機應用中用的最多的輸出方式,具體的傳輸協議內容就不進行介紹了,各比特大佬應該都會。STM32大容量處理器有5個串口(USART1,USART2,UART3~UART5),對於中容量的處理器有3個串口,小容量的有2個。本文中將會介紹串口的初始化、輸出、輸入接口以及串口接收緩沖區的管理。目前采用的傳輸方式為8數據比特、1停止比特、無校驗比特、對於USART無硬件流控,以後進行擴展的之後再來更新。
由於STM32不同型號的處理器,串口的數量不同,因此采用宏的方式來確定串口的數量,防止操作處理器不存在的串口而引起錯誤

#ifdef STM32F10X_HD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_SERIAL3
#define HAVE_SERIAL4
#define HAVE_SERIAL5
#define HAVE_I2C1
#define HAVE_I2C2
#define HAVE_SPI1
#define HAVE_SPI2
#define HAVE_SPI3
#elif STM32F10X_MD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_SERIAL3
#define HAVE_I2C1
#define HAVE_I2C2
#define HAVE_SPI1
#define HAVE_SPI2
#elif STM32F10X_LD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_I2C1
#define HAVE_SPI1
#endif

二、初始化和串口輸出接口

請添加圖片描述

1.枚舉:

/** * @brief 串口枚舉 \n * UART_1 串口1,以此類推 */
typedef enum
{

#ifdef HAVE_SERIAL1
UART_1 = (uint32_t)USART1,
#endif
#ifdef HAVE_SERIAL2
UART_2 = (uint32_t)USART2,
#endif
#ifdef HAVE_SERIAL3
UART_3 = (uint32_t)USART3,
#endif
#ifdef HAVE_SERIAL4
UART_4 = (uint32_t)UART4,
#endif
#ifdef HAVE_SERIAL5
UART_5 = (uint32_t)UART5,
#endif
UART_END//占比特,沒有用
} UART_enum;

2.函數接口
2.1 void uart_init(UART_enum uart, uint32_t baudrate):串口初始化

/************************************************************************* * @brief 初始化串口 * @param[in] uart 要初始化的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] baudrate 串口通信波特率 * @return 無 * @note 該函數默認使用 8N1(8數據比特,無校驗比特,1比特停止比特)模式,可在 my_uart.h中 * 對應宏進行修改 * @example uart_init(UART1, 115200) 初始化 UART1 並使能,波特率為115200 * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_init(UART_enum uart, uint32_t baudrate);

2,2 void uart_write_byte(UART_enum uart, uint8_t data):串口輸出一個字節

/************************************************************************* * @brief 串口輸出一個字節數據 * @param[in] uart 要輸出字節的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] data 輸出的字節數據 * @return 無 * @note 調用前應先對串口進行初始化 * @example uart_write_byte(UART1, 'a') 串口1輸出字節數據'a' * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
inline void uart_write_byte(UART_enum uart, uint8_t data);

2.3 void uart_write_buffer(UART_enum uart, const uint8_t *buf, int len) 串口輸出二進制數據

/************************************************************************* * @brief 串口輸出二進制數據(如輸出結構體、二進制數據) * @param[in] uart 要輸出字節的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] buf 二進制數據指針 * @param[in] len 二進制數據長度 * @return 無 * @note 調用前應先對串口進行初始化,調用時應注意二進制數據長度,不要越界! * @example uart_write_buffer(UART1, buf, 10) * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_write_buffer(UART_enum uart, const uint8_t *buf, int len);

2.4 void uart_write_string(UART_enum uart, const char *str):串口輸出C語言字符串

/************************************************************************* * @brief 串口輸出字符串 * @param[in] uart 要輸出字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] str 要輸出的字符串 * @return 無 * @note 調用前應先對串口進行初始化 * @example uart_write_string(UART_1, "hello world");串口1打印 hello world * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_write_string(UART_enum uart, const char *str);

三、串口接收、接收中斷和緩沖區管理

1 緩沖區結構 : 串口接收緩沖區大小為256個字節,讀指針和寫指針為uint8_t類型,所以當讀寫指針移動到緩沖區末尾後就會自動回到緩沖區頭部,形成循環隊列,如果緩沖區滿了,串口接收中斷就會忽略新收到的數據,直到將緩沖區的數據讀出。每個串口都有一個接收緩沖區,由串口接收中斷服務函數進行管理。串口接收的讀取接口實際上就是讀取緩沖區中的內容,對中斷服務函數的進行了屏蔽。

typedef struct
{

volatile uint8_t buf[256]; //接收緩沖區
volatile uint8_t write_index; //寫指針
volatile uint8_t read_index; //讀指針
volatile uint16_t data_size; //緩沖區接收到的數據長度
/* data */
}__rec_buf;

2.串口接收接口
2.1 uint16_t uart_rec_size(UART_enum uart) 獲取串口緩沖區接收數據長度

/************************************************************************* * @brief 獲取串口緩沖區接收數據長度 * @param[in] uart 要接收字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @return 串口緩沖區接收到數據的長度 * @note 串口緩沖區最大為256個字節 * @history 2021-12-2:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
uint16_t uart_rec_size(UART_enum uart)

2.2 uint8_t uart_read_byte(UART_enum uart) 從串口緩沖區讀取一個數據。該函數會讀取串口緩沖區的接收長度,如果緩沖區長度為0就會等待直到緩沖區收到數據。讀取數據後,會更新長度和讀指針。該函數可以配合 uart_rec_size(~)使用, 通過判斷緩沖區接收長度,來防止函數阻滯,類似於Windows控制臺中的_kbhit()和getch()的配合使用。

/************************************************************************* * @brief 從串口緩沖區讀取一個數據 * @param[in] uart 要接收字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @return 讀取到的值 * @note 該函數為阻滯函數 * @history 2021-12-2:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
uint8_t uart_read_byte(UART_enum uart)

3.串口接收中斷(以串口1為例)
上面已經說過,串口接收中斷用於管理串口接收緩沖區,因此在串口初始化後,串口接收完全自動進行,不需要代碼進行幹預,從而實現了中斷函數的屏蔽。對於上層的接口看來,似乎不存在中斷函數,串口的讀取就是對緩沖區的讀取。

#ifdef HAVE_SERIAL1
__rec_buf UART1_recbuf;
void USART1_IRQHandler(void)
{

if (USART_GetITStatus(USART1, USART_IT_RXNE))
{

if (UART1_recbuf.data_size >= 256)
{

// uart_write_string(UART_1, "UART1 recbuf fill!\r\n");
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
return;
}
uint16_t recdata = USART_ReceiveData(USART1);
UART1_recbuf.buf[UART1_recbuf.write_index++] = (uint8_t)recdata;
UART1_recbuf.data_size++;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
#endif

附:完整代碼

/*file:resources.h*/
#ifndef __RESOURCES_H
#define __RESOURCES_H
#ifdef __cplusplus
extern "C" {

#endif
#include "stm32f10x.h" 
/** * @brief GPIO口枚舉 \n * A0:GPIOA,P0口,其他以此類推 */
typedef enum
{

A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,
B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12,B13,B14,B15,
C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,
D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,
E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13,E14,E15,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,F14,F15,
G0,G1,G2,G3,G4,G5,G6,G7,G8,G9,G10,G11,G12,G13,G14,G15,
Pin_null
}Pin_enum;
typedef struct
{

volatile uint8_t buf[256]; //接收緩沖區
volatile uint8_t write_index; //寫指針
volatile uint8_t read_index; //讀指針
volatile uint16_t data_size; //緩沖區接收到的數據長度
/* data */
}__rec_buf;
#ifdef STM32F10X_HD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_SERIAL3
#define HAVE_SERIAL4
#define HAVE_SERIAL5
#define HAVE_I2C1
#define HAVE_I2C2
#define HAVE_SPI1
#define HAVE_SPI2
#define HAVE_SPI3
#elif STM32F10X_MD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_SERIAL3
#define HAVE_I2C1
#define HAVE_I2C2
#define HAVE_SPI1
#define HAVE_SPI2
#elif STM32F10X_LD
#define HAVE_SERIAL1
#define HAVE_SERIAL2
#define HAVE_I2C1
#define HAVE_SPI1
#endif
#ifdef __cplusplus
}
#endif
#endif
/*file:my_usart.h*/
/************************************************************************** * @brief : STM32 USART * @author : 龔為瑋(1461041096) * @copyright : 版權信息 * @version : v1.0 * @note : 無 * @history : 2021年11月20日:創建文件 * 2021年11月22日:完成串口初始化功能、串口基礎write功能 * 並對UART1進行了輸出測試,測試通過 * 2021年11月22日:添加注釋 * 2021年11月23日:對UART2~UART5進行了輸出測試,測試通過 * 2021年12月3日: 完成了串口接收相關接口,對UART1進行了測試 * 2021年12月13日:發現UART4和UART5無法接收,原因不明 * 2021年12月14日:解决了13日發現的問題,目前所有串口經過測試輸入輸 * 出可用 ***************************************************************************/
#ifndef __MY_USART_H
#define __MY_USART_H
#ifdef __cplusplus
extern "C" {

#endif
#include "stm32f10x_usart.h"
#include "my_afio.h"
#include "my_gpio.h"
/** * @brief 串口枚舉 \n * UART_1 串口1,以此類推 */
typedef enum
{

#ifdef HAVE_SERIAL1
UART_1 = (uint32_t)USART1,
#endif
#ifdef HAVE_SERIAL2
UART_2 = (uint32_t)USART2,
#endif
#ifdef HAVE_SERIAL3
UART_3 = (uint32_t)USART3,
#endif
#ifdef HAVE_SERIAL4
UART_4 = (uint32_t)UART4,
#endif
#ifdef HAVE_SERIAL5
UART_5 = (uint32_t)UART5,
#endif
UART_END//占比特,沒有用
} UART_enum;
#define DEFAULT_UART_WORDLENGTH USART_WordLength_8b //默認8比特數據比特
#define DEFAULT_UART_STOPBITS USART_StopBits_1 //默認1比特停止比特
#define DEFAULT_UART_PARITY USART_Parity_No //默認無校驗比特
#define DEFAULT_UART_FLOWCONTROL USART_HardwareFlowControl_None //默認無硬件流控
#ifdef HAVE_SERIAL1
extern __rec_buf UART1_recbuf;
#endif
#ifdef HAVE_SERIAL2
extern __rec_buf UART2_recbuf;
#endif
#ifdef HAVE_SERIAL3
extern __rec_buf UART3_recbuf;
#endif
#ifdef HAVE_SERIAL4
extern __rec_buf UART4_recbuf;
#endif
#ifdef HAVE_SERIAL5
extern __rec_buf UART5_recbuf;
#endif
void uart_init(UART_enum uart, uint32_t baudrate);
void uart_write_byte(UART_enum uart, uint8_t data);
void uart_write_buffer(UART_enum uart, const uint8_t *buf, int len);
void uart_write_string(UART_enum uart, const char *str);
uint16_t uart_rec_size(UART_enum uart);
uint8_t uart_read_byte(UART_enum uart);
#ifdef __cplusplus
}
#endif
#endif
/*file:my_usart.c*/
/************************************************************************** * @brief : STM32 USART * @author : 龔為瑋(1461041096) * @copyright : 版權信息 * @version : v1.0 * @note : 無 * @history : 2021年11月20日:創建文件 * 2021年11月22日:完成串口初始化功能、串口基礎write功能 * 並對UART1進行了輸出測試,測試通過 * 2021年11月22日:添加注釋 * 2021年11月23日:對UART2~UART5進行了輸出測試,測試通過 * 2021年12月3日: 完成了串口接收相關接口,對UART1進行了測試 * 2021年12月13日:發現UART4和UART5無法接收,原因不明 * 2021年12月14日:解决了13日發現的問題,目前所有串口經過測試輸入輸 * 出可用 ***************************************************************************/
#include "my_usart.h"
#include "string.h"
/** * @brief 串口默認引脚 \n *UART1_TX:串口1TX引脚,UART1_RX:串口1RX引脚,以此類推 */
typedef enum
{

#ifdef HAVE_SERIAL1
UART1_TX = A9,
UART1_RX = A10,
#endif
#ifdef HAVE_SERIAL2
UART2_TX = A2,
UART2_RX = A3,
#endif
#ifdef HAVE_SERIAL3
UART3_TX = B10,
UART3_RX = B11,
#endif
#ifdef HAVE_SERIAL4
UART4_TX = C10,
UART4_RX = C11,
#endif
#ifdef HAVE_SERIAL5
UART5_TX = C12,
UART5_RX = D2,
#endif
UARTn_Pin_End //占比特,沒用
} UART_pin;
/************************************************************************* * @brief 初始化串口 * @param[in] uart 要初始化的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] baudrate 串口通信波特率 * @return 無 * @note 該函數默認使用 8N1(8數據比特,無校驗比特,1比特停止比特)模式,可在 my_uart.h中 * 對應宏進行修改 * @example uart_init(UART1, 115200) 初始化 UART1 並使能,波特率為115200 * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_init(UART_enum uart, uint32_t baudrate)
{

Pin_enum uart_tx, uart_rx;
uint8_t USARTx_IRQn;
switch (uart)
{

#ifdef HAVE_SERIAL1
case UART_1:
uart_tx = (Pin_enum)UART1_TX, uart_rx = (Pin_enum)UART1_RX;
memset((void *)&UART1_recbuf, 0, sizeof(UART1_recbuf));
USARTx_IRQn = USART1_IRQn;
break;
#endif
#ifdef HAVE_SERIAL2
case UART_2:
uart_tx = (Pin_enum)UART2_TX, uart_rx = (Pin_enum)UART2_RX;
memset((void *)&UART2_recbuf, 0, sizeof(UART2_recbuf));
USARTx_IRQn = USART2_IRQn;
break;
#endif
#ifdef HAVE_SERIAL3
case UART_3:
uart_tx = (Pin_enum)UART3_TX, uart_rx = (Pin_enum)UART3_RX;
memset((void *)&UART3_recbuf, 0, sizeof(UART3_recbuf));
USARTx_IRQn = USART3_IRQn;
break;
#endif
#ifdef HAVE_SERIAL4
case UART_4:
uart_tx = (Pin_enum)UART4_TX, uart_rx = (Pin_enum)UART4_RX;
memset((void *)&UART4_recbuf, 0, sizeof(UART4_recbuf));
USARTx_IRQn = UART4_IRQn;
break;
#endif
#ifdef HAVE_SERIAL5
case UART_5:
uart_tx = (Pin_enum)UART5_TX, uart_rx = (Pin_enum)UART5_RX;
memset((void *)&UART5_recbuf, 0, sizeof(UART5_recbuf));
USARTx_IRQn = UART5_IRQn;
break;
#endif
default:
return;
}
//獲取UART對應引脚
gpio_init(uart_rx, INPUT);
afio_init(uart_tx, OUT_PP_AF);
//初始化UART RX、TX引脚
if (uart == UART_1)
{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}
else
{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 << (((uint32_t)uart - (uint32_t)UART_2) / 0x0400), ENABLE);
}
//使能UART時鐘
USART_InitTypeDef uart_inittype;
uart_inittype.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //開啟TX、RX模式
uart_inittype.USART_BaudRate = baudrate; //設置波特率
uart_inittype.USART_StopBits = DEFAULT_UART_STOPBITS; //設置停止比特
uart_inittype.USART_Parity = DEFAULT_UART_PARITY; //設置校驗比特
uart_inittype.USART_WordLength = DEFAULT_UART_WORDLENGTH; //設置數據比特長度
uart_inittype.USART_HardwareFlowControl = DEFAULT_UART_FLOWCONTROL; //設置硬件流控
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
USART_Init((USART_TypeDef *)uart, &uart_inittype); //初始化UART
USART_Cmd((USART_TypeDef *)uart, ENABLE); //使能UART
USART_ITConfig((USART_TypeDef *)uart, USART_IT_RXNE, ENABLE); //開啟ENABLE/關閉DISABLE中斷
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器
USART_ClearFlag((USART_TypeDef *)uart, USART_FLAG_TC);
uart_write_byte(uart,0);
}
/*****************************串口輸出相關接口*****************************/
/************************************************************************* * @brief 串口輸出一個字節數據 * @param[in] uart 要輸出字節的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] data 輸出的字節數據 * @return 無 * @note 調用前應先對串口進行初始化 * @example uart_write_byte(UART1, 'a') 串口1輸出字節數據'a' * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
inline void uart_write_byte(UART_enum uart, uint8_t data)
{

USART_SendData((USART_TypeDef *)uart, (uint16_t)data);
while (USART_GetFlagStatus((USART_TypeDef *)uart, USART_FLAG_TC) == RESET)
;
}
/************************************************************************* * @brief 串口輸出二進制數據(如輸出結構體、二進制數據) * @param[in] uart 要輸出字節的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] buf 二進制數據指針 * @param[in] len 二進制數據長度 * @return 無 * @note 調用前應先對串口進行初始化,調用時應注意二進制數據長度,不要越界! * @example uart_write_buffer(UART1, buf, 10) * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_write_buffer(UART_enum uart, const uint8_t *buf, int len)
{

for (int i = 0; i < len; i++)
{

uart_write_byte(uart, (uint16_t)buf[i]);
}
}
/************************************************************************* * @brief 串口輸出字符串 * @param[in] uart 要輸出字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @param[in] str 要輸出的字符串 * @return 無 * @note 調用前應先對串口進行初始化 * @example uart_write_string(UART_1, "hello world");串口1打印 hello world * @history 2021-11-22:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
void uart_write_string(UART_enum uart, const char *str)
{

int len = strlen(str);
for (int i = 0; i < len; i++)
{

uart_write_byte(uart, (uint16_t)str[i]);
}
}
/*****************************串口接收相關接口*****************************/
/************************************************************************* * @brief 選擇串口接收對應的緩沖區 * @param[in] uart 要接收字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @return 串口接收緩沖區指針 * @note 內部調用 * @history 2021-12-2:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
__rec_buf *select_buf(UART_enum uart)
{

switch (uart)
{

#ifdef HAVE_SERIAL1
case UART_1:
return &UART1_recbuf;
#endif
#ifdef HAVE_SERIAL2
case UART_2:
return &UART2_recbuf;
#endif
#ifdef HAVE_SERIAL3
case UART_3:
return &UART3_recbuf;
#endif
#ifdef HAVE_SERIAL4
case UART_4:
return &UART4_recbuf;
#endif
#ifdef HAVE_SERIAL5
case UART_5:
return &UART5_recbuf;
#endif
default:
return 0;
}
}
/************************************************************************* * @brief 獲取串口緩沖區接收數據長度 * @param[in] uart 要接收字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @return 串口緩沖區接收到數據的長度 * @note 串口緩沖區最大為256個字節 * @history 2021-12-2:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
uint16_t uart_rec_size(UART_enum uart)
{

__rec_buf *uart_recbuf = select_buf(uart);
return uart_recbuf->data_size;
}
/************************************************************************* * @brief 從串口緩沖區讀取一個數據 * @param[in] uart 要接收字符串的串口 (可選擇的值在 my_uart.h UART_enum枚舉中) * 此參數可以是以下值之一: * UART1 UART2 UART3 UART4 UART5 * @return 讀取到的值 * @note 該函數為阻滯函數 * @history 2021-12-2:創建,完成功能並使用 USART1 進行測試,測試通過 ************************************************************************/
uint8_t uart_read_byte(UART_enum uart)
{

__rec_buf *uart_recbuf = select_buf(uart);
while (uart_recbuf->data_size == 0) //等待串口緩沖區接收到數據
;
uint8_t res = uart_recbuf->buf[uart_recbuf->read_index++];
uart_recbuf->data_size--;
return res;
}
/***********************串口接收中斷***************************************/
#ifdef HAVE_SERIAL1
__rec_buf UART1_recbuf;
void USART1_IRQHandler(void)
{

if (USART_GetITStatus(USART1, USART_IT_RXNE))
{

if (UART1_recbuf.data_size >= 256)
{

// uart_write_string(UART_1, "UART1 recbuf fill!\r\n");
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
return;
}
uint16_t recdata = USART_ReceiveData(USART1);
UART1_recbuf.buf[UART1_recbuf.write_index++] = (uint8_t)recdata;
UART1_recbuf.data_size++;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
#endif
#ifdef HAVE_SERIAL2
__rec_buf UART2_recbuf;
void USART2_IRQHandler(void)
{

if (USART_GetITStatus(USART2, USART_IT_RXNE))
{

uint16_t recdata = USART_ReceiveData(USART2);
if (UART2_recbuf.data_size >= 256)
{

// uart_write_string(UART_2, "UART2 recbuf fill!\r\n");
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
return;
}
UART2_recbuf.buf[UART2_recbuf.write_index++] = (uint8_t)recdata;
UART2_recbuf.data_size++;
}
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
#endif
#ifdef HAVE_SERIAL3
__rec_buf UART3_recbuf;
void USART3_IRQHandler(void)
{

if (USART_GetITStatus(USART3, USART_IT_RXNE))
{

uint16_t recdata = USART_ReceiveData(USART3);
if (UART3_recbuf.data_size >= 256)
{

// uart_write_string(UART_3, "UART3 recbuf fill!\r\n");
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
return;
}
UART3_recbuf.buf[UART3_recbuf.write_index++] = (uint8_t)recdata;
UART3_recbuf.data_size++;
}
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
#endif
#ifdef HAVE_SERIAL4
__rec_buf UART4_recbuf;
void UART4_IRQHandler(void)
{

if (USART_GetITStatus(UART4, USART_IT_RXNE))
{

uint16_t recdata = USART_ReceiveData(UART4);
if (UART4_recbuf.data_size >= 256)
{

// uart_write_string(UART_4, "UART1 recbuf fill!\r\n");
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
return;
}
UART4_recbuf.buf[UART4_recbuf.write_index++] = (uint8_t)recdata;
UART4_recbuf.data_size++;
}
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
}
#endif
#ifdef HAVE_SERIAL5
__rec_buf UART5_recbuf;
void UART5_IRQHandler(void)
{

if (USART_GetITStatus(UART5, USART_IT_RXNE))
{

uint16_t recdata = USART_ReceiveData(UART5);
if (UART5_recbuf.data_size >= 256)
{

// uart_write_string(UART_5, "UART1 recbuf fill!\r\n");
USART_ClearITPendingBit(UART5, USART_IT_RXNE);
return;
}
UART5_recbuf.buf[UART5_recbuf.write_index++] = (uint8_t)recdata;
UART5_recbuf.data_size++;
}
USART_ClearITPendingBit(UART5, USART_IT_RXNE);
}
#endif
版权声明:本文为[SiO2愛上HF]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201071622368493.html