——Dec.7.2020
一、开始的开始
大家好,欢迎来到我的博客。😄 这次是我第一次尝试记录自己学习单片机的过程,同时也是面向想要开始接触单片机的同学们的一个非常基础的教程📖(主要是HAL库的应用)。今后有机会再去研究寄存器(挖坑)
学习的过程并不只是简单的输入,更需要时不时将所学的东西输出出来。这个系列也算是我学习单片机过程的“时不时输出”。对自己学习的过程有一个比较好的总结以及对于一些刚开始接触单片机的同学一些参考。
由于自己小萌新接触单片机至今也才一个月不到,不能称为一个老玩家,可能会时不时出点错误,如果聪明细心的你发现了,可以及时告诉我。大家一起共同进步🔆~
二、单片机以及开发平台
(1)微处理器(单片机)
大家通常讲的单片机(Single-Chip Microcompuer)也叫微处理器,主要采用大规模集成技术将CPU以及一部分外设集成到一颗芯片上,成为具有处理一定数据能力的微型计算系统。简单一点可以看成是一个小小沙盒🗳 ,需要你在里面构建相应设施才能实现特定的功能。具体可以参考百度百科-单片机,这里不多赘述。
(2)Keil还是STM32cubeIDE?
我相信这个是大多数人刚开始学习会遇到的问题,网上教程满天飞,众说纷纭难以选择。如果购买正点原子开发版的同学可能会倾向于跟着视频教程使用keil软件进行单片机开发,而且网上大部分开发人员也采用keil作为开发工具,资源相对来说会比较丰富。
但是这里我选择的是ST公司近几年推行的STM32cubeIDE集成开发平台(前身是STM32cubeMX),这时候就会有小伙伴问我为啥不选择keil呢。原因主要在于STM32cubeIDE有可视化的引脚配置管理和时钟树配置,再加目前ST公司主推的HAL库来替代原本的标准库,学STM32cubeIDE或者说STM32cubeMX都将是一个主流趋势。(说了这么多,然而最初选择它其实是因为STM32cubeIDE支持macOS)
(3)STM32cubeIDE的安装(macOS)
登陆官方网站STM32cubeIDE下载并安装软件,这里因为我用的是macOS,因此选择下载相应的macOS版本。这里还提供了各种平台的相应版本。
安装过程基本一路next,安装完成后就可以打开我们的STM32cubeIDE。注意这里的workplace指的是你的projects所要存放的位置,同一个workplace里面可以有许多个project。最好自行选择一个合适的地址,之后添加和删除文件会方便许多。
提醒:如果确定了workplace,尽量不要改动路径,这会导致工程因为工程路径错误而无法打开。
这里新建一个New_workplace的工作空间,我们点击Launch开始即可开始我们开发之旅⛵️~
(4)STM32cubeIDE的中文以及主题配置
也许有小伙伴和我一样一开始不大习惯于英语的操作界面,这里简单介绍一下中文的配置以及主题选择。
在网上有许多教程,这里选用STM32cubeIDE环境配置安装-汉化-主题设置的教程,相对来说还是比较好的。有需要的同学可以点开了解一下。
创建工程以及配置文件
(1)创建工程
使用开发平台:正点原子STM32F407探索者、STM32cubeIDE。
安装完IDE后,设置好workplace,点开Launch后我们看到一个崭新的界面,点击左上方file->new project
新建工程,会出现一个芯片选择界面。这里我们用的是正点原子的开发版,其芯片型号为F407ZGT6,我们选择该芯片型号,点击next>
(这里可以添加收藏以便将来快速找到该芯片)进入后给自己的工程取个名字就可以finish
了。如果需要更多的设置可以继续点击下一步设置。
等待软件自动生成项目后我们可以看到一个我们刚刚建立的工程:
如果是使用过STM32cubeMX的小伙伴们一定对这个界面很熟悉,这也是我认为STM32cubeIDE比较方便的原因。我们可以查阅相应的外设引脚来很快速的生成配置代码。
下面我们以跑马灯为例简单演示一下。
(2)跑马灯实验引脚配置
时钟树配置(Clock Configuration)
正点原子F407探索者开发板,外部晶振为8MHz,IDE默认是关闭外部时钟(RCC),我们需要在我们的时钟树中打开外部晶振。
我们点开System Core -> RCC
选项,找到High Speed Clock (HSE)
选项,选择我们的外部晶振Crystal/Ceramic Resonator
,选定后我们可以看到PH0、PH1两个引脚激活。
现在我们配置时钟树(如下图所示)
主要配置System Clock Mux以及之前的分频选项,后续的时钟可以根据自己需求调整。
引脚配置(Pinout & Configuration)
这里我们用的是正点原子的F407探索者开发板。通过原理图的原理查询,控制两个LED灯的引脚分别为PF9、PF10,我们找到对应的引脚,选择GPIO_Output,同时我们可以点开旁边的System Core -> GPIO
,我们可以看到刚刚激活的引脚PF9、PF10出现在界面中,我们点击这两个选项进行进一步配置。
这里我们找到引脚的输出配置GPIO Pull-up/Pull-down
输出为Pull-up
上拉输出,输出模式GPIO mode
为Output Push Pull
推挽输出。
User Label
:为用户自定义引脚的名称(方便引脚的管理和调用),这里我们设置为LED_0
和LED_1
。
相应的,我们还可以设置输出的速度Maximum output speed
,这里跑马灯实验对于输出速度不作特别要求因此我们保持默认就好了。
生成配置代码(Generate Code)
我们基本配置好后,就可以点Project -> generate code
生成代码啦!我们可以看到文件结构
注意⚠️:用户的代码必须要写在对应的区域
1 | while(1) |
(3)跑马灯实验代码
基础工作做好了,我们开始编写代码CODE!
-
首先我们需要了解一定的HAL库知识(
不了解也没关系,search一下就可以) -
善于利用搜索,寻找需要的函数:
我们可以通过查询找到**HAL_Delay(uint32_t Delay)**函数原型,其中入口变量Delay为对应ms。例如HAL_Delay(100)表示延迟100ms。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* @brief This function provides minimum delay (in milliseconds) based
* on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals where uwTick
* is incremented.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @param Delay specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while((HAL_GetTick() - tickstart) < wait)
{
}
}然后该实验还需要用到**HAL_GPIO_WritePin()**函数,入口变量依次为寄存器编号,控制的引脚编号,以及修改的状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/**
* @brief Sets or clears the selected data port bit.
*
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between
* the read and the modify access.
*
* @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
* x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
* @param GPIO_Pin specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @param PinState specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if(PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
}
}
现在我们开始编写跑马灯代码:
1 | /* USER CODE BEGIN WHILE */ |
然后点击Build All
进行编译,看到下方提示栏中显示
0 error,0 warming… //表示构建成功,没有问题
然后就可以烧录到单片机上了,这里提供一个基于ST-Link的方法。将ST-Link与电脑连接,在Help中找到ST-Link更新,然后电脑会自动更新,然后点击Run
进行烧录。(如果提示需要安装插件,可以根据提示到官网下载安装即可使用ST-Link调试)等到提示窗口显示,说明烧录成功并且结束了。
Download verified successfully
Debugger connection lost.
Shutting down…
我们就可以观察到单片机上的两个LED灯开始交替闪烁了!⭐️⭐️⭐️
END