大家好,我是良许。
随着疫情的平稳,最近全国各地都陆续放开了。但很不幸,我的几个号主朋友不小心中招了,成了「阳过」。
良许在此提醒各位朋友,放开不等于躺平,该做的防护一个都不能少。虽然现在病毒没有刚爆发时的可怕,但也绝不是大号的感冒。根据身边的阳大侠反馈,一旦中招那是相当不舒服的,千万不要以身试毒。
好了,回归正题。最近在录制一套 stm32 的课程,导致公众号的原创变少了,跟各位朋友说声抱歉哈。从现在开始,我也在公众号连更一些 stm32 相关的内容,毕竟俺是嵌入式开发工程师哦(不是你们以为的运维哈)~
学习嵌入式,最经典的第一个实验就是点亮一颗 led 灯。别小看这个实验,从我辅导的学员来看,不少初学者连这么简单的案例都做不出来。
想要成这一名优秀的点灯大师,第一步就是要学会 stm32 最基础的外设——gpio。
1. 什么是gpio?
1.1 定义
gpio是通用输入输出(general-purpose input/output)端口的简称,简单来说就是stm32可控制的引脚stm32芯片的gpio引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
这是比较正式的说法,是不是听得一愣一愣的?
再简单一点,就是芯片里拉出一堆引脚,这些引脚在我们的控制下可以输出高电平/低电平,或者可以通过这些引脚向芯片输入一些信号,从而实现你们的一些目的。
1.2 命名规则
以 stm32f103c8t6 这颗芯片为例,它的 gpio 口一共有 37 个,如何对它们进行命名呢?总不能叫翠花、二蛋、狗剩吧?
咱有正规的命名规则,那就是组编号+引脚编号。
什么是组编号?那就是 gpioa, gpiob, gpioc, gpiod .. gpiog,一般最多到 gpiog 。
什么是引引脚编号?那就是 0,1,2,3 ... 15。
所以组合起来,就是:
pa0, pa1, pa2 .. pa15
pb0, pb1, pb2 .. pb15
pc0, pc1, pc2 .. pc15
...
但并不是所有的芯片都有 a 到 g 个组,就比如咱这颗芯片就只有 a~d 四组。而且也不是每组都有 15 个引脚,就比如 d 组就只有 0 和 1 两个引脚。
1.3 内部框架
上面这张图来自于官方手册,看起来是不是有点吓人?
吓到你就对了,第一次看到的时候我也吓哭了。但是,作为初学者,可以先不用研究太底层的内容,咱先把灯点起来再说,否则你学会了一堆理论知识,结果到头来连颗灯都点不起来,岂不是本末倒置了?
1.4 推挽输出与开漏输出
咱先看下这两种输出的电路图。
从电路图可以看出,这两种输出有着本质的区别:
推挽输出: 可以真正的输出高电平和低电平
开漏输出: 开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动。
2. 如何点亮一颗 led 灯?
我们先看下 led 灯的接线。
可以看到,led 灯都是一侧通过电阻拉高,另一侧接到 gpio 脚。所以,gpio脚必须拉低,这样才会产生电压,对应的 led 灯才会亮起来。
以 led1 为例,它又接到了哪个引脚上呢?咱看原理图,一定要遵循一个原则:标号一样的导线在物理上是连接在一起的。
很明显,led1 引脚是连接在 pb8 这个 gpio 口的。所以,我们只要编程将 pb8 拉低,就可以实现将 led1 灯点亮。
3. 编程实现点灯
3.1 常用 gpio hal 库函数
对于单片机编程,一般有三种方式:寄存器编程、标准库编程、hal 库编程。目前,hal 库编程方式是 st 公司主推的编程方式,这也是时代的潮流,所以我们主要介绍的还是 hal 库编程。
gpio 常用 hal 库函数有以下这几个:
void hal_gpio_init(gpio_typedef *gpiox, gpio_inittypedef *gpio_init);void hal_gpio_writepin(gpio_typedef *gpiox, uint16_t gpio_pin, gpio_pinstate pinstate);gpio_pinstate hal_gpio_readpin(gpio_typedef *gpiox, uint16_t gpio_pin)void hal_gpio_togglepin(gpio_typedef *gpiox, uint16_t gpio_pin);
hal_gpio_init 这个函数是初使化一个 gpio 引脚的,如果你使用 cubemx 的话,那么初始化的代码将自动生成,你甚至都不需要自己动手写。
hal_gpio_writepin 就是可以将对应的引脚拉高或拉低,我们点灯的时候用的就是这个函数。而它的兄弟 hal_gpio_readpin 就是获取某个引脚的状态(拉高 or 拉低)。
最后的 hal_gpio_togglepin 可以实现引脚电平的翻转,比如原来是高电平,则会被翻转为低电平;原来是低电平,则会被翻转为高电平。
3.2 cubemx 配置
配置debug模式
配置 pb8 引脚
右侧选中 pb8 引脚,然后选择 gpio_output 模式。
在中间栏里,点击对应的 gpio 管脚,然后属性按图中所示设置。特别要注意,咱刚开始要将 pb8 拉高,否则一上电 led1 就亮了。我们要在代码中将它点亮。
配置工程
注意哈,一定不要将工程放在有中文路径的地方,否则将出现异常情况!
都配置完成之后,就可以点击右上角的 generate code 来生成工程了。
3.3 编写代码
到这边,我们的工作已经完成大半了。cubemx 的强大之处,就是它可以通过简单的几次点击,就可以自动生成初始化代码。
比如下面的这段 gpio 口初始化代码,如果自己写的话,至少需要几分钟时间,但它都已经自动帮你写好了,非常方便!
void mx_gpio_init(void){ gpio_inittypedef gpio_initstruct = {0}; /* gpio ports clock enable */ __hal_rcc_gpioa_clk_enable(); __hal_rcc_gpiob_clk_enable(); /*configure gpio pin output level */ hal_gpio_writepin(gpiob, gpio_pin_8, gpio_pin_set); /*configure gpio pin : pb8 */ gpio_initstruct.pin = gpio_pin_8; gpio_initstruct.mode = gpio_mode_output_pp; gpio_initstruct.pull = gpio_nopull; gpio_initstruct.speed = gpio_speed_freq_low; hal_gpio_init(gpiob, &gpio_initstruct);}
接下来,我们就可以在 main 函数的 while 循环里写自己的这么一段代码,就可以实现 led1 隔 1 秒点亮 1 秒的效果了。
一定要注意哈,要把代码放在 user code begin 和 user code end 里,否则你修改了 cubemx 的配置,自动生成的代码会将你写好的代码覆盖掉,那你的代码就白写了!
hal_gpio_writepin(gpiob, gpio_pin_8, gpio_pin_reset);hal_delay(1000);hal_gpio_writepin(gpiob, gpio_pin_8, gpio_pin_set);hal_delay(1000);
点灯操作就到此结束了,后面我还会继续更新 stm32 的其它干货内容,敬请期待哦~
我也建了个嵌入式交流群,专门进行技术交流,而且也会发一发小福利,到时候也会将源码放在群里,想要进群的小伙伴可以扫描下面二维码进群哈:
4. 小结
千里之行,始于足下。点亮 led 灯不难,但这是你学习 stm32 的第一步。千万不要过于自大,觉得这个太简单,然后就不自己动手操作。
很多小伙伴学习编程,都是觉得这个简单,然后不自己动手,结果学了一段时间后,突然发现,貌似自己啥也没学会~
所以,动手才是硬道理,千万不要自大,盲目自信!!
新兴存储器铁电RAM嵌入式应用的优势是什么
AR“小巨人”|亮风台继专精特新“小巨人”后,再获上海市“科技小巨人”
高通可向荣耀供货5G芯片,无需审批
动力电池新蓝海 装备巨头入局叠片领域
华为首款全面屏新机9月22日发布,不是华为Mate10也不是荣耀Note9!而是麦芒6,惊不惊喜意不意外
如何快速成为点灯大师?
自恢复保险丝(PPTC)规避的使用四要素
科里奥利流量计的工作原理及设计
FPC1500频谱分析仪的性能特点及应用范围
苏泊尔静音破壁机锻造心机料理 中西合璧生日趴在家就能开
视放电路的电源供电电路
中国电子报:国产车规级传感器,为何需要“高精度”?
509亿!华为研发中心等项目落地上海青浦!
双机ADSL共享上网方案详解
安森美半导体宣布新的QCS-AX2芯片组系列 已提供样品
使用无人驾驶船部署自主水下航行器的新系统
论SD-WAN对企业服务产生的影响
全集成设计环境下的视频处理系统开发
GTC中国大会 人工智能与英伟达共同构建的盛宴
加特兰Alps-Pro AUTOSAR项目通过ASPICE CL2等级评估