STM32:DMA实例之串口(USART)通信

来源:互联网 发布:阿里云服务器到期后 编辑:程序博客网 时间:2024/05/17 01:59
硬件平台:stm32f10xZET6
开发环境:keil MDK uVision v4.10
开发语言:C、ST_lib_3.5固件库

/* 代码演示 main.c */#include "stm32f10x.h"#include "bsp_usart1.h"#include "bsp_led.h"extern uint8_t SendBuff[SENDBUFF_SIZE];static void Delay(__IO u32 nCount); /**  * @brief  主函数  */int main(void){/* USART1 config 115200 8-N-1 */USART1_Config();USART1_DMA_Config();LED_GPIO_Config();printf ("\r\n usart1 DMA TX test... \r\n");{uint16_t i;/*填充将要发送的数据*/for(i=0;i<SENDBUFF_SIZE;i++){SendBuff[i] = 'a'; // 打字母a仅做演示}}/* USART1 向 DMA发出TX请求 */USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);/* 此时CPU是空闲的,可以干其他的事情 *///例如同时控制LEDfor(;;){LED1(ON);Delay(0xFFFFF);LED1(OFF);Delay(0xFFFFF);}}static void Delay(__IO uint32_t nCount) //简单的延时函数{for(; nCount != 0; nCount--);}
/* 中断处理函数 stm32f10x_it.c line:157 */void DMA1_Channel4_IRQHandler(void){//判断是否为 DMA 发送完成中断if (DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET){//LED 关闭LED1(OFF);DMA_ClearFlag(DMA1_FLAG_TC4);}}
/* 代码演示 bsp_usart1模块 */#ifndef __USART1_H#define__USART1_H#include "stm32f10x.h"#include <stdio.h>#define USART1_DR_Base  0x40013804// 0x40013800 + 0x04 = 0x40013804#define SENDBUFF_SIZE   5000void USART1_Config(void);void USART1_DMA_Config(void);#endif /* __USART1_H */// ------------------------------------------------------#include "bsp_usart1.h"uint8_t SendBuff[SENDBUFF_SIZE];/**  * @brief  USART1 GPIO 配置,工作模式配置。115200 8-N-1  * @param  无  * @retval 无  */void USART1_Config(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);/* USART1 GPIO config *//* Configure USART1 Tx (PA.09) as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);    /* Configure USART1 Rx (PA.10) as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);/* USART1 mode config */USART_InitStructure.USART_BaudRate = 115200;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(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE);}/**  * @brief  USART1 TX DMA 配置,内存到外设(USART1->DR)  * @param  无  * @retval 无  */void USART1_DMA_Config(void){DMA_InitTypeDef DMA_InitStructure;/*开启DMA时钟*/RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);/*传输大小DMA_BufferSize=SENDBUFF_SIZE*/DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;  // 此处是发送的buffer的配置/*方向:从内存到外设*/DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;/*禁止内存到内存的传输*/DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;/*内存地址(要传输的变量的指针)*/DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;/*内存数据单位 8bit*/DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;/*内存地址自增*/DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;/*DMA模式:不断循环*/DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  /* 设置DMA源:串口数据寄存器地址 */DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;/* 外设数据单位:字节 */DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    /* 外设地址不增 */    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*优先级:中*/DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  /*配置DMA1的4通道*/   DMA_Init(DMA1_Channel4, &DMA_InitStructure);    /*使能DMA*/DMA_Cmd (DMA1_Channel4,ENABLE);//DMA_ITConfig(DMA1_Channel4, DMA_IT_TC,ENABLE);  // 配置DMA发送完成后产生中断}/// 重定向c库函数printf到USART1int fputc(int ch, FILE *f){/* 发送一个字节数据到USART1 */USART_SendData(USART1, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return (ch);}/// 重定向c库函数scanf到USART1int fgetc(FILE *f){/* 等待串口1输入数据 */while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);}
/* 代码演示 bsp_led模块 */#ifndef __LED_H#define__LED_H#include "stm32f10x.h"/** the macro definition to trigger the led on or off   * 1 - off  *0 - on  */#define ON  0#define OFF 1/* 带参宏,可以像内联函数一样使用 */#define LED1(a)if (a)\GPIO_SetBits(GPIOB,GPIO_Pin_0);\else\GPIO_ResetBits(GPIOB,GPIO_Pin_0)#define LED2(a)if (a)\GPIO_SetBits(GPIOF,GPIO_Pin_7);\else\GPIO_ResetBits(GPIOF,GPIO_Pin_7)#define LED3(a)if (a)\GPIO_SetBits(GPIOF,GPIO_Pin_8);\else\GPIO_ResetBits(GPIOF,GPIO_Pin_8)void LED_GPIO_Config(void);#endif /* __LED_H *///---------------------------------------------------------#include "bsp_led.h"    /**  * @brief  初始化控制LED的IO  * @param  无  * @retval 无  */void LED_GPIO_Config(void){/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启GPIOB和GPIOF的外设时钟*/RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE); /*选择要控制的GPIOB引脚*/   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;/*设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   /*设置引脚速率为50MHz */   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*调用库函数,初始化GPIOB0*/GPIO_Init(GPIOB, &GPIO_InitStructure);/*选择要控制的GPIOF引脚*/   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;/*调用库函数,初始化GPIOF7*/GPIO_Init(GPIOF, &GPIO_InitStructure);/*选择要控制的GPIOF引脚*/   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;/*调用库函数,初始化GPIOF7*/GPIO_Init(GPIOF, &GPIO_InitStructure);  /* 关闭所有led灯*/GPIO_SetBits(GPIOB, GPIO_Pin_0);/* 关闭所有led灯*/GPIO_SetBits(GPIOF, GPIO_Pin_7|GPIO_Pin_8); }
*注:LED灯的管脚Pin根据开发板的不同,实际去调整即可。

0 0
原创粉丝点击