STM32F030-UART1_DMA使用提示

前言:

今天把STM32F030C8T6的串口DMA学习了一下,为了加快各位研发人员的开发进度,避免浪费大量的时间在硬件平台上,写出个人代码调试的经验。个人水平有限,如有错误,还请指正mr.li.ming@qq.com。

提示:使用的内部RC时钟,最大速度48MHz;使用USART1-PA9/PA10.

第一步:初始化端口

/*******************************************************************************

* @brief  串口1端口初始化

* @param  None

* @retval None

****************************************************************Author:Liming**/

void USART1_GPIO_Init(void)

{

GPIO_InitTypeDef    GPIO_Initstructure;

RCC_AHBPeriphClockCmd(USART1_GPIO_CLK,ENABLE);

/* Connect pin to Periph */

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);   // 注意这里是GPIO_PinSource9

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

GPIO_Initstructure.GPIO_Pin=USART1_TX_PIN;

GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AF;

GPIO_Initstructure.GPIO_OType=GPIO_OType_PP;  // 推挽输出

GPIO_Initstructure.GPIO_PuPd=GPIO_PuPd_UP;

GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(USART1_GPIO_PORT,&GPIO_Initstructure);

GPIO_Initstructure.GPIO_Pin = USART1_RX_PIN;  // 浮空输入

GPIO_Init(USART1_GPIO_PORT,&GPIO_Initstructure);

}

第二步:初始化UART1

/*******************************************************************************

* @brief  串口1初始化

* @param  None

* @retval None

****************************************************************Author:Liming**/

void USART1_Init(uint32_t BaudRate)

{

USART_InitTypeDef   USART_Initstructure;

RCC_APB2PeriphClockCmd(USART1_CLK,ENABLE);

USART1_GPIO_Init(); // 调用了上面的端口初始化,故主函数里调用此函数即可。

USART_Initstructure.USART_BaudRate = BaudRate;

USART_Initstructure.USART_Parity   =USART_Parity_No;

USART_Initstructure.USART_WordLength =USART_WordLength_8b;

USART_Initstructure.USART_StopBits  =USART_StopBits_1;

USART_Initstructure.USART_Mode     = USART_Mode_Rx|USART_Mode_Tx;

USART_Initstructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;

USART_Init(USART1,&USART_Initstructure);

USART_ClearFlag(USART1,USART_FLAG_TC);

USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);

USART_Cmd(USART1,ENABLE);      // 使能串口

}

第三步:DMA1中断配置

/*******************************************************************************

* @brief  DMA1中断配置

* @param  None

* @retval None

****************************************************************Author:Liming**/

void DMA1_NVIC_Init(void)

{

NVIC_InitTypeDef    NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPriority = 2;

NVIC_Init(&NVIC_InitStructure);

}

注意事项:

1.    
USART1发送数据
使用的是DMA1的第二通道。查表可知,为什么还有第四通道呢,那是给USART1端口重映射了之后使用的。

第四步:DMA1配置

/*******************************************************************************

*
@brief  DMA1配置

*
@param  None

* @retval
None

****************************************************************Author:Liming**/

void DMA1_Init(void)

{

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

DMA_InitStructure.DMA_BufferSize = 12; 
// 缓存大小

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    // 内存到内存关闭

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;   // 普通模式

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  // 内存到外设

DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA通道优先级

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 内存地址递增

DMA_InitStructure.DMA_PeripheralBaseAddr =
(uint32_t)&USART1->TDR;   // 外设地址

DMA_InitStructure.DMA_PeripheralInc = 
DMA_PeripheralInc_Disable;// 外设地址不变

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据长度

DMA_InitStructure.DMA_MemoryBaseAddr
= (uint32_t)UART1_TXBUFFER;   // 定义内存基地址

DMA_InitStructure.DMA_PeripheralDataSize =
DMA_PeripheralDataSize_Byte;//外设数据长度

DMA_Init(DMA1_Channel2,&DMA_InitStructure);

DMA_ClearITPendingBit(DMA1_IT_TC2); // 清除一次DMA中断标志

DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);// 使能DMA传输完成中断

