# 1 前言
本章介绍下如何使用uart的rx和tx功能,其中tx利用dma更为方便。
# 2 基础
uart一次只能收发一字节数据,所以发送相对简单点,直接用函数USART_SendData(),发送多个数据。 但是rx接收时需要等uart状态rx结束,读取到USART_FLAG_RXDNE状态可以收数据。 不过使用dma更为方便,使用usart目录下的DMA_polling示例。
简单介绍下dma:在内存中开辟一段数组空间,uart收到数据后将存入dma中,指针向后移动,直到填满后产生dma中断。 dma中断中可以配置清空等操作。
# 3 引脚介绍
其中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-XinSheng ... amples/USART/Printf
示例源码路径: https://gitee.com/CMIOT-XinSheng ... s/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.
- *
- *******************************************************************************/
- /**
- * [url=home.php?mod=space&uid=1455510]@file[/url] main.h
- * [url=home.php?mod=space&uid=40524]@author[/url] CMIOT Firmware Team
- * [url=home.php?mod=space&uid=644434]@version[/url] v1.0.0
- *
- * [url=home.php?mod=space&uid=855824]@copyright[/url] 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
- #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);
- /**
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] Main program
- */
- int main(void)
- {
- func_init_uart4();
- printf("start initrn");
- printf("-------test1: dma tx---------rn");
- /* 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]rn",(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("rn-------test2: uart tx---------rn");
- delay(1000);
- printf("dma tx over.rn");
- // USART_SendData(USARTy,'n');
- // delay();
- char temp_rx[]="hihihi";
- myUart_tx(5,temp_rx,4);
- // reset_dma_rx();
- printf("rn-------test3: uart rx---------rn");
- int count = 0;
- while (1)
- {
- printf("count = %drn",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]rn",(char*)TxBuffer1);
- // printf("TxBuffer2 = [%s]rn",(char*)TxBuffer2);
- printf("RxBuffer1 = [%s]rn",(char*)RxBuffer1);
- // printf("RxBuffer2 = [%s]rn",(char*)RxBuffer2);
- printf("rn");
- }
- void print_uart_wait()
- {
- if(status_wait_uart == true)
- {
- status_wait_uart = false;
- printf("uart transfer waiting......rn");
- }
- }
- void print_uart_wait_end()
- {
- status_wait_uart = true;
- printf("end uart wait.rn");
- }
- 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 uart5rn");
- dma = USARTy_Tx_DMA_Channel;
- dma_flag = DMA1_FLAG_TC1;
- break;
- }
- printf("sendrn");
- // 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]rn",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 uart5rn");
- uart = USARTy;
- break;
- }
- int i=0;
- while(temp_len > i)
- {
- // printf("i = %d, value = %02xrn",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 = %srn",len_str,len_send,
- str_data?"true":"false");
- if(str_data == true)
- {
- printf("send data len overside str_len.rn");
- }
- else
- {
- printf("send data len = %d.rn",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 uart5rn");
- uart = USARTy;
- break;
- }
- // printf("receivern");
- // 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 idlefrn");
- int dma_last = DMA_GetCurrDataCounter(USARTy_Rx_DMA_Channel);
- printf("dma get count =%d rn",dma_last);
- printf("has recv data len = %drn",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 结果
可以看到,串口接收工具
1. 收到dma传输的字符串
2. 收到通过uart函数传输的字符串
3. 向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实现数据的收发,后续再结合串口屏实现功能。
|