这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 高校专区 » 坤创E-Geek/天科大新电社 » 大Z带你重玩STM32系列(三)------STM32的通用GPIO口(寄存器法

共11条 1/2 1 2 跳转至

大Z带你重玩STM32系列(三)------STM32的通用GPIO口(寄存器法操作)

高工
2017-03-23 21:45:48     打赏

有朋友问到此系列的更新相关的情况,在此我简要说明一下。本STM32系列教程的更新,是楼主在利用工作之余的私人时间,同时在保证成帖质量的基础上,平均一周更新1-2篇。码字不易,还望各路朋友多多包涵。如有需要交流,可以在下方留言板骚扰我哦~或者直接私信楼主。在此,谢谢各位小伙伴们一直以来的关注和捧场。你所需要的,就是我所追求的。

PS:上周由于开发板的问题,耽误了帖子的更新。于是楼主又去某宝淘了一块开发板。以后所有的程序,均在这块开发板上执行。

-------------------------------------------------------------------------------------------------------

在上一讲中,我们学习了MDK的安装以及破解。这一讲中,我们就开始认认真真的谈一谈,STM32可爱的GPIO口。

本文中,通过对点亮一个LED灯的操作,我们来讲解一下,如何操作GPIO口。就像学各类软件编程的同学们言必谈HelloWorld一样,学单片机的最基本操作就是点灯了。这也是操作一款单片机最最基础的任务。而由于STM32的强大的功能,和芯片复杂的内部结构。对它的GPIO口的操作,相对于51单片机的IO口来说,使用起来要稍微繁琐了那么一点。

本节当中,通过操作寄存器的方式,来操作STM32GPIO口。从而实现点亮LED灯的操作。在下一讲当中,再介绍如何使用库函数来操作GPIO口。

既然是寄存器法点亮LED灯,那么就不得不说到,和点亮LED灯相关的寄存器了。在这之前,我们先上开发板的电路原理图。

由电路原理图我们可以看出,开发板上使用的是一个RGB全彩LED灯,具有红色,绿色,和蓝色三原色。也就是说这个LED灯内部具有三个不同颜色的LED灯,分别为红绿蓝,并分别接在PB5PB0PB1这三个GPIO口上。并且要想使他们发光,这三个GPIO口都要输出低电平才OK

那么,要想使这三个GPIO口能够输出低电平或者是高电平。需要哪些步骤呢?

1)打开这些GPIO口所对应端口的时钟;

2)配置PB5PB0PB1这三个GPIO口的工作模式;

3)令PB5PB0PB1这三个GPIO口输出高低电平以熄灭或点亮对应的LED发光管。

首先对第(1)步进行说明。

经过对原理图的分析,我们可以看出PB5PB0PB1这三个GPIO口是我们需要使用的三个IO口,而他们又都挂在APB2总线上,如图。


因此我们第一步首先要把GPIOB端口的时钟使能。通过查找微控制器参考手册。找到和GPIOB端口相关的寄存器RCC_APB2ENR,如图所示。通过查找我们发现,这个寄存器中的第三位为GPIOB端口的使能位。


再往下查对寄存器RCC_APB2ENR第三位的说明,可以得知,此位为0的时候,端口B的时钟关闭,此位设置成1的时候,表示打开IO端口B的时钟。



那么我们想使用这个端口的三个引脚PB5PB0PB1,就先要把端口B的时钟打开。因此程序如下:


RCC->APB2ENR |= (1<<3); //GPIOB端口时钟使能

其次对第(2)步进行分析。

在使能过GPIOB端口的时钟之后,接下来我们就要配置PB5PB0PB1这三个引脚的工作模式了。由于这三个引脚是用来点亮LED发光管的,因此要设置成推挽输出的模式;同时将其输出的最大频率设置为50MHz

通过查STM32F10x微控制器参考手册我们得知,配置GPIO口工作模式和两个寄存器相关。哪两个呢?一个叫做GPIOx_CRL,另一个叫做GPIOx_CRH。(其中x=ABC....)这两个寄存器中的L表示低,H表示高。因此顾名思义,GPIOx_CRL这个寄存器管的是0~7这底八个端口的配置,而GPIOx_CRH这个寄存器管的是8~15这个高八个端口的配置。

