说明:其他项目文件没有添加,主要实现DMA的接收(字节必须满足设定值才可以触发DMA中断,当前设定值为32个字节),main函数检查接收到数据后,通过DMA发送给串口调试助手;
1)主函数如下:
#include "uart_dma.h"
#include "misc.h"
#include <string.h>
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Uart2Config();
while(1)
{
if(uart2RecvFlag == 1)
{
uart2RecvFlag = 0;
uart2DmaClear();
uart2SendArray(uart2RecvData, uart2RecvLen);
memset(uart2RecvData, '\0', sizeof(uart2RecvData));
}
if(uart2SendFlag == 1)
{
uart2SendFlag = 0;
Uart2RxEnable();
}
}
}
1)uart_dma.c文件如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_dma.h"
#include "misc.h"
#include "systick.h"
#include "uart_dma.h"
uint8_t uart2RecvData[32] = {0};
uint8_t uart2RecvFlag = 0;
uint8_t uart2RecvLen = 0;
uint8_t uart2SendData[32] = {0};
uint8_t uart2SendFlag = 0;
unsigned char u485RxBuf[255];
void Uart2TxEnable(void)
{
GPIO_WriteBit(UART2_EN_PORT, UART2_EN_PIN, Bit_SET);
}
void Uart2RxEnable(void)
{
GPIO_WriteBit(UART2_EN_PORT, UART2_EN_PIN, Bit_RESET);
}
void Uart2Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//Config USART2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// ZIGEBB_SET---EN
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Configure USART2 Rx as input floating
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Configure USART2 Tx as
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_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;
USART_Init(USART2, &USART_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel =DMA1_Channel6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
NVIC_Init(&NVIC_InitStructure);
//
// DMA1 Channel6 (triggered by USART2 Rx event) Config
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)uart2RecvData; // U485BUFSIZE;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(uart2RecvData);
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_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;// DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);
// Enable USART2 DMA Rxrequest
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); // USART_DMAReq_Tx
//USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
USART_Cmd(USART2, ENABLE);
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)uart2SendData;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);
DMA_Cmd(DMA1_Channel7, ENABLE);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
}
void uart2DmaClear(void)
{
DMA_Cmd(DMA1_Channel6, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel6, sizeof(uart2RecvData));
DMA_Cmd(DMA1_Channel6, ENABLE);
}
void uart2SendArray(uint8_t *arr, uint8_t len)
{
if(len == 0)
return;
uint8_t sendLen = len>sizeof(uart2SendData) ? sizeof(uart2SendData) : len;
Uart2TxEnable();
while (DMA_GetCurrDataCounter(DMA1_Channel7));
if(arr)
memcpy(uart2SendData, arr, sendLen);
DMA_Cmd(DMA1_Channel7, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel7, sendLen);
DMA_Cmd(DMA1_Channel7, ENABLE);
}
3)uart_dma.h文件,代码如下:
#ifndef _UART_DAM_H_
#define _UART_DMA_H_
#include <stdint.h>
#define UART2_TX_PORT GPIOA
#define UART2_TX_PIN GPIO_Pin_2
#define UART2_RX_PORT GPIOA
#define UART2_RX_PIN GPIO_Pin_3
#define UART2_EN_PORT GPIOD
#define UART2_EN_PIN GPIO_Pin_1
#define BAUD_RATE (9600)
extern uint8_t uart2RecvData[32];
extern uint8_t uart2RecvFlag;
extern uint8_t uart2RecvLen;
extern uint8_t uart2SendFlag;
void Uart2GpioInit(void);
void Uart2Config(void);
void uart2DmaClear(void);
void uart2SendArray(uint8_t *arr, uint8_t len);
void Uart2RxEnable(void);
void Uart2TxEnable(void);
#endif /* uart_dma.h */
3)中断函数文件,代码如下:
#include "stm32f10x_it.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_dma.h"
#include "uart_dma.h"
void DMA1_Channel6_IRQHandler(void)
{
if(SET==DMA_GetITStatus(DMA1_IT_TC6))
{
DMA_ClearITPendingBit(DMA1_IT_TC6);
uart2RecvFlag = 1;
uart2RecvLen = sizeof(uart2RecvData) - DMA_GetCurrDataCounter(DMA1_Channel6);
}
}
void DMA1_Channel7_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC7) != RESET)
{
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Cmd(DMA1_Channel7, DISABLE);
DMA1_Channel7->CNDTR=0;
uart2SendFlag = 1;
}
}
5)测试效果如下图所示: