编译器平台及例程说明
1. Toolchain : MDK-ARM Community Version: 5.30.0.0(Kile V5)
2. Encoding : Chinese GB2312(Simplified)
3. Device Specific Packs : Keil.STM32F1xx_DFP.2.3.0.pack
4. C/C++ Preprocessor Symbols : STM32F10X_HD,USE_STDPERIPH_DRIVER
USE_STDPERIPH_DRIVER :允许使用标准外设驱动
STM32F10X_HD :STM32F10x大容量产品
5. Chip Type :STM32F103RET6, Flash:512KByte, ROM:48KByte, LQFP64
6. 在stm32hf10x.h文件中HSE_VALUE为外部高速振荡器,默认8MHZ。此值必须与硬件保持一致。
1. 使用DMA1通道5,来传输USART1接收的数据,将数据存储在RXD1BUF中。
2. 使用DMA1通道4,来传输USART1发送的数据,要发送的数据存储在RXD1BUF中。
3. 使用USART1空闲中断,来通知数据已接收完成待处理,将接收到的数据原样转发到USART1,便于在串口调试助手中显示。
4. USART1空闲中断标志位无法直接用USART_ClearITPendingBit(USART1, USART_IT_IDLE)清除,必须读取SR和DR寄存器值可清除。
5. 使用DMA_GetCurrDataCounter()前,必须将DMA失能。
一、 DMA简介
DMA全称Direct Memory Access,即直接存储器访问。用来提供外设和存储器之间,或者存储器和存储器之间的高速数据传输。无须CPU控制,数据可以通过DMA传输,它通过硬件为RAM与I/O设备之间开辟一条直接传送数据的通道,这节省CPU的资源,使CPU效率提高。
二、 DMA框图
1. DMA2仅存在于大容量产品和互联型产品。
2. SPI/I2S3、 UART4、 TIM5、 TIM6、 TIM7和DAC的DMA请求仅存在于大容量产品和互联型产品。
3. ADC3、 SDIO和TIM8的DMA请求仅存在于大容量产品。
三、 DMA1/DMA2请求映像
DMA1控制器
从外设(TIMx[x=1、 2、 3、 4]、 ADC1、 SPI1、 SPI/I2S2、 I2Cx[x=1、 2]和USARTx[x=1、 2、 3])产生的7个请求,通过逻辑或输入到DMA1控制器,这意味着同时只能有一个请求有效。参见下图的DMA1请求映像。外设的DMA请求,可以通过设置相应外设寄存器中的控制位,被独立地开启或关闭。
DMA2控制器
从外设(TIMx[5、 6、 7、 8]、 ADC3、 SPI/I2S3、 UART4、 DAC通道1、 2和SDIO)产生的5个请求,经逻辑或输入到DMA2控制器,这意味着同时只能有一个请求有效。参见下图的DMA2请求映像。外设的DMA请求,可以通过设置相应外设寄存器中的DMA控制位,被独立地开启或关闭。
注意: DMA2控制器及相关请求仅存在于大容量产品和互联型产品中。
四、 DMA1/DMA2通道请求
五、 DMA相关宏定义
//DMA_data_transfer_direction
#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010)
#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000)
//DMA_peripheral_incremented_mode
#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040)
#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000)
//DMA_memory_incremented_mode
#define DMA_MemoryInc_Enable ((uint32_t)0x00000080)
#define DMA_MemoryInc_Disable ((uint32_t)0x00000000)
//DMA_peripheral_data_size
#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000)
#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100)
#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200)
//DMA_memory_data_size
#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000)
#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400)
#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800)
//DMA_circular_normal_mode
#define DMA_Mode_Circular ((uint32_t)0x00000020)
#define DMA_Mode_Normal ((uint32_t)0x00000000)
//DMA_priority_level
#define DMA_Priority_VeryHigh ((uint32_t)0x00003000)
#define DMA_Priority_High ((uint32_t)0x00002000)
#define DMA_Priority_Medium ((uint32_t)0x00001000)
#define DMA_Priority_Low ((uint32_t)0x00000000)
//DMA_memory_to_memory
#define DMA_M2M_Enable ((uint32_t)0x00004000)
#define DMA_M2M_Disable ((uint32_t)0x00000000)
// DMA1_FLAG_GL1: DMA1 Channel1 global flag.
// DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag.
// DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag.
// DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag.
// DMA1_FLAG_GL2: DMA1 Channel2 global flag.
// DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag.
// DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag.
// DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag.
// DMA1_FLAG_GL3: DMA1 Channel3 global flag.
// DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag.
// DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag.
// DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag.
// DMA1_FLAG_GL4: DMA1 Channel4 global flag.
// DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag.
// DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag.
// DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag.
// DMA1_FLAG_GL5: DMA1 Channel5 global flag.
// DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag.
// DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag.
// DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag.
// DMA1_FLAG_GL6: DMA1 Channel6 global flag.
// DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag.
// DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag.
// DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag.
// DMA1_FLAG_GL7: DMA1 Channel7 global flag.
// DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag.
// DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag.
// DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag.
// DMA2_FLAG_GL1: DMA2 Channel1 global flag.
// DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag.
// DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag.
// DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag.
// DMA2_FLAG_GL2: DMA2 Channel2 global flag.
// DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag.
// DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag.
// DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag.
// DMA2_FLAG_GL3: DMA2 Channel3 global flag.
// DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag.
// DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag.
// DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag.
// DMA2_FLAG_GL4: DMA2 Channel4 global flag.
// DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag.
// DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag.
// DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag.
// DMA2_FLAG_GL5: DMA2 Channel5 global flag.
// DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag.
// DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag.
// DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag.
//DMA_flags_definition
#define DMA1_FLAG_GL1 ((uint32_t)0x00000001)
#define DMA1_FLAG_TC1 ((uint32_t)0x00000002)
#define DMA1_FLAG_HT1 ((uint32_t)0x00000004)
#define DMA1_FLAG_TE1 ((uint32_t)0x00000008)
#define DMA1_FLAG_GL2 ((uint32_t)0x00000010)
#define DMA1_FLAG_TC2 ((uint32_t)0x00000020)
#define DMA1_FLAG_HT2 ((uint32_t)0x00000040)
#define DMA1_FLAG_TE2 ((uint32_t)0x00000080)
#define DMA1_FLAG_GL3 ((uint32_t)0x00000100)
#define DMA1_FLAG_TC3 ((uint32_t)0x00000200)
#define DMA1_FLAG_HT3 ((uint32_t)0x00000400)
#define DMA1_FLAG_TE3 ((uint32_t)0x00000800)
#define DMA1_FLAG_GL4 ((uint32_t)0x00001000)
#define DMA1_FLAG_TC4 ((uint32_t)0x00002000)
#define DMA1_FLAG_HT4 ((uint32_t)0x00004000)
#define DMA1_FLAG_TE4 ((uint32_t)0x00008000)
#define DMA1_FLAG_GL5 ((uint32_t)0x00010000)
#define DMA1_FLAG_TC5 ((uint32_t)0x00020000)
#define DMA1_FLAG_HT5 ((uint32_t)0x00040000)
#define DMA1_FLAG_TE5 ((uint32_t)0x00080000)
#define DMA1_FLAG_GL6 ((uint32_t)0x00100000)
#define DMA1_FLAG_TC6 ((uint32_t)0x00200000)
#define DMA1_FLAG_HT6 ((uint32_t)0x00400000)
#define DMA1_FLAG_TE6 ((uint32_t)0x00800000)
#define DMA1_FLAG_GL7 ((uint32_t)0x01000000)
#define DMA1_FLAG_TC7 ((uint32_t)0x02000000)
#define DMA1_FLAG_HT7 ((uint32_t)0x04000000)
#define DMA1_FLAG_TE7 ((uint32_t)0x08000000)
#define DMA2_FLAG_GL1 ((uint32_t)0x10000001)
#define DMA2_FLAG_TC1 ((uint32_t)0x10000002)
#define DMA2_FLAG_HT1 ((uint32_t)0x10000004)
#define DMA2_FLAG_TE1 ((uint32_t)0x10000008)
#define DMA2_FLAG_GL2 ((uint32_t)0x10000010)
#define DMA2_FLAG_TC2 ((uint32_t)0x10000020)
#define DMA2_FLAG_HT2 ((uint32_t)0x10000040)
#define DMA2_FLAG_TE2 ((uint32_t)0x10000080)
#define DMA2_FLAG_GL3 ((uint32_t)0x10000100)
#define DMA2_FLAG_TC3 ((uint32_t)0x10000200)
#define DMA2_FLAG_HT3 ((uint32_t)0x10000400)
#define DMA2_FLAG_TE3 ((uint32_t)0x10000800)
#define DMA2_FLAG_GL4 ((uint32_t)0x10001000)
#define DMA2_FLAG_TC4 ((uint32_t)0x10002000)
#define DMA2_FLAG_HT4 ((uint32_t)0x10004000)
#define DMA2_FLAG_TE4 ((uint32_t)0x10008000)
#define DMA2_FLAG_GL5 ((uint32_t)0x10010000)
#define DMA2_FLAG_TC5 ((uint32_t)0x10020000)
#define DMA2_FLAG_HT5 ((uint32_t)0x10040000)
#define DMA2_FLAG_TE5 ((uint32_t)0x10080000)
// DMA1_IT_GL1: DMA1 Channel1 global interrupt.
// DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt.
// DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt.
// DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt.
// DMA1_IT_GL2: DMA1 Channel2 global interrupt.
// DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt.
// DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt.
// DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt.
// DMA1_IT_GL3: DMA1 Channel3 global interrupt.
// DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt.
// DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt.
// DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt.
// DMA1_IT_GL4: DMA1 Channel4 global interrupt.
// DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt.
// DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt.
// DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt.
// DMA1_IT_GL5: DMA1 Channel5 global interrupt.
// DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt.
// DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt.
// DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt.
// DMA1_IT_GL6: DMA1 Channel6 global interrupt.
// DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt.
// DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt.
// DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt.
// DMA1_IT_GL7: DMA1 Channel7 global interrupt.
// DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt.
// DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt.
// DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt.
// DMA2_IT_GL1: DMA2 Channel1 global interrupt.
// DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt.
// DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt.
// DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt.
// DMA2_IT_GL2: DMA2 Channel2 global interrupt.
// DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt.
// DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt.
// DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt.
// DMA2_IT_GL3: DMA2 Channel3 global interrupt.
// DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt.
// DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt.
// DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt.
// DMA2_IT_GL4: DMA2 Channel4 global interrupt.
// DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt.
// DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt.
// DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt.
// DMA2_IT_GL5: DMA2 Channel5 global interrupt.
// DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt.
// DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt.
// DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt.
//DMA_interrupts_definition
#define DMA1_IT_GL1 ((uint32_t)0x00000001)
#define DMA1_IT_TC1 ((uint32_t)0x00000002)
#define DMA1_IT_HT1 ((uint32_t)0x00000004)
#define DMA1_IT_TE1 ((uint32_t)0x00000008)
#define DMA1_IT_GL2 ((uint32_t)0x00000010)
#define DMA1_IT_TC2 ((uint32_t)0x00000020)
#define DMA1_IT_HT2 ((uint32_t)0x00000040)
#define DMA1_IT_TE2 ((uint32_t)0x00000080)
#define DMA1_IT_GL3 ((uint32_t)0x00000100)
#define DMA1_IT_TC3 ((uint32_t)0x00000200)
#define DMA1_IT_HT3 ((uint32_t)0x00000400)
#define DMA1_IT_TE3 ((uint32_t)0x00000800)
#define DMA1_IT_GL4 ((uint32_t)0x00001000)
#define DMA1_IT_TC4 ((uint32_t)0x00002000)
#define DMA1_IT_HT4 ((uint32_t)0x00004000)
#define DMA1_IT_TE4 ((uint32_t)0x00008000)
#define DMA1_IT_GL5 ((uint32_t)0x00010000)
#define DMA1_IT_TC5 ((uint32_t)0x00020000)
#define DMA1_IT_HT5 ((uint32_t)0x00040000)
#define DMA1_IT_TE5 ((uint32_t)0x00080000)
#define DMA1_IT_GL6 ((uint32_t)0x00100000)
#define DMA1_IT_TC6 ((uint32_t)0x00200000)
#define DMA1_IT_HT6 ((uint32_t)0x00400000)
#define DMA1_IT_TE6 ((uint32_t)0x00800000)
#define DMA1_IT_GL7 ((uint32_t)0x01000000)
#define DMA1_IT_TC7 ((uint32_t)0x02000000)
#define DMA1_IT_HT7 ((uint32_t)0x04000000)
#define DMA1_IT_TE7 ((uint32_t)0x08000000)
#define DMA2_IT_GL1 ((uint32_t)0x10000001)
#define DMA2_IT_TC1 ((uint32_t)0x10000002)
#define DMA2_IT_HT1 ((uint32_t)0x10000004)
#define DMA2_IT_TE1 ((uint32_t)0x10000008)
#define DMA2_IT_GL2 ((uint32_t)0x10000010)
#define DMA2_IT_TC2 ((uint32_t)0x10000020)
#define DMA2_IT_HT2 ((uint32_t)0x10000040)
#define DMA2_IT_TE2 ((uint32_t)0x10000080)
#define DMA2_IT_GL3 ((uint32_t)0x10000100)
#define DMA2_IT_TC3 ((uint32_t)0x10000200)
#define DMA2_IT_HT3 ((uint32_t)0x10000400)
#define DMA2_IT_TE3 ((uint32_t)0x10000800)
#define DMA2_IT_GL4 ((uint32_t)0x10001000)
#define DMA2_IT_TC4 ((uint32_t)0x10002000)
#define DMA2_IT_HT4 ((uint32_t)0x10004000)
#define DMA2_IT_TE4 ((uint32_t)0x10008000)
#define DMA2_IT_GL5 ((uint32_t)0x10010000)
#define DMA2_IT_TC5 ((uint32_t)0x10020000)
#define DMA2_IT_HT5 ((uint32_t)0x10040000)
#define DMA2_IT_TE5 ((uint32_t)0x10080000)
六、 DMA初始化
u8 RXD1BUF[RXD1_BUF_SIZE] = {
0};
/**********************************************************************************************************************************************
* 函数名 : vDMA_Init
* 描 述 : DMA初始化
* 说 明 : 1. DMA1_Channel5 ==> USART1_RXD
* 2. DMA1_Channel4 ==> USART1_TXD
**********************************************************************************************************************************************/
void vDMA_Init(void)
{
//USART1 RXD DMA enable
vDMA_Config(DMA1_Channel5, (u32)(&USART1->DR), (u32)RXD1BUF, RXD1_BUF_SIZE, DMA_DIR_PeripheralSRC, DMA_Priority_High);
//USART1 TXD DMA enable
vDMA_Config(DMA1_Channel4, (u32)(&USART1->DR), (u32)RXD1BUF, 0, DMA_DIR_PeripheralDST, DMA_Priority_Medium);
}
/**********************************************************************************************************************************************
* 函数名 : vDMA_Config
* 描 述 : DMA配置
* 输 入 : channel : 通道
* perBaseAddr : 外设基地址
* memBaseAddr : 存储器基地址
* memSize : 存储器大小
* perDir : 外设方向(DMA_DIR_PeripheralDST/DMA_DIR_PeripheralSRC)
* priority : 优先级(DMA_Priority_VeryHigh/DMA_Priority_High/DMA_Priority_Medium/DMA_Priority_Low)
* 说 明 : 1. 外设基地址不变,储存器基地址自增长。
* 2. 外设和存储器数据宽度字节对齐。
* 3. DMA正常模式,不开启存储器到存储器传输。
**********************************************************************************************************************************************/
static void vDMA_Config(DMA_Channel_TypeDef * channel, u32 perBaseAddr, u32 memBaseAddr, u16 memSize, u8 perDir, u16 priority)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //Enable DMA1 clock
DMA_DeInit(channel); //Reset MDA channel
DMA_InitStructure.DMA_PeripheralBaseAddr = perBaseAddr; //Peripheral base address
DMA_InitStructure.DMA_MemoryBaseAddr = memBaseAddr; //Memory base address
DMA_InitStructure.DMA_DIR = perDir; //DMA transmit direction
DMA_InitStructure.DMA_BufferSize = memSize; //MDA Channel buffer size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Peripheral address incremented
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Memory address incremented
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //Peripheral data width
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //Memory data width
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMAy Channe mode
DMA_InitStructure.DMA_Priority = priority; //MDA Channel priority
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //Memory-to-memory transfer
DMA_Init(channel, &DMA_InitStructure); //DMA init
DMA_Cmd(channel, ENABLE); //Enable DMA channel
}
/**********************************************************************************************************************************************
* 函数名 : vDMA_Start_Channel_Transfer
* 描 述 : 开始DMA通道传输
* 输 入 : channel : 通道
* lenDat : 数据长度
* 说 明 : 1. DMA_SetCurrDataCounter()只在DMA失能下有效
**********************************************************************************************************************************************/
void vDMA_Start_Channel_Transfer(DMA_Channel_TypeDef * channel, u16 lenDat)
{
DMA_Cmd(channel, DISABLE); //Disable DMA channel
DMA_SetCurrDataCounter(channel, lenDat); //Set data count
DMA_Cmd(channel, ENABLE); //Enable DMA channel
}
#define RXD1_BUF_SIZE 200
extern u8 RXD1BUF[RXD1_BUF_SIZE];
void vDMA_Start_Channel_Transfer(DMA_Channel_TypeDef * channel, u16 lenDat); //vDMA_Start_Channel_Transfer
void vDMA_Init(void); //vDMA_Init
七、 USART1初始化
#define USE_USART1_ENABLE 1 //Use USART1 Enable
#define USE_USART1_RXD_ENABLE 1 //Use USART1 receive enable
#define USE_USART1_TXD_ENABLE 1 //Use USART1 transmit enable
#define USE_USART0_ENABLE 0 //Use USART0 Enable
#define USE_USART2_ENABLE 0 //Use USART2 Enable
#define USE_USART3_ENABLE 0 //Use USART3 Enable
#define USE_USART4_ENABLE 0 //Use USART4 Enable
#define USE_USART5_ENABLE 0 //Use USART5 Enable
/*************************
*********************************************************************************************************************
* 函数名 : vUSART_GPIO_Config
* 描 述 : USART GPIO配置
* 输 入 : USARTx : 串口对象
* 说 明 : Pin42 -- PA9 -- USRT1_TXD
* Pin43 -- PA10 -- USRT1_RXD
*
* Pin16 -- PA2 -- USRT2_TXD
* Pin17 -- PA3 -- USRT2_RXD
*
* Pin29 -- PB10 -- USRT3_TXD
* Pin30 -- PB11 -- USRT3_RXD
*
* Pin51 -- PC10 -- USART4_TXD
* Pin52 -- PC11 -- USART4_RXD
**********************************************************************************************************************************************/
static void vUSART_GPIO_Config(USART_TypeDef * USARTx)
{
GPIO_InitTypeDef GPIO_InitStructure;
#if ( USE_USART1_ENABLE > 0)
if(USARTx == USART1)
{
// Pin42 -- PA9 -- USRT1_TXD
// Pin43 -- PA10 -- USRT1_RXD
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //Enable USARTx clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Enable GPIO clock
//USART1_TXD
GPIO_InitStructure.GPIO_Pin = USART1_TXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Reuse Push pull output
GPIO_Init(USART1_GPIO, &GPIO_InitStructure); //Init GPIO pin
//USART1_RXD
GPIO_InitStructure.GPIO_Pin = USART1_RXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Float input
GPIO_Init(USART1_GPIO, &GPIO_InitStructure); //Init GPIO pin
}
#endif
#if ( USE_USART2_ENABLE > 0)
if(USARTx == USART2)
{
// Pin16 -- PA2 -- USRT2_TXD
// Pin17 -- PA3 -- USRT2_RXD
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE); //Enable USARTx clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Enable GPIO clock
//USRT2_TXD
GPIO_InitStructure.GPIO_Pin = USART2_TXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Reuse Push pull output
GPIO_Init(USART2_GPIO, &GPIO_InitStructure); //Init GPIO pin
//USRT2_RXD
GPIO_InitStructure.GPIO_Pin = USART2_RXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Float input
GPIO_Init(USART2_GPIO, &GPIO_InitStructure); //Init GPIO pin
}
#endif
#if ( USE_USART3_ENABLE > 0)
if(USARTx == USART3)
{
// Pin29 -- PB10 -- USRT3_TXD
// Pin30 -- PB11 -- USRT3_RXD
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART3, ENABLE); //Enable USARTx clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //Enable GPIO clock
//USRT3_TXD
GPIO_InitStructure.GPIO_Pin = USART3_TXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Reuse Push pull output
GPIO_Init(USART3_GPIO, &GPIO_InitStructure); //Init GPIO pin
//USRT3_RXD
GPIO_InitStructure.GPIO_Pin = USART3_RXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Float input
GPIO_Init(USART3_GPIO, &GPIO_InitStructure); //Init GPIO pin
}
#endif
#if ( USE_USART4_ENABLE > 0)
if(USARTx == UART4)
{
// Pin51 -- PC10 -- USART4_TXD
// Pin52 -- PC11 -- USART4_RXD
RCC_APB1PeriphClockCmd(RCC_APB2Periph_UART4, ENABLE); //Enable USARTx clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //Enable GPIO clock
//USART4_TXD
GPIO_InitStructure.GPIO_Pin = USART4_TXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Reuse Push pull output
GPIO_Init(USART4_GPIO, &GPIO_InitStructure); //Init GPIO pin
//USART4_RXD
GPIO_InitStructure.GPIO_Pin = USART4_RXD_Pin; //GPIO pin
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Float input
GPIO_Init(USART4_GPIO, &GPIO_InitStructure); //Init GPIO pin
}
#endif
#if ( USE_USART5_ENABLE > 0)
if(USARTx == UART5)
{
}
#endif
}
/**********************************************************************************************************************************************
* 函数名 : vUSART_BaudRate_Config
* 描 述 : 串口波特率配置
* 输 入 : USARTx : 串口对象
* baudRate : 波特率
* 说 明 : 1. 8Bit数据位+1Bit停止位+无校验+无硬件控制流+使能收发
**********************************************************************************************************************************************/
static void vUSART_BaudRate_Config(USART_TypeDef * USARTx, u32 baudRate)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = baudRate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8Bit data
USART_InitStructure.USART_StopBits = USART_StopBits_1; //1Bit stop
USART_InitStructure.USART_Parity = USART_Parity_No; //No odd-even check
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No Hardware Flow Contro
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //Enable Txd and Rxd
USART_Init(USARTx, &USART_InitStructure); //USARTx init
USART_Cmd(USARTx, ENABLE); //Enable USART
}
/**********************************************************************************************************************************************
* 函数名 : vUSART_Peripheral_Init
* 描 述 : 串口外设初始化
* 输 入 : USARTx : 串口对象
* baudRate : 波特率
**********************************************************************************************************************************************/
static void vUSART_Peripheral_Init(USART_TypeDef * USARTx, u32 baudRate)
{
vUSART_GPIO_Config(USARTx);
vUSART_BaudRate_Config(USARTx, baudRate);
}
/**********************************************************************************************************************************************
* 函数名 : vUSART1_ITConfig
* 描 述 : 串口1中断配置
* 输 入 : prePriority : 抢占优先级
* subPriority : 从优先级
* 说 明 : 1. 清除空闲标志需要读SR和DR寄存器方可清除
**********************************************************************************************************************************************/
static void vUSART1_ITConfig(u8 prePrio, u8 subPrio)
{
USART_Cmd(USART1, DISABLE); //Disable USART1
vIRQ_NVIC_Config(USART1_IRQn, prePrio, subPrio); //Config priority
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //Enables Idle interrupt
//Clear Idle flag
USART_GetFlagStatus(USART1, USART_FLAG_IDLE); //Get Idle flag
USART_ReceiveData(USART1); //Get receive data
USART_Cmd(USART1, ENABLE); //Enable USART1
}
/**********************************************************************************************************************************************
* 函数名 : vUSART1_DMAConfig
* 描 述 : 串口1DMA配置
* 说 明 : 1. USART_DMAReq_Tx : USART DMA transmit request
* 2. USART_DMAReq_Rx : USART DMA receive request
**********************************************************************************************************************************************/
static void vUSART1_DMAConfig(void)
{
USART_DMACmd(USART1, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); //Enable DMA receive/transmit request
}
/**********************************************************************************************************************************************
* 函数名 : vIRQ_NVIC_Config
* 描 述 : 中断NVIC配置
* 输 入 : perIRQ : 中断通道
* prePrio : 抢占优先级
* subPrio : 从优先级
**********************************************************************************************************************************************/
void vIRQ_NVIC_Config(IRQn_Type perIRQ, u8 prePrio, u8 subPrio)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = perIRQ; //IRQ Channel
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prePrio; //Preemption Priority
NVIC_InitStructure.NVIC_IRQChannelSubPriority = subPrio; //SubPriority Priority
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable IRQ Channe
NVIC_Init(&NVIC_InitStructure); //Init NVIC
}
/**********************************************************************************************************************************************
* 函数名 : vUSART_Init
* 描 述 : USART 初始化
**********************************************************************************************************************************************/
void vUSART_Init(void)
{
vUSART_Peripheral_Init(USART1, 115200);
vUSART1_ITConfig(3, 0);
vUSART1_DMAConfig();
printf("USART Init OK......\r\n");
}
/**********************************************************************************************************************************************
* printf()重定义
**********************************************************************************************************************************************/
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);
USART_SendData(DEBUG_USART, (u8)ch);
return (ch);
}
u16 txCount = 0;
#if ( USE_USART1_RXD_ENABLE > 0)
/**********************************************************************************************************************************************
* 函数名 : USART1_IRQHandler
* 描 述 : USART1中断服务
**********************************************************************************************************************************************/
void USART1_IRQHandler(void)
{
u16 reCount = 0;
OSIntEnter();
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_RXNE);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//Idle interrupt set
{
// Clear idle interrupt
// rDat = USART1->SR;//Read state register
// rDat = USART1->DR;//Read data register
USART_GetITStatus(USART1, USART_IT_IDLE);//Get idle interrupt state
USART_ReceiveData(USART1);//Get USARTx received data
reCount = DMA_GetCurrDataCounter(DMA1_Channel5);//Get remaining length
txCount = RXD1_BUF_SIZE - reCount;//Used length
printf("Used:%d --> Remain:%d\r\n", txCount, reCount);
vDMA_Start_Channel_Transfer(DMA1_Channel5, RXD1_BUF_SIZE);//Start transfer
}
OSIntExit();
}
#endif
// * Pin42 -- PA9 -- USRT1_TXD
// * Pin43 -- PA10 -- USRT1_RXD
#define USART1_GPIO GPIOA
#define USART1_TXD_Pin GPIO_Pin_9
#define USART1_RXD_Pin GPIO_Pin_10
// * Pin16 -- PA2 -- USRT2_TXD
// * Pin17 -- PA3 -- USRT2_RXD
#define USART2_GPIO GPIOA
#define USART2_TXD_Pin GPIO_Pin_2
#define USART2_RXD_Pin GPIO_Pin_3
// * Pin29 -- PB10 -- USRT3_TXD
// * Pin30 -- PB11 -- USRT3_RXD
#define USART3_GPIO GPIOB
#define USART3_TXD_Pin GPIO_Pin_10
#define USART3_RXD_Pin GPIO_Pin_11
// * Pin51 -- PC10 -- USART4_TXD
// * Pin52 -- PC11 -- USART4_RXD
#define USART4_GPIO GPIOC
#define USART4_TXD_Pin GPIO_Pin_10
#define USART4_RXD_Pin GPIO_Pin_11
void vUSART_BaudRate_Config(USART_TypeDef * USARTx, u32 baudRate); //vUSART_BaudRate_Config
void vUSART_Peripheral_Init(USART_TypeDef * USARTx, u32 baudRate); //vUSART_Peripheral_Init
void vUSART1_ITConfig(u8 prePrio, u8 subPrio); //vUSART1_ITConfig
void vUSART1_DMAConfig(void); //vUSART1_DMAConfig
八、 STM32F1xx DMA+USART1发送+接收+USART1空闲中断测试代码
extern u16 txCount;
/**********************************************************************************************************************************************
* 函数名 : vQueue_Task
* 描 述 :
**********************************************************************************************************************************************/
void vQueue_Task(void *pdata)
{
while(1)
{
OSTimeDlyHMSM(0, 0, 1, 200);
if(txCount)
{
// RXD1BUF[txCount] = 0;
// printf("Rec Dat : %s\r\n", RXD1BUF);
// txCount = 0;
DMA_ClearFlag(DMA1_FLAG_TC4);//Clear DMA1 Channel4 transfer complete flag
vDMA_Start_Channel_Transfer(DMA1_Channel4, txCount);//Start transfer
while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET);//Wait transfer finish
txCount = 0;
}
}
}
九、 运行结果
USART Init OK......
UID : 0x05DAFF30 0x33385333 0x57087238
Flash Cap : 512 KByte
Compile Date : Jan 22 2021 14:01:45
Hardware OK......
Debug Versions......
USART Init OK......
UID : 0x05DAFF30 0x33385333 0x57087238
Flash Cap : 512 KByte
Compile Date : Jan 22 2021 14:01:45
Hardware OK......
Debug Versions......
Used:15 --> Remain:185
uC/OS-II Idle
Used:14 --> Remain:186
uC/OS-II Tmr
Used:14 --> Remain:186
Used:46 --> Remain:154
STM32F1xx DMA+USART1发送+接收+USART1空闲中断
Used:15 --> Remain:185
Used:14 --> Remain:186
uC/OS-II Tmr
Used:14 --> Remain:186
Used:46 --> Remain:154
STM32F1xx DMA+USART1发送+接收+USART1空闲中断