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

发布者:楼高峰最新更新时间:2017-09-21 来源: eefocus关键字:STM32  DMA  串口  USART 手机看文章 扫描二维码
随时随地手机看文章

硬件平台:stm32f10xZET6
开发环境:keil MDK uVision v4.10
开发语言:C、ST_lib_3.5固件库

  1. /* 代码演示 main.c */  

  2. #include "stm32f10x.h"  

  3. #include "bsp_usart1.h"  

  4. #include "bsp_led.h"  

  5.   

  6. extern uint8_t SendBuff[SENDBUFF_SIZE];  

  7. static void Delay(__IO u32 nCount);   

  8.   

  9. /** 

  10.   * @brief  主函数 

  11.   */  

  12. int main(void)  

  13. {  

  14.         /* USART1 config 115200 8-N-1 */  

  15.         USART1_Config();  

  16.       

  17.         USART1_DMA_Config();  

  18.       

  19.         LED_GPIO_Config();  

  20.       

  21.         printf ("\r\n usart1 DMA TX test... \r\n");  

  22.       

  23.         {  

  24.             uint16_t i;  

  25.             /*填充将要发送的数据*/  

  26.             for(i=0;i

  27.             {  

  28.                 SendBuff[i]  = 'a'; // 打字母a仅做演示  

  29.             }  

  30.         }  

  31.           

  32.         /* USART1 向 DMA发出TX请求 */  

  33.         USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);  

  34.   

  35.         /* 此时CPU是空闲的,可以干其他的事情 */  

  36.           

  37.         //例如同时控制LED  

  38.         for(;;)  

  39.         {  

  40.             LED1(ON);  

  41.             Delay(0xFFFFF);  

  42.             LED1(OFF);  

  43.             Delay(0xFFFFF);  

  44.         }  

  45. }  

  46.   

  47. static void Delay(__IO uint32_t nCount)  //简单的延时函数  

  48. {  

  49.     for(; nCount != 0; nCount--);  

  50. }  



  1. /* 中断处理函数 stm32f10x_it.c line:157 */  

  2. void DMA1_Channel4_IRQHandler(void)  

  3. {  

  4.     //判断是否为 DMA 发送完成中断  

  5.     if (DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)  

  6.     {  

  7.         //LED 关闭  

  8.         LED1(OFF);  

  9.   

  10.   

  11.         DMA_ClearFlag(DMA1_FLAG_TC4);  

  12.     }  

  13. }  


  1. /* 代码演示 bsp_usart1模块 */  

  2. #ifndef __USART1_H  

  3. #define __USART1_H  

  4.   

  5.   

  6. #include "stm32f10x.h"  

  7. #include   

  8.   

  9.   

  10. #define USART1_DR_Base  0x40013804      // 0x40013800 + 0x04 = 0x40013804  

  11. #define SENDBUFF_SIZE   5000  

  12.   

  13.   

  14. void USART1_Config(void);  

  15. void USART1_DMA_Config(void);  

  16.   

  17.   

  18. #endif /* __USART1_H */  

  19. // ------------------------------------------------------  

  20. #include "bsp_usart1.h"  

  21.   

  22.   

  23. uint8_t SendBuff[SENDBUFF_SIZE];  

  24.   

  25.   

  26. /** 

  27.   * @brief  USART1 GPIO 配置,工作模式配置。115200 8-N-1 

  28.   * @param  无 

  29.   * @retval 无 

  30.   */  

  31. void USART1_Config(void)  

  32. {  

  33.         GPIO_InitTypeDef GPIO_InitStructure;  

  34.         USART_InitTypeDef USART_InitStructure;  

  35.           

  36.         /* config USART1 clock */  

  37.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);  

  38.           

  39.         /* USART1 GPIO config */  

  40.         /* Configure USART1 Tx (PA.09) as alternate function push-pull */  

  41.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  

  42.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

  43.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  44.         GPIO_Init(GPIOA, &GPIO_InitStructure);      

  45.         /* Configure USART1 Rx (PA.10) as input floating */  

  46.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

  47.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  48.         GPIO_Init(GPIOA, &GPIO_InitStructure);  

  49.               

  50.         /* USART1 mode config */  

  51.         USART_InitStructure.USART_BaudRate = 115200;  

  52.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

  53.         USART_InitStructure.USART_StopBits = USART_StopBits_1;  

  54.         USART_InitStructure.USART_Parity = USART_Parity_No ;  

  55.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

  56.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  

  57.   

  58.   

  59.         USART_Init(USART1, &USART_InitStructure);   

  60.         USART_Cmd(USART1, ENABLE);  

  61. }  

  62.   

  63.   

  64. /** 

  65.   * @brief  USART1 TX DMA 配置,内存到外设(USART1->DR) 

  66.   * @param  无 

  67.   * @retval 无 

  68.   */  

  69. void USART1_DMA_Config(void)  

  70. {  

  71.         DMA_InitTypeDef DMA_InitStructure;  

  72.       

  73.         /*开启DMA时钟*/  

  74.         RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);  

  75.   

  76.   

  77.         /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/      

  78.         DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;  // 此处是发送的buffer的配置  

  79.         /*方向:从内存到外设*/         

  80.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  

  81.         /*禁止内存到内存的传输    */  

  82.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  

  83.   

  84.   

  85.         /*内存地址(要传输的变量的指针)*/  

  86.         DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;  

  87.         /*内存数据单位 8bit*/  

  88.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  

  89.         /*内存地址自增*/  

  90.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  

  91.   

  92.   

  93.         /*DMA模式:不断循环*/  

  94.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    

  95.                            

  96.         /* 设置DMA源:串口数据寄存器地址 */  

  97.         DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;  

  98.         /* 外设数据单位:字节 */   

  99.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;              

  100.         /* 外设地址不增 */          

  101.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   

  102.   

  103.   

  104.         /*优先级:中*/     

  105.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;    

  106.   

  107.   

  108.         /*配置DMA1的4通道*/           

  109.         DMA_Init(DMA1_Channel4, &DMA_InitStructure);         

  110.           

  111.         /*使能DMA*/  

  112.         DMA_Cmd (DMA1_Channel4,ENABLE);                   

  113.         //DMA_ITConfig(DMA1_Channel4, DMA_IT_TC,ENABLE);  // 配置DMA发送完成后产生中断  

  114. }  

  115.   

  116.   

  117. /// 重定向c库函数printf到USART1  

  118. int fputc(int ch, FILE *f)  

  119. {  

  120.         /* 发送一个字节数据到USART1 */  

  121.         USART_SendData(USART1, (uint8_t) ch);  

  122.           

  123.         /* 等待发送完毕 */  

  124.         while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);         

  125.       

  126.         return (ch);  

  127. }  

  128.   

  129.   

  130. /// 重定向c库函数scanf到USART1  

  131. int fgetc(FILE *f)  

  132. {  

  133.         /* 等待串口1输入数据 */  

  134.         while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);  

  135.   

  136.   

  137.         return (int)USART_ReceiveData(USART1);  

  138. }  


  1. /* 代码演示 bsp_led模块 */  

  2. #ifndef __LED_H  

  3. #define __LED_H  

  4.   

  5.   

  6. #include "stm32f10x.h"  

  7.   

  8.   

  9. /** the macro definition to trigger the led on or off  

  10.   * 1 - off 

  11.   *0 - on 

  12.   */  

  13. #define ON  0  

  14. #define OFF 1  

  15.   

  16.   

  17. /* 带参宏,可以像内联函数一样使用 */  

  18. #define LED1(a) if (a)  \  

  19.                     GPIO_SetBits(GPIOB,GPIO_Pin_0);\  

  20.                     else        \  

  21.                     GPIO_ResetBits(GPIOB,GPIO_Pin_0)  

  22.   

  23. #define LED2(a) if (a)  \  

  24.                     GPIO_SetBits(GPIOF,GPIO_Pin_7);\  

  25.                     else        \  

  26.                     GPIO_ResetBits(GPIOF,GPIO_Pin_7)  

  27.   

  28. #define LED3(a) if (a)  \  

  29.                     GPIO_SetBits(GPIOF,GPIO_Pin_8);\  

  30.                     else        \  

  31.                     GPIO_ResetBits(GPIOF,GPIO_Pin_8)  

  32.   

  33. void LED_GPIO_Config(void);  

  34.   

  35. #endif /* __LED_H */  

  36. //---------------------------------------------------------  

  37. #include "bsp_led.h"     

  38.   

  39.   

  40.  /** 

  41.   * @brief  初始化控制LED的IO 

  42.   * @param  无 

  43.   * @retval 无 

  44.   */  

  45. void LED_GPIO_Config(void)  

  46. {         

  47.         /*定义一个GPIO_InitTypeDef类型的结构体*/  

  48.         GPIO_InitTypeDef GPIO_InitStructure;  

  49.   

  50.   

  51.         /*开启GPIOB和GPIOF的外设时钟*/  

  52.         RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE);   

  53.   

  54.   

  55.         /*选择要控制的GPIOB引脚*/                                                                

  56.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;     

  57.   

  58.   

  59.         /*设置引脚模式为通用推挽输出*/  

  60.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     

  61.   

  62.   

  63.         /*设置引脚速率为50MHz */     

  64.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   

  65.   

  66.   

  67.         /*调用库函数,初始化GPIOB0*/  

  68.         GPIO_Init(GPIOB, &GPIO_InitStructure);    

  69.           

  70.         /*选择要控制的GPIOF引脚*/                                                                

  71.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;  

  72.   

  73.   

  74.         /*调用库函数,初始化GPIOF7*/  

  75.         GPIO_Init(GPIOF, &GPIO_InitStructure);  

  76.           

  77.         /*选择要控制的GPIOF引脚*/                                                                

  78.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  

  79.   

  80.   

  81.         /*调用库函数,初始化GPIOF7*/  

  82.         GPIO_Init(GPIOF, &GPIO_InitStructure);              

  83.   

  84.   

  85.         /* 关闭所有led灯 */  

  86.         GPIO_SetBits(GPIOB, GPIO_Pin_0);  

  87.           

  88.         /* 关闭所有led灯 */  

  89.         GPIO_SetBits(GPIOF, GPIO_Pin_7|GPIO_Pin_8);    

  90. }  

