1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近小编也是在学习 STM32F1 系列,因为前一段时间学过 51 ,所以这几天总结了一下从 51 过度到 STM32 经验与心得,现在与大家分享分享我的心得。
对于引脚的操作和 STM32 与 51 的不同 在 51 中,我们如果想要操作 P0^0 这个引脚,应该有一下几种操作吧。 //这个是小编最开始学的操作IO口。 P0 = 0x01; //直接操作整个P0口,使P00口为高电平,其他为低电平。 P0^0 = 1; //单独操作一个51单片机IO口。 //后来学会了只影响一个IO口,而其他IO口不受影响。 P0 |= 0x01; //这样做可以保证在不影响P0的其他IO的情况下只改变P00口。 //在51单片机中还有一种独有的(这个我查阅了其他资料,并没有发现***it是51单片机独有,但是我所学过的里面只有51能用***it,就暂时说是51单片机独有吧,希望大佬指正。)引脚定义。 ***it IO = P0^0; //将P00口单独定义出来,这样就只会操作到一个IO口了。 以上就是我目前用到过的对于 51 单片机的 IO 口的操作。 不过我一直在思考为什么这样做?为什么 P0^0 这个符号就可以代表的 P0^0 这个引脚,是不是 STM32 也一样? 直到我学习了 STM32 ,我对于它的操作原理有了新的定义。 对于每一个 IO 口其实是有一个地址,要操作这个 IO 口其实是对这个地址的操作,下面我放一段 //由于原程序里面代码太长,我这儿截取几段来集中讲解。 //这儿我截取了51单片机里对P0和P1的定义 sfr P0 = 0x80; //首先我们要知道sfr的意义。 //sfr的定义有点长,在这儿的作用我就长话短说,它是将0x80定义为P0. //这儿就可以发现,曾经我以为的P0就是IO口的引脚其实也是认为定义的,IO口真正的地址其实是0x80,这个也是接下来说STM32要用到的原理。 ***it P00 = P0^0; //对于***it就不生疏了吧,这儿为什么要这样定义呢? //因为我们在上面已经知道了P0的地址,0x80,这个是属于P0口的基地址,什么是基地址?简单来说,就是第一个地址。 //因此我们可以由此推断,P00就是P0的基地址在位移0位,也就是0x80,而P01就是P0位移1位,也就是0X81,所以后面的代码也就由此退出了。 ***it P01 = P0^1; ***it P02 = P0^2; ***it P03 = P0^3; ***it P04 = P0^4; ***it P05 = P0^5; ***it P06 = P0^6; ***it P07 = P0^7; sfr P0M0 = 0x94; sfr P0M1 = 0x93; //下面与上面意义一样 sfr P1 = 0x90; ***it P10 = P1^0; ***it P11 = P1^1; ***it P12 = P1^2; ***it P13 = P1^3; ***it P14 = P1^4; ***it P15 = P1^5; ***it P16 = P1^6; ***it P17 = P1^7; sfr P1M0 = 0x92; sfr P1M1 = 0x91; sfr P1ASF = 0x9D; 对于 51 单片机的 IO 口定义也就分析完了,现在我们开始进入正题,由于上面的知识,对于 STM32 我觉得应该会相当好理解了。 首先,我们要明白, STM32 中可没有 sfr 或者 ***it 或者 bit 这种方便的定义,所以我们只有操作地址来操作 IO 口。 在具体分析之前,有个概念必须了解一下,就是储存器,储存器映射,寄存器和寄存器映射。 储存器 储存器应该很好理解,就是每一个外设(外设就是我们上面说的 P0 , P1 等 IO 口在 STM32 中这些 IO 口被分为了不同的外设。)储存了一个地址,而对于储存器本身是不具有地址信息的,它的地址是由芯片厂商或用户分配,这个过程(给储存器分配地址的过程)就称为储存器映射。 寄存器 我们已经了解到了储存器映射,那么什么是寄存器映射呢?寄存器到底是什么呢? 已经知道了储存器, 那我们可以找到每个内存单元 (每一个外设都是分配了内存单元的,用 51 单片机来讲,就可以这样理解,P00 这一个 IO 口就占用 1 bit 的内存单元) 的地址,然后通过 C 语言指针的操作方式来访问这些单元,但是,每次都通过寻址来访问,不仅不好记忆,还容易出错。所以这个时候我们可以根据每个每个单元 功能 的不同,以功能为名给这些内存单元取一个别名,这个别名就是我们常说的寄存器。取名字这个过程就叫做寄存器映射(和储存器映射相仿。)。 看到这儿,想必对寄存器和储存器的概念已经很清晰了吧,接下来我们就可以深入了解 STM32 了! 上面是我所使用的 STM32F103 系列的寄存器的起始地址。 可能天马行空的这样看图不是很理解,接下来我就用代码与讲解的方式来讲解。 我就用图中的 GPIOB 这个寄存器来作为例子。(因为小编最开始接触 STM32 的时候就是学习的这个寄存器的使用。) 在图中可以看到 GPIOB 的起始地址是 0x40010c00; 所以我们就可以通过控制这个基地址来操作 GPIOB 了。但是,要怎么操作呢? 是像 51 单片机里面一样直接让这个地址等于 0 吗?显然不是! 从 STM32F103 的数据手册的目录,我们可以找到与 GPIO 有关的寄存器。 下面我们随便打开一个寄存器来分析。 有这个图片来分析,首先是偏移地址。什么是偏移地址? 因为对于 GPIO 口不只有 GPIOB ,还有 GPIOA 、 GPIOC 等等每个 GPIO 都有相对应的这种寄存器(图中是 BSRR )寄存器,所以,偏移地址就是 各自 GPIO 口的基地址所偏移后的地址。 //理论如果不好理解,可以参考代码,综合理解。 //由上可知GPIOB的基地址是0x40010c00,所以我们可以使用宏定义。 #define GPIOB_BASE ((unsigned int)0x40010c00) //有了GPIOB的基地址的用定义,我们就可以在这个的基础上定义BSRR寄存器了(重点:使用指针!!!!!!)。 #define GPIOB_BSRR *(unsigned int*)(GPIOB_BASE + 0x10) //现在,我们就把GPIOB的BSRR寄存器的地址定义好了。 接下来我们先分析 BSRR 的作用。 由图我们可以看到, BSRR 一共有 32 位,低 16 位的作用是控制 GPIOB 的 16 个输出端口输出 1(高电平); //就像是51单片机里面的。 P0 = 0x01; 而高 16 位是控制 GPIOB 的 16 个端口清除(就是输出 0(低电平) 。)。 所以,我们可以这样控制 STM32 的 GPIOB 的 1 到 16 口的输出。 //由于在这之上我们使用了宏定义,所以可以直接使用所定义的宏。 GPIOB_BSRR |= (1 << x); //从这儿就可看出,将GPIOB的GPIOB_x这个引脚设置为高电平了。 //具体想要输出/清除哪个引脚,只需要改变x的值就行,若x=0,就是使GPIOB的Pin0口输出高电平。 //当然,也可以直接用地址(不过比较麻烦。)。 *(unsigned int *)0x40010c10 |= (1 << x); //作用与上面相同。 这就完了? 当然不是! 再来看一下这张图: 上面有些 AHP ,APB2,是什么呢? 我们就要结合这张图了。 这儿可以看到 GPIO 、 ADC (这些称之为外设)等等外设是挂载到 APB1、 APB2、AHB上面的,在 STM32 中,要使用这些外设,我们就必须将这些总线的时钟打开(因为默认是关闭,所以需要手动打开。)。 这儿的操作与上面操作 GPIOB 操作一样,找到时钟( RCC )的基地址,再找到寄存器地址,通过操作寄存器的方法来是使APB2 (因为我们操作的是 GPIOB ,而 GPIOB 是挂载在 APB2 上面的)的 RCC 打开。 然后我们的 GPIOB就可以正常使用了。 #define RCC_BASE 0x40021000 //RCC的基地址。 #define RCC_APB2END *(unsigned int*)(RCC_BASE + 0x18) //RCC的使能寄存器地址。 RCC_APB2END |= (1 << 3) //由数据手册来看第三位是使能GPIOB的时钟。 好了,今天的分享就说完了,不过,这儿,只是从原理分析了 STM32 的 IO 的操作,对于固件库还有 HAL 库的讲解以后会分享,使用库可以更加容易的理解和使用 STM32 ! |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9055 浏览 16 评论
4086 浏览 18 评论
1174浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 19:18 , Processed in 1.208391 second(s), Total 78, Slave 59 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号