微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32 串口DMA方式接收

STM32 串口DMA方式接收

时间:11-19 来源:互联网 点击:
STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M。最近因为要在车机上集成TPMS功能, 便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USART1~USART5),支持DMA方式通信,DMA方式由于不需要CPU的参与,而是直接由DMA控制器完成串口数据的读写,因而可以很大程度的提高CPU的利用率。在使用STM32串口之前需要做一系列的初始化工作:

1.RCC(复位和时钟控制寄存器)初始化,启用GPIO、DMA、USART时钟。
2.NVIC(嵌套向量中断控制寄存器)初始化,完成各个硬件中断的配置。
3.USART初始话,配置串口,设置DMA通道等。
4.DMA初始化,完成DMA的配置。
最后是使能USART和DMA。下面是通过DMA的方式从串口USART1接收数据,STM32工作后串口数据由DMA控制器接收存到指定buffer,读取数据直接从DMA buffer中读取即可。发送数据采用非DMA方式,首先将待发送的数据存入到发送队列,然后在任务循环中将队列中的数据发送给USART1。实例代码如下:
[cpp] view plaincopy
//**********************************************************************************************
// STM32F10x USART Test
// compiler: Keil UV3
// 2011-03-28 , By friehood
//**********************************************************************************************
static int8u rDMABuffer[64]; // DMA buffer
static int16u rDMARear = sizeof(rDMABuffer);

static int8u USART_RevBuf[64]; // 串口接收buffer
static int8u USART_SndBuf[64]; // 串口发送buffer
static int8u Head=0,Tail=0; // 发送buffer的头尾

// 串口任务
void Task_USART(void)
{
int16u end;
if (USART1->SR & (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE))
{
USART_ReceiveData(USART1);
}

// DMA接收
end = DMA_GetCurrDataCounter(DMA1_Channel5);
/*if((sizeof(rDMABuffer)-end)>0)
dbgprt("DMA available datalen=%d/n",sizeof(rDMABuffer)-end); */
while(rDMARear != end)
{
USART_receive(rDMABuffer[sizeof(rDMABuffer)-rDMARear]);
if (!(--rDMARear))
{
rDMARear = sizeof(rDMABuffer);
}
}

//发送
if(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET)
{
int8u chr;
// 从发送队列取出一个字符
if(PopFront(&chr))
{
USART_SendData(USART1, chr);
dbgprt("USART_SendData:0x%02x/n",chr);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
}
}
}

// USART串口初始化
void dev_USART_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

/* DMA1 Channel5 (triggered by USART1 Rx event) Config */ //参见 STM32 datasheet
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)rDMABuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(rDMABuffer);
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);

USART_InitStructure.USART_BaudRate = 9600;
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;

//配置IO: GPIOA9和GPIOA10分别作为串口TX、RX端。 见STM32 datasheet
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_InitStructure);

/

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top