DMA1_NVIC_Init(); // 调用了上面的中断配置,故主函数里调用此函数即可

DMA_Cmd(DMA1_Channel2,ENABLE);

}

注意事项:

1.    
缓存大小:就是你一次要发送多长的数据。

2.    
DMA方向:因为是串口发送数据,所以是从内存到外设,USART1对于单片机来讲是个外设。定义的发送数组是内存。

3.    
内存地址递增:其实不难理解,从发送数组的UART1_TXBUFFER[0]- UART1_TXBUFFER[n]肯定是递增的。

4.    
外设地址不递增:所有的数据都是通过串口发送寄存器发出去,所以外设地址不变。

5.    
内存/外设数据长度:串口发送的数据都是字节为单位,所以长度是Byte

6.    
DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);注意这一句不要写错。

第五步:DMA1的中断处理函数

/**

*
@brief  DMA1_Channel1中断服务函数

*
@param  无

* @retval 无

*/

void DMA1_Channel2_3_IRQHandler(void)

{

/*判断DMA传输完成中断*/

if(DMA_GetITStatus(DMA1_IT_TC2)
!= RESET)

{

UART1_STATE = 2;// send over

}

/*清除DMA中断标志位*/

DMA_ClearITPendingBit(DMA1_IT_TC2);

}

这里使用了一个变量UART1_STATE作为标志位

第六步:使用DMA1发送串口数据

USART1_Init(115200);

DMA1_Init();

while(1)

{

if(UART1_STATE==2)

{

UART1_STATE = 1;

DMA_Cmd(DMA1_Channel2,DISABLE); // 发送完成先关掉DMA通道

DMA_SetCurrDataCounter(DMA1_Channel2,12); // 设置需要发送的长度

DMA_Cmd(DMA1_Channel2,ENABLE); // 再打开DMA通道

}

GPIO_SetBits(GPIOA,GPIO_Pin_4);Delay(500);

GPIO_SetBits(GPIOA,GPIO_Pin_3);Delay(500);

GPIO_ResetBits(GPIOA,GPIO_Pin_4);Delay(500);

GPIO_ResetBits(GPIOA,GPIO_Pin_3);Delay(500);

}

注意事项:

1.    
一定要注意,DMA的传输有个长度计数器,DMA传输完成后,计数器里的值就变成了0;数据是不传了,但是通道并没有关闭。所以想要再次传输就需要修改这个长度计数器的值,但是这个值的修改必须要关闭通道后修改。所以就有了上面的步骤,关闭通道—修改计数值—打开通道

希望对各位看官有所帮助,并能触类旁通,对于外设到内存啊,内存到内存啊,ADC与DMA啊,SPI与DMA都能轻松的应用。

