共计 3277 个字符,预计需要花费 9 分钟才能阅读完成。
大家好,我是良许。
随着疫情的安稳,最近全国各地都陆续放开了。但很可怜,我的几个号主敌人不小心中招了,成了「阳过」。
良许在此揭示各位朋友,放开不等于躺平,该做的防护一个都不能少。尽管当初病毒没有刚暴发时的可怕,但也绝不是大号的感冒。依据身边的阳大侠反馈,一旦中招那是相当不难受的,千万不要以身试毒。
好了,回归正题。最近在录制一套 STM32 的课程,导致公众号的原创变少了,跟各位朋友说声道歉哈。从当初开始,我也在公众号连更一些 STM32 相干的内容,毕竟俺是嵌入式开发工程师哦(不是你们认为的运维哈)~
学习嵌入式,最经典的第一个试验就是点亮一颗 LED 灯。别小看这个试验,从我辅导的学员来看,不少初学者连这么简略的案例都做不进去。
高手都是从菜鸟过去的,成长须要过程嘛。前两天我在抖音上发了个视频——挑战 20 秒点亮一颗 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 的第一步。千万不要过于自卑,感觉这个太简略,而后就不本人入手操作。
很多小伙伴学习编程,都是感觉这个简略,而后不本人入手,后果学了一段时间后,忽然发现,貌似本人啥也没学会~
所以,入手才是硬道理,千万不要自卑,自觉自信!!