mcu 串口外设简介
该芯片内置多达 6 个通用同步/异步收发器,USART1/6 接口通信速率可达 10.5Mbit/s,其它USART/UART 的通信速率可达 5.25Mbit/s,所有 USART/UART 可配置波特率、奇偶校验位、停止位、数据位长度,都可以支持 DMA
函数库
本函数库主要是用来后期开发方便使用,将所有的变量封装在一个结构体内部
该函数库使用的是接收非空中断+空闲中断的方式收数据
头文件
#ifndef __BSP_USART_IT_H
#include "bsp_delay.h"
#include "apm32f4xx.h"
#include "apm32f4xx_gpio.h"
#include "apm32f4xx_eint.h"
#include "apm32f4xx_rcm.h"
#include "apm32f4xx_syscfg.h"
#include "apm32f4xx_misc.h"
#include "apm32f4xx_usart.h"
//缓冲区的大小
#define RX_BUFF_SIZE 256
//串口id定义,对外部的操作均使用该id操作
typedef enum
{
UART_1,
UART_2,
UART_NUM
}em_uart_id;
//数据发送函数
void bsp_uart_send_data(em_uart_id id,uint8_t *dat, uint32_t count);
//初始化所有配置的串口
void bsp_uart_it_init_all(void);
//接收数据
void bsp_uart_recv_data(em_uart_id id,uint8_t *dat, uint32_t *count);
#endif
源文件
/* Includes */
#include "../usart_it/bsp_uart_it.h"
#include <string.h>
typedef struct
{
GPIO_T *tx_gpio_grp;
GPIO_PIN_T tx_pin;
uint32_t tx_rcc;
GPIO_PIN_SOURCE_T tx_pin_source;
GPIO_T *rx_gpio_grp;
GPIO_PIN_T rx_pin;
uint32_t rx_rcc;
GPIO_PIN_SOURCE_T rx_pin_source;
GPIO_AF_T gpio_af;
USART_T *uart;
IRQn_Type irq;
uint32_t uart_rcc;
uint8_t rx_buff[RX_BUFF_SIZE];
uint16_t rx_count;
uint16_t idle;
} uart_it_t;
static uart_it_t uarts_it[]=
{
{ GPIOA,GPIO_PIN_9,RCM_AHB1_PERIPH_GPIOA,GPIO_PIN_SOURCE_9,
GPIOA,GPIO_PIN_10,RCM_AHB1_PERIPH_GPIOA,GPIO_PIN_SOURCE_10,GPIO_AF_USART1,
USART1,USART1_IRQn,RCM_APB2_PERIPH_USART1
},
{ GPIOA,GPIO_PIN_2,RCM_AHB1_PERIPH_GPIOA,GPIO_PIN_SOURCE_2,
GPIOA,GPIO_PIN_3,RCM_AHB1_PERIPH_GPIOA,GPIO_PIN_SOURCE_3,GPIO_AF_USART2,
USART2,USART2_IRQn,RCM_APB1_PERIPH_USART2
},
};
static void bsp_uart_it_config(uart_it_t *puart)
{
USART_Config_T usartConfigStruct;
usartConfigStruct.baudRate = 115200;
usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
usartConfigStruct.mode = USART_MODE_TX_RX;
usartConfigStruct.parity = USART_PARITY_NONE;
usartConfigStruct.stopBits = USART_STOP_BIT_1;
usartConfigStruct.wordLength = USART_WORD_LEN_8B;
if (puart->uart == USART1 || puart->uart == USART6)
{
RCM_EnableAPB2PeriphClock(puart->uart_rcc);
}
else
{
RCM_EnableAPB1PeriphClock(puart->uart_rcc);
}
/** USART configuration */
USART_Config(puart->uart, &usartConfigStruct);
/** Enable USART1 RXBNE interrput */
USART_EnableInterrupt(puart->uart, USART_INT_RXBNE);
USART_EnableInterrupt(puart->uart,USART_INT_IDLE);
USART_ClearStatusFlag(puart->uart, USART_FLAG_RXBNE);
NVIC_EnableIRQRequest(puart->irq,1,0);
/** Enable USART */
USART_Enable(puart->uart);
}
static void bsp_uart_it_gpio_config(uart_it_t *puart)
{
GPIO_Config_T GPIO_configStruct;
GPIO_ConfigStructInit(&GPIO_configStruct);
/** 使能gpio的rcc*/
RCM_EnableAHB1PeriphClock(puart->tx_rcc|puart->rx_rcc );
/** Connect PXx to USARTx_Tx */
GPIO_ConfigPinAF(puart->tx_gpio_grp, puart->tx_pin_source, puart->gpio_af);
/** Connect PXx to USARTx_Rx */
GPIO_ConfigPinAF(puart->rx_gpio_grp, puart->rx_pin_source, puart->gpio_af);
/** Configure USART Tx as alternate function push-pull */
GPIO_configStruct.mode = GPIO_MODE_AF;
GPIO_configStruct.pin = puart->tx_pin;
GPIO_configStruct.speed = GPIO_SPEED_50MHz;
GPIO_Config(puart->tx_gpio_grp, &GPIO_configStruct);
/** Configure USART Rx as input floating */
GPIO_configStruct.mode = GPIO_MODE_AF;
GPIO_configStruct.pin = puart->rx_pin;
GPIO_Config(puart->rx_gpio_grp, &GPIO_configStruct);
}
void bsp_uart_it_init_all(void)
{
for(int i=0; i<UART_NUM; i++)
{
bsp_uart_it_gpio_config(uarts_it+i);
bsp_uart_it_config(uarts_it+i);
}
}
void bsp_uart_send_data(em_uart_id id,uint8_t *dat, uint32_t count)
{
uart_it_t *puart;
if(UART_NUM>id)
puart = uarts_it+id;
while(puart && count--)
{
while(USART_ReadStatusFlag(puart->uart, USART_FLAG_TXBE) == RESET);
USART_TxData(puart->uart, *dat++);
}
}
#define min(num0,num1) (num0>num1?num1:num0)
void bsp_uart_recv_data(em_uart_id id,uint8_t *dat, uint32_t *count)
{
uart_it_t *puart;
if(UART_NUM>id)
puart = uarts_it+id;
if(puart && dat&&count)
{
*count = min(puart->rx_count,*count);
memcpy(dat, puart->rx_buff,*count);
puart->rx_count=0;
}
else{
*count=0;
}
}
static void bsp_uart_ira_handler(uart_it_t *puart)
{
if(USART_ReadIntFlag(puart->uart, USART_INT_RXBNE) == SET)
{
USART_ClearIntFlag(puart->uart, USART_INT_RXBNE);
puart->rx_buff[puart->rx_count++%RX_BUFF_SIZE] = (uint8_t)USART_RxData(puart->uart);
}
else if (USART_ReadIntFlag(puart->uart, USART_INT_IDLE) == SET)
{
USART_ClearIntFlag(puart->uart, USART_INT_IDLE);
puart->idle=1;
USART_RxData(puart->uart);
}
}
void USART1_IRQHandler(void)
{
bsp_uart_ira_handler(uarts_it+UART_1);
}
void USART2_IRQHandler(void)
{
bsp_uart_ira_handler(uarts_it+UART_2);
}
## main.c
uint8_t buff[1024];
int main(void)
{
bsp_uart_it_init_all();
bsp_uart_send_data(UART_1,"HELLO",6);
while(1)
{
bsp_uart_recv_data(UART_1,buff,1024);
}
}