文章目录
1 前言
本章介绍下如何使用uart的rx和tx功能,其中tx利用dma更为方便。
2 基础
参考文章:STM32单片机串口空闲中断+DMA接收不定长数据
uart一次只能收发一字节数据,所以发送相对简单点,直接用函数USART_SendData(),发送多个数据。
但是rx接收时需要等uart状态rx结束,读取到USART_FLAG_RXDNE状态可以收数据。
不过使用dma更为方便,使用usart目录下的DMA_polling示例。
简单介绍下dma:在内存中开辟一段数组空间,uart收到数据后将存入dma中,指针向后移动,直到填满后产生dma中断。
dma中断中可以配置清空等操作。
3 引脚介绍
整理了一下开发板的uart端口。
其中usart有三个,分别为usart1-3,uart有四个,分别为uart4-7。
usart相对uart多了时钟信号,用于同步。
其中uart4一般作为和电脑的串口通信,用于打印信息。printf函数显示log就通过uart4传输出来。
4 硬件
usart3和uart5-7,分别为PC10/11,PB13/14,PB0/1,PC4/5。
uart4根据电路图来看是接到了PA2/3。推测PA2/3和PA13/12有关联,因为PA13/12是microusb数据线。
5 代码
主要参考两个示例,usart/printf是用于打印log,usart/dma_polling是用于dma接收数据。
printf示例:https://gitee.com/CMIOT-XinShengTech/CMIOT.CM32M4xxR_Library/tree/main/Projects/CM32M433R-START/Examples/USART/Printf
示例源码路径:https://gitee.com/CMIOT-XinShengTech/CMIOT.CM32M4xxR_Library/tree/main/Projects/CM32M433R-START/Examples/USART/DMA_Polling
打印log使用的uart4,用到的io为PD0/1。
uart收发使用的uart5,用到io为PB13/14。
5.1 main.h
头文件定义uart引脚和dma信息。
/*******************************************************************************
*
* COPYRIGHT(c) 2020, China Mobile IOT
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of China Mobile IOT nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
/**
* @file main.h
* @author CMIOT Firmware Team
* @version v1.0.0
*
* @copyright Copyright (c) 2020, CMIOT. All rights reserved.
*/
#ifndef __MAIN_H__
#define __MAIN_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "nuclei_sdk_soc.h"
/* USARTx configuration */
#define _USART4_COM_
#ifdef _USART4_COM_
#define USARTx UART4
#define USARTx_GPIO GPIOD
#define USARTx_CLK RCC_APB1_PERIPH_UART4
#define USARTx_GPIO_CLK RCC_APB2_PERIPH_GPIOD
#define USARTx_RxPin GPIO_PIN_1
#define USARTx_TxPin GPIO_PIN_0
#define GPIO_APBxClkCmd RCC_EnableAPB2PeriphClk
#define USART_APBxClkCmd RCC_EnableAPB1PeriphClk
#endif
#define _USART5_USART6_
#ifdef _USART5_USART6_
#define USARTy UART5
#define USARTy_GPIO GPIOB
#define USARTy_CLK RCC_APB1_PERIPH_UART5
#define USARTy_GPIO_CLK RCC_APB2_PERIPH_GPIOB
#define USARTy_TxPin GPIO_PIN_13
#define USARTy_RxPin GPIO_PIN_14
#define USARTy_APBxClkCmd RCC_EnableAPB1PeriphClk
#define USARTy_DMAx DMA1
#define USARTy_DMAx_CLK RCC_AHB_PERIPH_DMA1
#define USARTy_DR_Base (UART5_BASE + 0x04)
#define USARTy_Tx_DMA_Channel DMA1_CH1
#define USARTy_Tx_DMA_FLAG DMA1_FLAG_TC1
#define USARTy_Rx_DMA_Channel DMA1_CH8
#define USARTy_Rx_DMA_FLAG DMA1_FLAG_TC8
#define USARTy_Tx_DMA_IRQn DMA1_Channel1_IRQn
#define USARTy_Tx_DMA_IRQHandler DMA1_Channel1_IRQHandler
#define USARTy_Tx_DMA_INT DMA1_INT_TXC1
#define USARTz UART6
#define USARTz_GPIO GPIOB
#define USARTz_CLK RCC_APB2_PERIPH_UART6
#define USARTz_GPIO_CLK RCC_APB2_PERIPH_GPIOB
#define USARTz_TxPin GPIO_PIN_0
#define USARTz_RxPin GPIO_PIN_1
#define USARTz_APBxClkCmd RCC_EnableAPB2PeriphClk
#define USARTz_DMAx DMA2
#define USARTz_DMAx_CLK RCC_AHB_PERIPH_DMA2
#define USARTz_DR_Base (UART6_BASE + 0x04)
#define USARTz_Tx_DMA_Channel DMA2_CH2
#define USARTz_Tx_DMA_FLAG DMA2_FLAG_TC2
#define USARTz_Rx_DMA_Channel DMA2_CH1
#define USARTz_Rx_DMA_FLAG DMA2_FLAG_TC1
#define USARTz_Rx_DMA_IRQn DMA2_Channel1_IRQn
#define USARTz_Rx_DMA_IRQHandler DMA2_Channel1_IRQHandler
#define USARTz_Rx_DMA_INT DMA2_INT_TXC1
#define USARTz_IRQn UART6_IRQn
#endif
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H__ */
5.2 main.c
实现uart测试功能。
测试1:dma的tx传输
测试2:uart传输字符串
测试3:dma的rx接收
/*******************************************************************************
*
* COPYRIGHT(c) 2020, China Mobile IOT
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of China Mobile IOT nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
/**
* @file main.c
* @author CMIOT Firmware Team
* @version v1.0.0
*
* @copyright Copyright (c) 2020, CMIOT. All rights reserved.
*/
#include <stdio.h>
#include "main.h"
/** @addtogroup CM32M4xxR_StdPeriph_Examples
* @{
*/
/** @addtogroup USART_DMA_Polling
* @{
*/
typedef enum
{
FAILED = 0,
PASSED = !FAILED
} TestStatus;
#define TxBufferSize1 (countof(TxBuffer1) - 1)
#define TxBufferSize2 (countof(TxBuffer2) - 1)
#define countof(a) (sizeof(a) / sizeof(*(a)))
USART_InitType USART_InitStructure;
uint8_t TxBuffer1[] = "USART DMA Polling: USARTy -> USARTz using DMA";
uint8_t TxBuffer2[] = "USART DMA Polling: USARTz -> USARTy using DMA";
uint8_t RxBuffer1[TxBufferSize2];
uint8_t RxBuffer2[TxBufferSize1];
volatile TestStatus TransferStatus1 = FAILED;
volatile TestStatus TransferStatus2 = FAILED;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
// youkai add
void func_init_uart4();
void print_dma();
bool status_wait_uart = false;
#define UART_STATUS_RX true
#define UART_STATUS_TX false
void print_uart_wait();
void print_uart_wait_end();
void reset_dma_rx();
void reset_dma_tx();
void myUart_rx(uint8_t uart_id,bool rx_tx);
void myUart_tx(uint8_t uart_id,uint8_t * data,uint8_t len_send);
void myUart_senddata(uint8_t uart_id, uint8_t * data,uint8_t len_send);
void myDMA_tx(uint8_t uart_id);
void delay(vu32 nCount);
/**
* @brief Main program
*/
int main(void)
{
func_init_uart4();
printf("start init\r\n");
printf("-------test1: dma tx---------\r\n");
/* System Clocks Configuration */
RCC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
/* Configure the DMA */
DMA_Configuration();
/* USARTy and USARTz configuration ------------------------------------------------------*/
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
/* Configure USARTy and USARTz */
USART_Init(USARTy, &USART_InitStructure);
USART_Init(USARTz, &USART_InitStructure);
// strcpy(TxBuffer1,"hihihihihihihihihihihihihihihihihihihihihihih");
// printf("TxBuffer1 = [%s]\r\n",(char*)TxBuffer1);
/* Enable USARTy DMA Rx and TX request */
USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);
/* Enable USARTz DMA Rx and TX request */
USART_EnableDMA(USARTz, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);
/* Enable USARTy TX DMA1 Channel */
DMA_EnableChannel(USARTy_Tx_DMA_Channel, ENABLE);
/* Enable USARTy RX DMA1 Channel */
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
/* Enable USARTz TX DMA1 Channel */
DMA_EnableChannel(USARTz_Tx_DMA_Channel, ENABLE);
/* Enable USARTz RX DMA1 Channel */
DMA_EnableChannel(USARTz_Rx_DMA_Channel, ENABLE);
/* Enable the USARTy and USARTz */
USART_Enable(USARTy, ENABLE);
USART_Enable(USARTz, ENABLE);
// wait until dma send data ok.
while(DMA_GetFlagStatus(DMA1_FLAG_TC1,USARTy_DMAx)==RESET)
{
}
printf("\r\n-------test2: uart tx---------\r\n");
delay(1000);
printf("dma tx over.\r\n");
// USART_SendData(USARTy,'\n');
// delay();
char temp_rx[]="hihihi";
myUart_tx(5,temp_rx,4);
// reset_dma_rx();
printf("\r\n-------test3: uart rx---------\r\n");
int count = 0;
while (1)
{
printf("count = %d\r\n",count++);
myUart_rx(5,UART_STATUS_RX);
}
}
/**
* @brief Configures the different system clocks.
*/
void RCC_Configuration(void)
{
/* DMA clock enable */
RCC_EnableAHBPeriphClk(USARTy_DMAx_CLK, ENABLE);
RCC_EnableAHBPeriphClk(USARTz_DMAx_CLK, ENABLE);
/* Enable GPIO clock */
RCC_EnableAPB2PeriphClk(USARTy_GPIO_CLK | USARTz_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
/* Enable USARTy and USARTz Clock */
USARTy_APBxClkCmd(USARTy_CLK, ENABLE);
USARTz_APBxClkCmd(USARTz_CLK, ENABLE);
}
/**
* @brief Configures the different GPIO ports.
*/
void GPIO_Configuration(void)
{
GPIO_InitType GPIO_InitStructure;
GPIO_ConfigPinRemap(GPIO_RMP_USART1,ENABLE);
/* Configure USARTy Rx as input floating */
GPIO_InitStructure.Pin = USARTy_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
/* Configure USARTz Rx as input floating */
GPIO_InitStructure.Pin = USARTz_RxPin;
GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTy_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
/* Configure USARTz Tx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTz_TxPin;
GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);
GPIO_ConfigPinRemap(GPIO_RMP1_UART5, ENABLE);
GPIO_ConfigPinRemap(GPIO_RMP3_UART6, ENABLE);
}
/**
* @brief Configures the DMA.
*/
void DMA_Configuration(void)
{
DMA_InitType DMA_InitStructure;
/* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
DMA_DeInit(USARTy_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)TxBuffer1;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = TxBufferSize1;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
/* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
DMA_DeInit(USARTy_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)RxBuffer1;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = TxBufferSize2;
DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
/* USARTz TX DMA1 Channel (triggered by USARTz Tx event) Config */
DMA_DeInit(USARTz_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTz_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)TxBuffer2;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = TxBufferSize2;
DMA_Init(USARTz_Tx_DMA_Channel, &DMA_InitStructure);
/* USARTz RX DMA1 Channel (triggered by USARTz Rx event) Config */
DMA_DeInit(USARTz_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTz_DR_Base;
DMA_InitStructure.MemAddr = (uint32_t)RxBuffer2;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = TxBufferSize1;
DMA_Init(USARTz_Rx_DMA_Channel, &DMA_InitStructure);
}
void func_init_uart4()
{
//RCC_Configuration
/* Enable GPIO clock */
GPIO_APBxClkCmd(USARTx_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
/* Enable USARTy and USARTz Clock */
USART_APBxClkCmd(USARTx_CLK, ENABLE);
//GPIO_Configuration
GPIO_InitType GPIO_InitStructure;
GPIO_ConfigPinRemap(GPIO_RMP_USART1,ENABLE);
/* Configure USARTx Tx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTx_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(USARTx_GPIO, &GPIO_InitStructure);
/* Configure USARTx Rx as input floating */
GPIO_InitStructure.Pin = USARTx_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USARTx_GPIO, &GPIO_InitStructure);
GPIO_ConfigPinRemap(GPIO_RMP3_UART4, ENABLE);
//uart
/* USARTy and USARTz configuration ------------------------------------------------------*/
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
/* Configure USARTx */
USART_Init(USARTx, &USART_InitStructure);
/* Enable the USARTx */
USART_Enable(USARTx, ENABLE);
}
void print_dma()
{
// printf("TxBuffer1 = [%s]\r\n",(char*)TxBuffer1);
// printf("TxBuffer2 = [%s]\r\n",(char*)TxBuffer2);
printf("RxBuffer1 = [%s]\r\n",(char*)RxBuffer1);
// printf("RxBuffer2 = [%s]\r\n",(char*)RxBuffer2);
printf("\r\n");
}
void print_uart_wait()
{
if(status_wait_uart == true)
{
status_wait_uart = false;
printf("uart transfer waiting......\r\n");
}
}
void print_uart_wait_end()
{
status_wait_uart = true;
printf("end uart wait.\r\n");
}
void myDMA_tx(uint8_t uart_id)
{
// choose dma
DMA_Module* dma = USARTy_Tx_DMA_Channel;
uint32_t dma_flag = DMA1_FLAG_TC1;
switch(uart_id)
{
case 5:
dma = USARTy_Tx_DMA_Channel;
dma_flag= DMA1_FLAG_TC1;
break;
case 6:
dma = USARTz_Tx_DMA_Channel;
dma_flag = DMA2_FLAG_TC8;
break;
default:
printf("use default uart5\r\n");
dma = USARTy_Tx_DMA_Channel;
dma_flag = DMA1_FLAG_TC1;
break;
}
printf("send\r\n");
// tx : send uart data to other dev
while (DMA_GetFlagStatus(dma_flag, dma) == RESET)
{
print_uart_wait();
}
print_uart_wait_end();
}
void myUart_senddata(uint8_t uart_id,uint8_t* data, uint8_t len_send)
{
uint8_t * temp_value = data;
uint8_t temp_len = len_send;
printf("len_send = %d, strvalue = [%s]\r\n",temp_len,(char * )data);
// choose uart
USART_Module* uart = USARTy;
switch(uart_id)
{
case 5:
uart = USARTy;
break;
case 6:
uart = USARTz;
break;
default:
printf("use default uart5\r\n");
uart = USARTy;
break;
}
int i=0;
while(temp_len > i)
{
// printf("i = %d, value = %02x\r\n",i,*temp_value);
USART_SendData(uart,*temp_value);
// wait until data has send
while(USART_GetFlagStatus(uart,USART_FLAG_TXDE)==RESET)
{
}
i++;
temp_value++;
}
return;
}
void myUart_tx(uint8_t uart_id,uint8_t * data,uint8_t len_send)
{
int len_str = strlen(data);
bool str_data = len_send>=len_str;
// if send overside strlen, just send strlen
int len = str_data? len_str:len_send;
printf("strlen = %d, send len = %d, send>strlen = %s\r\n",len_str,len_send,
str_data?"true":"false");
if(str_data == true)
{
printf("send data len overside str_len.\r\n");
}
else
{
printf("send data len = %d.\r\n",len_send);
}
myUart_senddata(uart_id,data,len);
}
void myUart_rx(uint8_t uart_id,bool rx_tx)
{
USART_Module * uart = USARTy;
DMA_Module * dma = USARTy_Rx_DMA_Channel;
switch(uart_id)
{
case 5:
uart = USARTy;
dma = USARTy_Rx_DMA_Channel;
break;
case 6:
uart = USARTz;
dma = USARTz_Rx_DMA_Channel;
break;
default:
printf("use default uart5\r\n");
uart = USARTy;
break;
}
// printf("receive\r\n");
// rx : get uart data from other dev
/* Wait until USARTy get idlef */
while (USART_GetFlagStatus(uart, USART_FLAG_IDLEF) == RESET)
{
print_uart_wait();
}
print_uart_wait_end();
printf("uart is idlef\r\n");
int dma_last = DMA_GetCurrDataCounter(USARTy_Rx_DMA_Channel);
printf("dma get count =%d \r\n",dma_last);
printf("has recv data len = %d\r\n",TxBufferSize2-dma_last);
reset_dma_rx();
}
void reset_dma_rx()
{
print_dma();
memset(RxBuffer1,0x00,sizeof(RxBuffer1));
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel,TxBufferSize1);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
// clear idlef flag
USART_ReceiveData(USARTy);
}
void reset_dma_tx()
{
print_dma();
memset(TxBuffer1,0x00,sizeof(TxBuffer1));
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel,TxBufferSize1);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
// clear idlef flag
USART_ReceiveData(USARTy);
}
/**
* @brief Delay function.
*/
void delay(vu32 nCount)
{
vu32 index = 0;
for (index = (34000 * nCount); index != 0; index--)
{
}
}
/**
* @}
*/
/**
* @}
*/
6 结果
可以看到,串口接收工具
- 收到dma传输的字符串
- 收到通过uart函数传输的字符串
- 向uart5发出不定长度的数据,log中显示出来获取的数据及长度。
7 使用函数
USART_SendData:uart传输数据tx
USART_GetFlagStatus:获取uart状态,根据传入的uart和flag,返回set表示该flag已经设置,则跳出while循环
DMA_GetCurrDataCounter:获取dma剩余空间长度,用于计算当前收到了多少数据。
DMA_EnableChannel:开关dma的channel,两个dma,每个有8channel。
DMA_SetCurrDataCounter:设置当前dma的指针。
PS:收到过一次后需要开关dma,然后重新设置当前数据数。
此外,由于判断dma收到数据状态,通过判断usart的idle,空闲中断。
当判定到uart收到空闲中断,则表示uart数据传输完成。不过该状态清空需要使用到receive函数。
USART_ReceiveData:uart接收数据rx。
8 小结
本章介绍了结合uart及dma实现数据的收发,后续再结合串口屏实现功能。