*注:LED灯的管脚Pin根据开发板的不同,实际去调整即可。


关键字:STM32  DMA  串口  USART 引用地址:STM32:DMA实例之串口(USART)通信

上一篇:STM32:ADC采集数据实例(采用DMA模式)
下一篇:STM32:GPIO基础与对应管脚操作库函数

推荐阅读最新更新时间:2024-03-16 15:37

STM32库函数void USART_SendData()的缺陷和解决方法
简介:本文主要谈到了STM32库函数void USART_SendData()存在的一些问题,针对这些问题提到了3个解决方案,一起来看看。 2.1问题及现象 使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。 如: for(TxCounter = 0;TxCounter RxCounter; TxCounter++) USART_SendData(USART1, RxBuffer ); 2.2原因 此API
[单片机]
stm32中i2c之学习浅谈
首先介绍下自己的学习背景,博主本人是在上周刚入门stm32并且学习gpio口基本用法和中断的介绍。在这样的知识储备下我开始学习I2c通信协议,并尝试编写了师兄布置的一个小任务。 1.1. I2C总线物理结构 首先介绍下i2c通信协议,从物理层上来看这是一种非常简洁明了的通信协议。本身一共就两条总线,一条SCL(时钟总线),一条SDA(数据总线)。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。硬件图如下: 1.2 I2C总线特征 I2C总线上的每一个设备都可以作为主设备或
[单片机]
<font color='red'>stm32</font>中i2c之学习浅谈
STM32 进阶教程 8 - 位带操作
前言 有过51单片机开发经历的朋友应该都对51的IO口或一些特殊寄存器可以直接按位操作的方式不陌生吧,那么在stm32中有没有类似的操作呢,答案是肯定的,本节将给大家介绍如何在STM32中实现位带操作。 在《ARM Cortex-M3权为指南》中的第87页对位带操作如下描述: 位带操作 支持了位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。在 CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过
[单片机]
<font color='red'>STM32</font> 进阶教程 8 - 位带操作
基于STM32的温度采集报警系统
单片机源程序如下: #include stm32f10x.h #include delay.h #include usart.h #include LCD1602.h #include led.h #include ds18b20.h //Buzzer--------------- PB8 //LED1----------------- PB15 //LED2----------------- PA8 //Relay2--------------- PA9 //Relay1--------------- PA10 float Set_H = 35.0; //高温报警温度 float Set_L = 10
[单片机]
基于<font color='red'>STM32</font>的温度采集报警系统
如何用STM32CubeIDE软件实现STM32外部中断
本文用STM32CubeIDE软件实现STM32外部中断实例。 新建工程 “File”-“New”-“STM32 Project”。 输入芯片型号STM32F103ZE。 选择相应封装,下一步。 填写项目名,选择工程位置,下一步。 配置时钟、调试模式 选择高速外部时钟。 HCLK总线时钟处输入72,回车,配置使用最高时钟频率。 调试模式选择串行,方便下载程序。 配置管脚外设 本实例中用到了LED1与KEY_LEFT,找到相应电路图。 可见LED1对应PC0管脚,低电平点亮。按键K1对应PE2管脚,低电平有效。 PC0配置为GPIO_Output,GPIO输出模式 PE2配置为GPIO_EX TI 2,GPIO中断线2。 对G
[单片机]
如何用STM32CubeIDE软件实现<font color='red'>STM32</font>外部中断
stm32 TIM2定时器触发ADC、DMA采样
使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!采用TIM2定时器的触发间隔,实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断。 做示波器时,由于要做调整横坐标显示倍数增大和缩小,故需要改变采样频率,也就是改变TIM2 的定时器时间间隔,在TIM2初始化函数定义时,添加u16 Value参数,第一次调试时,设置如下: 定时器2初始化函数void TIM2_Configuration(u16 Value),配置TIM_Period = Value - 1; TIM_TimeBaseStructu
[单片机]
STM32 基础系列教程 0 - CubeMX 下载与安装
前言 学习STM32CUBEMX工具的下载与安装,学会从st官网(www.st.com)查找与下载资料。 示例详解 STM32CUBEMX 下载 进入st官网(www.st.com),在官网的网页搜索框中输入STM32cubeMX 在跳转后面网页中,点 Get Software 网页自动跳转到尾部,选选最高版本(如图中5.0.1) 在弹出的界面中点ACCEPT,然后输入用户名及邮箱地址(用于接收下载地址),勾选I have…后点DOWNLOAD 此时网页显示界面如下,登入邮箱,去查收下载地址,在接收到的邮件中直接点击DownLoad Now 网页自动加载,然后自动下载 stm32cub
[单片机]
<font color='red'>STM32</font> 基础系列教程 0 - CubeMX 下载与安装
认识STM32的复位与电源管理
复位功能是一个非常重要的功能,大到PC,小到单片机,每一台计算机系统都有。在我小时候,去网吧的时候,但凡是电脑出现任何一点小问题,网管的第一回答一定是重启。重启和复位就是同一个意思。 发展到现在PC已经很稳定了,复位按钮慢慢的淡出我们的视野,但是在主板上我们依然可以找到复位电路的存在。单片机上的复位功能也有着类似的变化,在我们学单片机那个年代,需要在单片机的外部一个复位电路,从专用引脚上接一个电阻和电容组成的复位电路。如果没有这个电路,单片机就没法工作。现在的新款单片机都把复位功能内置到单片机中。如果是开发项目要手动复位,我们可以在复位引脚上接一个按键用来手动复位。 复位 复位功能的作用是让RAM 中的数据清空,让所有连接
[单片机]
认识<font color='red'>STM32</font>的复位与电源管理
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved