本文主要记录UART DMA操作方式,同时对STM32F103 UART驱动抽象出来实现帧数据接收
1、MDK工程目录(创建工程方式略)

main.c内容如下
运行后的结果是UART收到数据立即通过TX发送出去,同时LED状态反转一次
#include 《stdio.h》
#include “stm32f10x.h”
#include “platform.h”
unsigned char led_count = 0;
void LED_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void uart_recv_str(UART_TypeDef *p, uint8_t *pbuf, uint16_t len){
UART_ApiStructure.send_str(p, pbuf, len);
GPIO_WriteBit(GPIOB, GPIO_Pin_9, (++led_count & 0x01) ? Bit_SET : Bit_RESET);
}
int main(void){
LED_Init();
UART_ApiStructure.config(&UART_TypeDef_param, uart_recv_str);
UART_ApiStructure.send_str(&UART_TypeDef_param, (uint8_t *)“uart init okrn”, 14);
for(;;){}
}
uart.h
#ifndef __UART_H
#define __UART_H
typedef void (*pfunc_uart_gpio_init)(void);
/**
* @addtogroup 串口参数定义
* @{
*/
/** UART 数据处理设置 */
typedef struct{
uint8_t *tx_buf; /*!《 发送数据缓存 */
uint8_t *rx_buf; /*!《 接收数据缓存 */
uint16_t tx_buf_len_max; /*!《 发送数据最大缓存空间大小 */
uint16_t rx_buf_len_max; /*!《 接收数据最大缓存空间大小 */
uint16_t rx_tail; /*!《 接收数据缓存尾标识 */
uint16_t rx_head; /*!《 接收数据缓存头标识 */
}UART_UserParam;
/** DMA 参数设置 */
typedef struct{
uint8_t irq_tx; /*!《 发送通道中断号 */
uint8_t irq_rx; /*!《 接收通道中断号 */
DMA_Channel_TypeDef *channel_tx; /*!《 发送通道 */
DMA_Channel_TypeDef *channel_rx; /*!《 接收通道 */
uint32_t TX_IT_FLAG_TCx; /*!《 发送完成中断标志 */
uint32_t RX_IT_FLAG_TCx; /*!《 接收完成中断标志 */
}DMA_Param;
/** UART 参数设置 */
typedef struct{
uint32_t baud; /*!《 波特率参数 */
pfunc_uart_gpio_init pfunc_gpio_init; /*!《 指向串口GPIO初始化函数指针 */
USART_TypeDef* USARTx; /*!《 使用串口号 */
uint8_t USARTx_IRQn; /*!《 串口接收中断号 */
DMA_Param *DMAx; /*!《 DMA参数指针 */
UART_UserParam *user; /*!《 UART数据处理指针 */
}UART_TypeDef;
/**
* @}
*/
/**
* @addtogroup API 接口定义
*/
typedef void (*pfunc_uart_rsend_str)(UART_TypeDef *p, uint8_t *pbuf, uint16_t len);
typedef uint8_t (*pfunc_uart_config)(UART_TypeDef *p, pfunc_uart_rsend_str cb);
typedef struct{
pfunc_uart_config config; /*!《 初始化串口 */
pfunc_uart_rsend_str send_str; /*!《 发送数据 */
pfunc_uart_rsend_str recv_cb; /*!《 接收数据 */
}UART_ApiDef;
extern UART_ApiDef UART_ApiStructure;
/**
* @}
*/
#ifdef USE_PRINTF
extern int __printf(const char *fmt, 。..);
#else
#define __printf(。..)
#endif
#endif
uart.c
/**
* @file uart.c USART 驱动程序
*
* @author T0213-ZH
* @date 2018.06.13
*/
#include “platform.h”
/**
* @brief 配置USART参数
* @param p: 指向串口参数指针
* @param cb: 用于接收数据回调函数指针
*
* @retval 0-成功,1-已初始过了,2-未设置GPIO初始函数, 3-串口组参数不匹配
*/
static uint8_t uart_init(UART_TypeDef *p, pfunc_uart_rsend_str cb){
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
//if(g_uart_param) return 1;
if(!p-》pfunc_gpio_init) return 2;
if(cb)
UART_ApiStructure.recv_cb = cb;
//g_uart_param = p;
p-》pfunc_gpio_init();
if(p-》USARTx == USART1){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}else if(p-》USARTx == USART2){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
}else if(p-》USARTx == USART3){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
}else{
return 3;
}
USART_InitStructure.USART_BaudRate = p-》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(p-》USARTx, &USART_InitStructure);
USART_Cmd(p-》USARTx, ENABLE);
USART_ClearFlag(p-》USARTx, USART_FLAG_TC); //注:避免首字符丢掉现象
USART_ITConfig(p-》USARTx, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = p-》USARTx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_DMACmd(p-》USARTx, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(p-》USARTx, USART_DMAReq_Rx, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//DMA TX Config
DMA_DeInit(p-》DMAx-》channel_tx);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&p-》USARTx-》DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)p-》user-》tx_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = p-》user-》tx_buf_len_max;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(p-》DMAx-》channel_tx, &DMA_InitStructure);
//DMA_Cmd(p-》DMAx-》channel_tx, ENABLE)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = p-》DMAx-》irq_tx;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//DMA RX Config
DMA_DeInit(p-》DMAx-》channel_rx);
DMA_InitStructure.DMA_BufferSize = p-》user-》rx_buf_len_max;;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)p-》user-》rx_buf;
DMA_Init(p-》DMAx-》channel_rx, &DMA_InitStructure);
DMA_Cmd(p-》DMAx-》channel_rx, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = p-》DMAx-》irq_rx;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(p-》DMAx-》channel_tx, DMA_IT_TC, ENABLE);
DMA_ITConfig(p-》DMAx-》channel_rx, DMA_IT_TC, ENABLE);
return 0;
}
/**
* @brief 发送数据接口
* @param p: 指向发送数据缓存指针
* @param len: 数据长度
*
* @retval none
*/
static void uart_send_str(UART_TypeDef *p, uint8_t *pbuf, uint16_t len){
if(!len) return;
uint16_t i;
for(i=0; i《len; i++){
p-》user-》tx_buf[i] = *pbuf++;
}
while(DMA_GetFlagStatus(p-》DMAx-》TX_IT_FLAG_TCx) == SET);
DMA_SetCurrDataCounter(p-》DMAx-》channel_tx, len);
DMA_Cmd(p-》DMAx-》channel_tx, ENABLE);
}
/**
* @brief 接收数据接口,中断触发
*
* @retval none
*/
static void uart_recv_len(UART_TypeDef *p){
p-》user-》rx_head = p-》user-》rx_buf_len_max - DMA_GetCurrDataCounter(p-》DMAx-》channel_rx);
if(p-》user-》rx_tail != p-》user-》rx_head){
uint16_t i = 0;
uint8_t buf[p-》user-》rx_buf_len_max];
uint16_t head = p-》user-》rx_head;
do{
buf[i++] = p-》user-》rx_buf[p-》user-》rx_tail++];
if(p-》user-》rx_tail == p-》user-》rx_buf_len_max)
p-》user-》rx_tail = 0;
}while(p-》user-》rx_tail != head);
if(UART_ApiStructure.recv_cb){
UART_ApiStructure.recv_cb(p, buf, i);
}
//uart_send_str(buf, i);
}
}
/**
* @brief UART 接口函数
*/
UART_ApiDef UART_ApiStructure = {
.config = uart_init, /*!《 指向串口参数配置接口函数指针 */
.send_str = uart_send_str, /*!《 指向串口发送字符串接口函数指针 */
.recv_cb = 0,
};
void uart_tx_irq(UART_TypeDef *p){
if(DMA_GetITStatus(p-》DMAx-》TX_IT_FLAG_TCx) == SET){
DMA_Cmd(p-》DMAx-》channel_tx, DISABLE);
DMA_ClearITPendingBit(p-》DMAx-》TX_IT_FLAG_TCx);
}
}
void uart_rx_irq(UART_TypeDef *p){
if(DMA_GetITStatus(p-》DMAx-》RX_IT_FLAG_TCx) == SET){
DMA_ClearITPendingBit(p-》DMAx-》RX_IT_FLAG_TCx);
}
}
void uart_irq(UART_TypeDef *p){
if(USART_GetITStatus(p-》USARTx, USART_IT_IDLE) != RESET){
USART_ReceiveData(p-》USARTx);
USART_ClearITPendingBit(p-》USARTx, USART_IT_IDLE);
uart_recv_len(p);
}
}
#ifdef USE_PRINTF
int __fputc(unsigned char ch, unsigned char *f){
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
return ch;
}
#endif
platform.c
#include “platform.h”
extern void uart_tx_irq(UART_TypeDef *p);
extern void uart_rx_irq(UART_TypeDef *p);
extern void uart_irq(UART_TypeDef *p);
void USART_GpioInit(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**
* @addtogroup
* @{
*/
#define UART_TX_BUF_MAX (256)
#define UART_RX_BUF_MAX (256)
uint8_t uart_tx_buf[UART_TX_BUF_MAX];
uint8_t uart_rx_buf[UART_RX_BUF_MAX];
DMA_Param dma_param = {
.irq_tx = DMA1_Channel4_IRQn,
.irq_rx = DMA1_Channel5_IRQn,
.channel_tx = DMA1_Channel4,
.channel_rx = DMA1_Channel5,
.TX_IT_FLAG_TCx = DMA1_IT_TC4,
.RX_IT_FLAG_TCx = DMA1_IT_TC5,
};
/** UART */
UART_UserParam uart_param = {
.tx_buf = uart_tx_buf,
.rx_buf = uart_rx_buf,
.tx_buf_len_max = UART_TX_BUF_MAX,
.rx_buf_len_max = UART_RX_BUF_MAX,
.rx_tail = 0,
.rx_head = 0,
};
/** UART */
UART_TypeDef UART_TypeDef_param = {
.baud = 115200,
.pfunc_gpio_init = USART_GpioInit,
.USARTx = USART1,
.USARTx_IRQn = USART1_IRQn,
.DMAx = &dma_param,
.user = &uart_param,
};
void DMA1_Channel4_IRQHandler(void){
uart_tx_irq(&UART_TypeDef_param);
}
void DMA1_Channel5_IRQHandler(void){
uart_rx_irq(&UART_TypeDef_param);
}
void USART1_IRQHandler(void){
uart_irq(&UART_TypeDef_param);
}
/**
* @}
*/
本文主要记录UART DMA操作方式,同时对STM32F103 UART驱动抽象出来实现帧数据接收
1、MDK工程目录(创建工程方式略)

main.c内容如下
运行后的结果是UART收到数据立即通过TX发送出去,同时LED状态反转一次
#include 《stdio.h》
#include “stm32f10x.h”
#include “platform.h”
unsigned char led_count = 0;
void LED_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void uart_recv_str(UART_TypeDef *p, uint8_t *pbuf, uint16_t len){
UART_ApiStructure.send_str(p, pbuf, len);
GPIO_WriteBit(GPIOB, GPIO_Pin_9, (++led_count & 0x01) ? Bit_SET : Bit_RESET);
}
int main(void){
LED_Init();
UART_ApiStructure.config(&UART_TypeDef_param, uart_recv_str);
UART_ApiStructure.send_str(&UART_TypeDef_param, (uint8_t *)“uart init okrn”, 14);
for(;;){}
}
uart.h
#ifndef __UART_H
#define __UART_H
typedef void (*pfunc_uart_gpio_init)(void);
/**
* @addtogroup 串口参数定义
* @{
*/
/** UART 数据处理设置 */
typedef struct{
uint8_t *tx_buf; /*!《 发送数据缓存 */
uint8_t *rx_buf; /*!《 接收数据缓存 */
uint16_t tx_buf_len_max; /*!《 发送数据最大缓存空间大小 */
uint16_t rx_buf_len_max; /*!《 接收数据最大缓存空间大小 */
uint16_t rx_tail; /*!《 接收数据缓存尾标识 */
uint16_t rx_head; /*!《 接收数据缓存头标识 */
}UART_UserParam;
/** DMA 参数设置 */
typedef struct{
uint8_t irq_tx; /*!《 发送通道中断号 */
uint8_t irq_rx; /*!《 接收通道中断号 */
DMA_Channel_TypeDef *channel_tx; /*!《 发送通道 */
DMA_Channel_TypeDef *channel_rx; /*!《 接收通道 */
uint32_t TX_IT_FLAG_TCx; /*!《 发送完成中断标志 */
uint32_t RX_IT_FLAG_TCx; /*!《 接收完成中断标志 */
}DMA_Param;
/** UART 参数设置 */
typedef struct{
uint32_t baud; /*!《 波特率参数 */
pfunc_uart_gpio_init pfunc_gpio_init; /*!《 指向串口GPIO初始化函数指针 */
USART_TypeDef* USARTx; /*!《 使用串口号 */
uint8_t USARTx_IRQn; /*!《 串口接收中断号 */
DMA_Param *DMAx; /*!《 DMA参数指针 */
UART_UserParam *user; /*!《 UART数据处理指针 */
}UART_TypeDef;
/**
* @}
*/
/**
* @addtogroup API 接口定义
*/
typedef void (*pfunc_uart_rsend_str)(UART_TypeDef *p, uint8_t *pbuf, uint16_t len);
typedef uint8_t (*pfunc_uart_config)(UART_TypeDef *p, pfunc_uart_rsend_str cb);
typedef struct{
pfunc_uart_config config; /*!《 初始化串口 */
pfunc_uart_rsend_str send_str; /*!《 发送数据 */
pfunc_uart_rsend_str recv_cb; /*!《 接收数据 */
}UART_ApiDef;
extern UART_ApiDef UART_ApiStructure;
/**
* @}
*/
#ifdef USE_PRINTF
extern int __printf(const char *fmt, 。..);
#else
#define __printf(。..)
#endif
#endif
uart.c
/**
* @file uart.c USART 驱动程序
*
* @author T0213-ZH
* @date 2018.06.13
*/
#include “platform.h”
/**
* @brief 配置USART参数
* @param p: 指向串口参数指针
* @param cb: 用于接收数据回调函数指针
*
* @retval 0-成功,1-已初始过了,2-未设置GPIO初始函数, 3-串口组参数不匹配
*/
static uint8_t uart_init(UART_TypeDef *p, pfunc_uart_rsend_str cb){
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
//if(g_uart_param) return 1;
if(!p-》pfunc_gpio_init) return 2;
if(cb)
UART_ApiStructure.recv_cb = cb;
//g_uart_param = p;
p-》pfunc_gpio_init();
if(p-》USARTx == USART1){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}else if(p-》USARTx == USART2){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
}else if(p-》USARTx == USART3){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
}else{
return 3;
}
USART_InitStructure.USART_BaudRate = p-》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(p-》USARTx, &USART_InitStructure);
USART_Cmd(p-》USARTx, ENABLE);
USART_ClearFlag(p-》USARTx, USART_FLAG_TC); //注:避免首字符丢掉现象
USART_ITConfig(p-》USARTx, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = p-》USARTx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_DMACmd(p-》USARTx, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(p-》USARTx, USART_DMAReq_Rx, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//DMA TX Config
DMA_DeInit(p-》DMAx-》channel_tx);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&p-》USARTx-》DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)p-》user-》tx_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = p-》user-》tx_buf_len_max;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(p-》DMAx-》channel_tx, &DMA_InitStructure);
//DMA_Cmd(p-》DMAx-》channel_tx, ENABLE)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = p-》DMAx-》irq_tx;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//DMA RX Config
DMA_DeInit(p-》DMAx-》channel_rx);
DMA_InitStructure.DMA_BufferSize = p-》user-》rx_buf_len_max;;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)p-》user-》rx_buf;
DMA_Init(p-》DMAx-》channel_rx, &DMA_InitStructure);
DMA_Cmd(p-》DMAx-》channel_rx, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = p-》DMAx-》irq_rx;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(p-》DMAx-》channel_tx, DMA_IT_TC, ENABLE);
DMA_ITConfig(p-》DMAx-》channel_rx, DMA_IT_TC, ENABLE);
return 0;
}
/**
* @brief 发送数据接口
* @param p: 指向发送数据缓存指针
* @param len: 数据长度
*
* @retval none
*/
static void uart_send_str(UART_TypeDef *p, uint8_t *pbuf, uint16_t len){
if(!len) return;
uint16_t i;
for(i=0; i《len; i++){
p-》user-》tx_buf[i] = *pbuf++;
}
while(DMA_GetFlagStatus(p-》DMAx-》TX_IT_FLAG_TCx) == SET);
DMA_SetCurrDataCounter(p-》DMAx-》channel_tx, len);
DMA_Cmd(p-》DMAx-》channel_tx, ENABLE);
}
/**
* @brief 接收数据接口,中断触发
*
* @retval none
*/
static void uart_recv_len(UART_TypeDef *p){
p-》user-》rx_head = p-》user-》rx_buf_len_max - DMA_GetCurrDataCounter(p-》DMAx-》channel_rx);
if(p-》user-》rx_tail != p-》user-》rx_head){
uint16_t i = 0;
uint8_t buf[p-》user-》rx_buf_len_max];
uint16_t head = p-》user-》rx_head;
do{
buf[i++] = p-》user-》rx_buf[p-》user-》rx_tail++];
if(p-》user-》rx_tail == p-》user-》rx_buf_len_max)
p-》user-》rx_tail = 0;
}while(p-》user-》rx_tail != head);
if(UART_ApiStructure.recv_cb){
UART_ApiStructure.recv_cb(p, buf, i);
}
//uart_send_str(buf, i);
}
}
/**
* @brief UART 接口函数
*/
UART_ApiDef UART_ApiStructure = {
.config = uart_init, /*!《 指向串口参数配置接口函数指针 */
.send_str = uart_send_str, /*!《 指向串口发送字符串接口函数指针 */
.recv_cb = 0,
};
void uart_tx_irq(UART_TypeDef *p){
if(DMA_GetITStatus(p-》DMAx-》TX_IT_FLAG_TCx) == SET){
DMA_Cmd(p-》DMAx-》channel_tx, DISABLE);
DMA_ClearITPendingBit(p-》DMAx-》TX_IT_FLAG_TCx);
}
}
void uart_rx_irq(UART_TypeDef *p){
if(DMA_GetITStatus(p-》DMAx-》RX_IT_FLAG_TCx) == SET){
DMA_ClearITPendingBit(p-》DMAx-》RX_IT_FLAG_TCx);
}
}
void uart_irq(UART_TypeDef *p){
if(USART_GetITStatus(p-》USARTx, USART_IT_IDLE) != RESET){
USART_ReceiveData(p-》USARTx);
USART_ClearITPendingBit(p-》USARTx, USART_IT_IDLE);
uart_recv_len(p);
}
}
#ifdef USE_PRINTF
int __fputc(unsigned char ch, unsigned char *f){
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
return ch;
}
#endif
platform.c
#include “platform.h”
extern void uart_tx_irq(UART_TypeDef *p);
extern void uart_rx_irq(UART_TypeDef *p);
extern void uart_irq(UART_TypeDef *p);
void USART_GpioInit(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**
* @addtogroup
* @{
*/
#define UART_TX_BUF_MAX (256)
#define UART_RX_BUF_MAX (256)
uint8_t uart_tx_buf[UART_TX_BUF_MAX];
uint8_t uart_rx_buf[UART_RX_BUF_MAX];
DMA_Param dma_param = {
.irq_tx = DMA1_Channel4_IRQn,
.irq_rx = DMA1_Channel5_IRQn,
.channel_tx = DMA1_Channel4,
.channel_rx = DMA1_Channel5,
.TX_IT_FLAG_TCx = DMA1_IT_TC4,
.RX_IT_FLAG_TCx = DMA1_IT_TC5,
};
/** UART */
UART_UserParam uart_param = {
.tx_buf = uart_tx_buf,
.rx_buf = uart_rx_buf,
.tx_buf_len_max = UART_TX_BUF_MAX,
.rx_buf_len_max = UART_RX_BUF_MAX,
.rx_tail = 0,
.rx_head = 0,
};
/** UART */
UART_TypeDef UART_TypeDef_param = {
.baud = 115200,
.pfunc_gpio_init = USART_GpioInit,
.USARTx = USART1,
.USARTx_IRQn = USART1_IRQn,
.DMAx = &dma_param,
.user = &uart_param,
};
void DMA1_Channel4_IRQHandler(void){
uart_tx_irq(&UART_TypeDef_param);
}
void DMA1_Channel5_IRQHandler(void){
uart_rx_irq(&UART_TypeDef_param);
}
void USART1_IRQHandler(void){
uart_irq(&UART_TypeDef_param);
}
/**
* @}
*/
举报