由于PB5PB0PB1这三个引脚都属于GPIOB_CRL寄存器的配置范畴,因此我们只需要对GPIOB_CRL这个寄存器进行相关配置就好。通过查微控制器参考手册,我们发现我们应该分别对GPIOB_CRL0~3位(PB0)、4~7位(PB1)、20~23位(PB5)进行配置。如下图所示。


同时,通过对其对应位的说明,如要将PB5PB0PB1配置成推挽输出,50MHz的模式,应该将其对应的4位写入0011(即0x03)即可。

因此写出程序如下:

//初始化PB0 PB1 PB5为推挽输出,输出频率最大为50MHz

//先清零,再赋值。以下三行为将对应位清零操作

GPIOB->CRL &= ~( 0x0F<< (4*0));

GPIOB->CRL &= ~( 0x0F<< (4*1));

GPIOB->CRL &= ~( 0x0F<< (4*5));

//以下三行分别将PB0 PB1 PB5,设置为推挽输出50MHz

GPIOB->CRL |= (3<<4*0);

GPIOB->CRL |= (3<<4*1);

GPIOB->CRL |= (3<<4*5);

最后对第(3)步进行分析。

通过原理图,我们可以看出。要想使这三个LED灯发光,那么我们需要让PB5PB0PB1这三个引脚输出一个低电平信号。通过查微控制器参考手册,我们可以选择使用端口输出数据寄存器(GPIOx_ODR) (x=A..E)来对这三个引脚输出高低电平进行控制。

对于GPIOB_ODR的用法就是,将对应的位写0,其对应的管脚输出低电平信号。反之,输出高电平信号。因此要想将红绿蓝三个LED灯依次点亮,那么程序如下:

While(1)

{

GPIOB->ODR &= ~(1<<5); //PB5输出低电平,点亮红色LED

Delay(1000000);

GPIOB->ODR |= (1<<5); //PB5输出高电平,熄灭红色LED

GPIOB->ODR &= ~(1<<0); //PB0输出低电平,点亮绿色LED

Delay(1000000);

GPIOB->ODR |= (1<<0); //PB0输出高电平,熄灭绿色LED

GPIOB->ODR &= ~(1<<1); //PB1输出低电平,点亮蓝色LED

Delay(1000000);

GPIOB->ODR |= (1<<1); //PB1输出高电平,熄灭蓝色LED

}

经过以上(1)(2)(3)三个步骤的配置之后,我们将程序编译烧写到开发板中,可以看到如下现象:

视频连接

http://v.youku.com/v_show/id_XMjY1ODYxMDQxMg==.html

----------------我是萌萌哒分割线-----------------------------

好啦,到这儿今天的这一讲就算是顺利结束啦。下一讲当中,我们将要对如何使用库函数法,来操作GPIO口。欢迎大家有问题,下方留言交流哦~


大Z带你重玩STM32系列(四)------STM32的库函数(固件库)







关键词: STM32     ------STM32     寄存器     GPI    

专家
2017-03-24 08:35:34     打赏
2楼
期待中。

专家
2017-03-24 08:47:30     打赏
3楼
直接操作寄存器,不错。

专家
2017-03-26 12:03:08     打赏
4楼
参考和学习,很有用

工程师
2017-04-14 09:00:10     打赏
5楼
什么时候更新下一帖?

专家
2017-04-16 10:05:36     打赏
6楼
我喜欢用寄存器操作,简洁。

菜鸟
2017-07-28 19:02:25     打赏
7楼
对32的知识点巩固了一遍

助工
2017-08-29 22:48:01     打赏
8楼

楼主写的条例很清楚,比自己啃datasheet好多了,自己看总是很头疼,


菜鸟
2017-09-09 17:15:02     打赏
9楼

直接操作寄存器,不错。


工程师
2017-12-26 06:34:41     打赏
10楼

看此文好亲切,已有至少1年没有采用寄存器写的方式了——当然在ARM0时还可以,以后发现寄存器太多说明手册看不过来了,只好转为函数,晦涩难懂——但不需要懂,结果出来就好。谢谢楼主!


共11条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]