硬件准备:TG STK , 将20pin 扩展口的4脚与6脚相连接。第4脚为PD0,Tx, 第6脚为PD1,Rx。
软件流程:UART配置完毕之后,在主函数中不停的触发TX的DMA传输,总共传输12个字节的数据,0~9, '\n' , '\r'。 Rx采用普通中断来做。
#include <stdint.h>
#include <stdbool.h>
#include "efm32.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_dma.h"
#define DMA_CHANNEL_UART_TX 0 //定义DMA传输的通道,0代表是通道0
#define SPITXSAMPLES (12) //定义了传输的字节个数,最大为1024字节
//定义DMA控制器的全局变量,请不要动
/* DMA init structure */
DMA_Init_TypeDef dmaInit;
/* DMA callback structure */
DMA_CB_TypeDef cb[DMA_CHAN_COUNT];//DMA_CHAN_COUN通道总数
/** DMA control block, requires proper alignment. */
#if defined (__ICCARM__)
#pragma data_alignment=256
DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMA_CHAN_COUNT * 2];
#elif defined (__CC_ARM)
DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMA_CHAN_COUNT * 2] __attribute__ ((aligned(256)));
#elif defined (__GNUC__)
DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMA_CHAN_COUNT * 2] __attribute__ ((aligned(256)));
#else
#error Undefined toolkit, need to define alignment
#endif
unsigned char ucUARTTxBuffer[SPITXSAMPLES]; //定义一个1K字节的缓冲区,作为Tx的传输测试
unsigned char ucComplete = 0;
//USART1的接收中断函数
void USART1_RX_IRQHandler(void)
{
USART_Rx(USART1);// 接收中断标志位在读取Rx数据之后,自动清零
}
void UART_Initial(void)
{
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_USART1, true);
USART_InitAsync_TypeDef UART_init = USART_INITASYNC_DEFAULT;
//设置USART1的波特率为9600
UART_init.baudrate = 9600;
//初始化USART1
USART_InitAsync(USART1, &UART_init);
//先清除Rx中断标志位,然后使能Rx中断允许
USART1->IFC = _USART_IFC_MASK;
NVIC_ClearPendingIRQ(USART1_RX_IRQn);
NVIC_EnableIRQ(USART1_RX_IRQn);
USART1->IEN = USART_IEN_RXDATAV;
//USART1 GPIO口设置
GPIO_PinModeSet(gpioPortD,0,gpioModePushPull,1); //tx
GPIO_PinModeSet(gpioPortD,1,gpioModeInput,1); //rx
USART1->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC1;
}
void UARTTxTransferComplete(unsigned int channel, bool primary, void *user)
{
ucComplete = 1;
}
void DMA_for_UART_Tx(void)
{
DMA_CfgChannel_TypeDef chnlCfg;
DMA_CfgDescr_TypeDef descrCfg;
/* Setting up call-back function */
cb[DMA_CHANNEL_UART_TX].cbFunc = UARTTxTransferComplete; //设置DMA完成之后,是否调用回调函数。如果没有回调函数,则设置为NULL
cb[DMA_CHANNEL_UART_TX].userPtr = NULL;
/* Setting up channel */
chnlCfg.highPri = false;
chnlCfg.enableInt = true;
//设置DMA发送下一字节的条件,此处为:当Tx发送完毕之后,DMA再开始取下一字节进行发送
chnlCfg.select = DMAREQ_USART1_TXEMPTY;
//初始化DMA寄存器中的回调部分的功能
chnlCfg.cb = &(cb[DMA_CHANNEL_UART_TX]);
DMA_CfgChannel(DMA_CHANNEL_UART_TX, &chnlCfg);
//定义DMA逻辑部分的寄存器
/* Setting up channel descriptor */
descrCfg.dstInc = dmaDataIncNone; //意思目标地址不变
descrCfg.srcInc = dmaDataInc1; //意思是源地址每次加1字节
descrCfg.size = dmaDataSize1; //每次发送的字节单位
descrCfg.arbRate = dmaArbitrate1; //DMA仲裁,每发送1字节,仲裁一次
descrCfg.hprot = 0;
DMA_CfgDescr(DMA_CHANNEL_UART_TX, true, &descrCfg);
//激活一次DMA发送
DMA_ActivateBasic(DMA_CHANNEL_UART_TX,
true,
false,
(void *)&(USART1->TXDATA),
(void *)&ucUARTTxBuffer,
SPITXSAMPLES - 1);
}
//DMA初始化,无需改动
void DMAInit(void)
{
CMU_ClockEnable(cmuClock_DMA, true);
/* Initializing the DMA */
dmaInit.hprot = 0;
dmaInit.controlBlock = dmaControlBlock;
DMA_Init(&dmaInit);
}
//Demo演示使用,初始化发送缓冲区
void Uart_Tx_Data_Init(void)
{
unsigned char ucData = '0';
unsigned long ucCount = 0;
for(ucCount = 0; ucCount < SPITXSAMPLES-2; ucCount++)
{
ucUARTTxBuffer[ucCount] = ucData;
if(ucData < '9')ucData++;
else ucData = '0';
}
ucUARTTxBuffer[ucCount] = '\n';
ucCount++;
ucUARTTxBuffer[ucCount] = '\r';
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
SystemCoreClockUpdate();
Uart_Tx_Data_Init();
DMAInit();
UART_Initial();
DMA_for_UART_Tx();
ucComplete = 1;
/* Infinite blink loop */
while(1)
{
//上一次的DMA是否发送完毕
if(ucComplete)
{
unsigned long ulDelay = 800000;
while(ulDelay--);
DMA_ActivateBasic(DMA_CHANNEL_UART_TX,
true,
false,
NULL,
NULL,
SPITXSAMPLES - 1);
ucComplete = 0;
}
}
}