APM32E030的USART驱动(中断)
本帖最后由 口天土立口 于 2025-9-7 18:33 编辑APM32E030支持USART外设最高速度可达6Mbit/s.
USART驱动代码如下:
/* 串口 */
#define UART_INS (USART1)
/* 接收数据大小 */
#define UART_RX_LEN (512)
/* 接收缓存 */
uint8_t rx_buf;
/* 接收长度 */
uint16_t rx_len;
/* 接收完成 */
uint16_t rx_complete;
/* 发送索引 */
uint16_t tx_index;
/* 发送长度 */
uint16_t tx_len;
/* 发送缓存 */
uint8_t *tx_buf;/*
* @brief 初始化
*
* @param None
*
* @retval None
*
*/
void bsp_uart_init(void)
{
GPIO_Config_T gpioConfig;
USART_Config_T configStruct;
/* GPIO */
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
GPIO_ConfigStructInit(&gpioConfig);
gpioConfig.pin = GPIO_PIN_6 | GPIO_PIN_7;
gpioConfig.mode = GPIO_MODE_AF;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.pupd = GPIO_PUPD_NO;
GPIO_Config(GPIOB, &gpioConfig);
/* TX */
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_6, GPIO_AF_PIN0);
/* RX */
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_7, GPIO_AF_PIN0);
/* USART */
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
USART_Reset(UART_INS);
USART_ConfigStructInit(&configStruct);
configStruct.baudRate = 115200;
configStruct.wordLength = USART_WORD_LEN_8B;
configStruct.stopBits = USART_STOP_BIT_1;
configStruct.parity = USART_PARITY_NONE ;
configStruct.mode = USART_MODE_TX_RX;
configStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
USART_Config(UART_INS, &configStruct);
/* 关闭发送为空中断 */
USART_DisableInterrupt(UART_INS, USART_INT_TXBEIE);
/* 使能接收非空中断 */
USART_EnableInterrupt(UART_INS, USART_INT_RXBNEIE);
/* 使能空闲中断 */
USART_EnableInterrupt(UART_INS, USART_INT_IDLEIE);
/* 使能中断 */
NVIC_SetPriority(USART1_IRQn, 0);
NVIC_EnableIRQ(USART1_IRQn);
/* 使能串口 */
USART_Enable(UART_INS);
}/*
* @brief 串口中断
*
* @param None
*
* @retval None
*
*/
void USART1_IRQHandler(void)
{
/* 发送为空 */
if (USART_ReadIntFlag(UART_INS, USART_INT_FLAG_TXBE) != RESET) {
if (tx_index < tx_len) {
/* 发数据 */
USART_TxData(UART_INS, tx_buf);
} else {
/* 关闭发送 */
USART_DisableInterrupt(UART_INS, USART_INT_TXBEIE);
}
}
/* 接收非空 */
if (USART_ReadIntFlag(UART_INS, USART_INT_FLAG_RXBNE) != RESET) {
rx_buf = USART_RxData(UART_INS);
}
/* 空闲 */
if (USART_ReadIntFlag(UART_INS, USART_INT_FLAG_IDLE) != RESET) {
USART_ClearIntFlag(UART_INS, USART_INT_FLAG_IDLE);
rx_complete = 1;
}
}/*
* @brief 发送数据
*
* @param buf: 数据缓存
* buf_len: 缓存大小
*
* @retval None
*
*/
void bsp_uart_send(uint8_t *buf, uint16_t buf_len)
{
if ((buf != NULL) && (buf_len > 0)) {
tx_buf = buf;
tx_index = 0;
tx_len = buf_len;
/* 开启发送为空中断 */
USART_EnableInterrupt(UART_INS, USART_INT_TXBEIE);
}
}/*
* @brief 接收完成
*
* @param None
*
* @retval 0: 未完成; 1: 完成
*
*/
uint8_t bsp_is_rx_complete(void)
{
uint8_t ret = rx_complete;
rx_complete = 0;
return ret;
}/*
* @brief 获取接收长度
*
* @param None
*
* @retval 接收数据长度
*
*/
uint16_t bsp_get_rx_len(void)
{
uint16_t ret = rx_len;
rx_len = 0;
return ret;
}
测试代码如下:
// 应用初始化
void app_init(void)
{
bsp_uart_init();
}
// 应用任务
void app_task(void)
{
/* 接收完成再发出来 */
if (bsp_is_rx_complete() != 0) {
bsp_uart_send(bsp_get_rx_buf(), bsp_get_rx_len());
}
}
详细代码,请查看附件:
楼主您倒是测试一下 6Mbps的速率啊 如果是发送的话,使用中断的方式是不是意义不大啊 DawnFervor 发表于 2025-10-7 17:25
如果是发送的话,使用中断的方式是不是意义不大啊
中断不用干等发送完,就能直接开始后续的工作,效率高一些 串口发送我倾向于使用DMA来完成 不错,不错。
谢谢楼主分享 像这种中断处理方式,是不是先把中断标志状态寄存器读出来,再分别判断更好一些啊 代码中使用了中断方式来处理USART的发送和接收,这是提高效率的好方法
页:
[1]