STM32F030-UART1_DMA使用提示的更多相关文章

  1. iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法

    问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...

  2. jsp中出现onclick函数提示Cannot return from outside a function or method

    在使用Myeclipse10部署完项目后,原先不出错的项目,会有红色的叉叉,JSP页面会提示onclick函数错误 Cannot return from outside a function or m ...

  3. 【SQLServer】【恢复挂起的解决方案】附加文件时候的提示“无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。 ”【数据库恢复】

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 先贴错误: 吐槽一下: 进入正题: 新建一个同名数据库 停止MSSQL服务 替换数据库文 ...

  4. SQLServer执行命令出现“目录无效的提示”

    异常处理汇总-数据库系列  http://www.cnblogs.com/dunitian/p/4522990.html 一般都是清理垃圾清理过头了,把不该删的目录删了 网上说法: 问题描述: 1.s ...

  5. 利用CSS中的:after、: before制作的边三角提示框

    小颖昨天分享了一篇参考bootstrap中的popover.js的css画消息弹框今天给大家再分享一篇使用:before和:after伪元素画消息弹框的CSS. 画出来是介个酱紫的: 有没有觉得画的萌 ...

  6. TypeScript Vs2013 下提示Can not compile modules unless '--module' flag is provided

    VS在开发TypeScript程序时候,如果import了模块有的时候会有如下提示: 这种情况下,只需要对当前TypeScript项目生成设置为AMD规范即可!

  7. 当web.config文件放置在共享目录下(UNC),启动IIS会提示有错误信息500.19,伴随有错误代码0x80070003和错误代码0x80070005的解决办法

    最近遇到一个很有意思的使用环境,操作人员将所有的网站应用内容投放到共享存储里面,并且使用微软的SMB协议将其以CIFS的方式共享出来,使用Windows Server 2008 R2的IIS将其连接起 ...

  8. HTML5轻松实现搜索框提示文字点击消失---及placeholder颜色的设置

    在做搜索框的时候无意间发现html5的input里有个placeholder属性能轻松实现提示文字点击消失功能,之前还傻傻的在用js来实现类似功能... 示例 <form action=&quo ...

  9. Win10提示没有权限使用网络资源问题解决

    借鉴链接:http://www.cr173.com/html/67361_1.html Win10提示没有权限使用网络资源解决方法 1.打开控制面板; 2.在所有控制面板项中找到凭据管理器; 3.添加 ...

  10. Xamarin Android 应用程序内图标上数字提示

    最近在用 Xamarin 做一个 Android 应用,打开应用时,如果有新消息,需要在应用内的 Toolbar 或者首页的图标上显示数字提示.在这里和大家分享一下实现方法,如果你有更新好的实现方法, ...

随机推荐

  1. 2019.12.11 java练习

    class Demo01 { public static void main(String[] args) { //数组求最大值 int[] arr={1,2,3,4,5,6,7,8,9}; int ...

  2. Codeforces - 1264C - Beautiful Mirrors with queries - 概率期望dp

    一道挺难的概率期望dp,花了很长时间才学会div2的E怎么做,但这道题是另一种设法. https://codeforces.com/contest/1264/problem/C 要设为 \(dp_i\ ...

  3. 小技巧--解决eclipse导入的jar文件后,无法使用默认包中的方法问题

    问题:我已经导入了stdlib的jar文件,但是由于包是(default package)所以无法使用包中的方法 解决方法: 1.新建一个项目 2.新建一个文件夹 3.打开项目,新建一个包,然后导入j ...

  4. PHP 之Mysql优化

    一.建立索引 普通索引 index: 对关键字没有要求. 唯一索引 unique index: 要求关键字不能重复.同时增加唯一约束. 主键索引 primary key: 要求关键字不能重复,也不能为 ...

  5. 懵了!简单的HTTP调用,时延竟如此大?

    最近项目测试遇到个奇怪的现象,在测试环境通过 Apache HTTP Client 调用后端的 HTTP 服务,平均耗时居然接近 39.2ms. 图片来自 Pexels 可能乍一看觉得这不是很正常吗, ...

  6. Java 自定义异常

    新建类CustomException继承 Exception /** * Create by on 2019-07-30 * 自定义类需要继承Exception * @author lsw */ pu ...

  7. Net core学习系列(一)——Net Core介绍

    一.什么是Net Core .NET Core是适用于 windows.linux 和 macos 操作系统的免费.开源托管的计算机软件框架,是微软开发的第一个官方版本,具有跨平台 (Windows. ...

  8. Alpha2

    队名:福大帮 组长博客链接:https://www.cnblogs.com/mhq-mhq/p/11885037.html 作业博客 :https://edu.cnblogs.com/campus/f ...

  9. SQL优化-如何分析性能瓶颈

    MySQL优化一览图 笔者将优化分为了两大类:软优化和硬优化.软优化一般是操作数据库即可:而硬优化则是操作服务器硬件及参数设置. 1.软优化 1)查询语句优化 首先我们可以用EXPLAIN或DESCR ...

  10. 性能测试分析过程(二)cpu 使用率过高的分析方法

    Linux 系统下 cpu 使用率过高的分析方法 1.通过 top 命令可以很明显查看出哪个进程耗cpu比较高 2. ps -mp 25147-o THREAD,tid,time\top -Hp pi ...