寄存器&HAL库完成LED流水灯程序
- 一.原理学习
- 二、假设你手中已有 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。
- 1.流水灯原理
- 2.创建新项目
- 1.找到stm32f103cB![在这里插入图片描述](https://img-blog.csdnimg.cn/f35c42691e2e49a8a1c836d4d27f8669.png)
- 2.点击system core,进入SYS,在debug下选择serial wire:
- 3.配置时钟,进入上面的rcc,有两个时钟,一个是hse和lse,我们要用是GPIO接口,而这些接口都在APB2里:
- 4.将hse那里设为Crystal/Ceramic Resonator:
- 5.接下来就是点击相应的引脚设置输出寄存器了,就是output那一项,一共选了三个,是PA4,PB5,PC14:修改为如图所示![在这里插入图片描述](https://img-blog.csdnimg.cn/6e3c1e73e2a641e6b29589d6052c7db9.png)
- 6.点击project manager,配置好自己的路径和项目名,然后IDE那项改为MDK-ARM:
- 7.进入 code generate界面,选择生成初始化.c/.h文件,后面点击generate code,选择open project,然后就到KEIL5了:
- 8.进入 code generate界面,选择生成初始化.c/.h文件,后面点击generate code,选择open project,然后就到KEIL5了:
- 代码
- 使用keil观察波形
一.原理学习
学习和理解STM32F103系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)。
1.寄存器
(1)寄存器的含义
寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。寄存器是中央处理器内的组成部分。寄存器是有限存储容量的高速存储部件,它们可用来暂存指令、数据和位址。
(2)寄存器具有的四个功能
①清除数码:将寄存器里的原有数码清除。
②接收数码:在接收脉冲作用下,将外输入数码存入寄存器中。
③存储数码:在没有新的写入脉冲来之前,寄存器能保存原有数码不变。
④输出数码:在输出脉冲作用下,才通过电路输出数码。
仅具有以上功能的寄存器称为数码寄存器;有的寄存器还具有移位功能,称为移位寄存器。
2.地址映射和寄存器映射原理
通过查看数据手册找到某个寄存器的地址。
手册中没有直接给出所有的寄存器的地址,需要稍加计算。STM32给不同的寄存器分配了不同的地址,有点像划分了片区。在《STM32中文参考手册_V10》的第28页,有不同寄存器的地址范围。
假如我们想读取PB3引脚的电平,需要查询PB3的地址。
第一步
,PB3是在GPIOB端口内,所以要找到GPIOB的基地址
也就是找到GPIOB的地址范围。结论是,所有GPIOB相关的寄存器,地址都在0x4001 0C00到0x4001 0FFF范围内。
第二步
找到端口输入寄存器的地址偏移,找到存储数据的那个屋子,结论是0x4001 0C00+8 = 0x4001 0C08
第三步
找到知道数据的那个人,PB3的数据位于从右往左数第4位。IDR3。
经过这三步查找,我们可以做出以下结论:
PB3的输入数据位于0x4001 0C08这个地址上,这个地址上存放数据的右起第4个位就是PB3引脚对应的高低电平。
直接访问这个地址:
unsigned int *pGPIOB_IDR = (unsigned int *)0x40010C08; unsigned char PB3 = *pGPIOB_IDR & 0x8;//取出从右往左数的第4位
3、GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)
本次实验采用GPIOA、B、C三个端口。该三个端口都属于APB2总线
1.找到时钟使能寄存器映射基地址
2.使能对应端口时钟
//----------------APB2使能时钟寄存器 ---------------------
#define RCC_APB2ENR *((unsigned volatile int*)0x40021018)
RCC_APB2ENR|=1<<2|1<<3|1<<4; //APB2-GPIOA、GPIOB、GPIOC外设时钟使能
输入输出模式和输出速率设置
本次实验采用通用推挽输出模式,最高输出时钟频率2Mhz。分别用到A4、B5、C14三个引脚。其中A4、B5属于端口配置低寄存器偏移地址为0x00,C13属于端口配置高寄存器偏移地址为0x04。
二、假设你手中已有 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED,并搭建了电路,分别GPIOA-5、GPIOB-9、GPIOC-14 这3个引脚上控制LED灯(最高时钟2Mhz),轮流闪烁,间隔时长1秒。
1.流水灯原理
本次实验采用三个灯实现,亮灯状态用1表示,灭灯状态用0表示。
初始状态为0 0 0,
状态一为1 0 0
状态二为0 1 0
状态三为0 0 1
状态三结束后继续进入状态一,一直循环达到流水灯效果。
2.创建新项目
1.找到stm32f103cB
2.点击system core,进入SYS,在debug下选择serial wire:
3.配置时钟,进入上面的rcc,有两个时钟,一个是hse和lse,我们要用是GPIO接口,而这些接口都在APB2里:
接下来观察时钟架构,APB2总线的时钟由hse控制,同时在这个界面得把PLLCLK右边选上:
4.将hse那里设为Crystal/Ceramic Resonator:
5.接下来就是点击相应的引脚设置输出寄存器了,就是output那一项,一共选了三个,是PA4,PB5,PC14:修改为如图所示
6.点击project manager,配置好自己的路径和项目名,然后IDE那项改为MDK-ARM:
7.进入 code generate界面,选择生成初始化.c/.h文件,后面点击generate code,选择open project,然后就到KEIL5了:
8.进入 code generate界面,选择生成初始化.c/.h文件,后面点击generate code,选择open project,然后就到KEIL5了:
代码
打开main.c文件,滑倒主函数那一部分:
(1)将下面代码放入主函数中(替代里面的内容)
SystemClock_Config();//系统时钟初始化
MX_GPIO_Init();//gpio初始化
while (1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//PA4亮灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);//PB9亮灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//PC15熄灯
HAL_Delay(1000);//延时1s
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);//PA4熄灯
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);//PB9熄灯
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//PC15亮灯
HAL_Delay(1000);//延时1s
}
随后生成hex文件。
连接线路
根据设计的程序连接电路:
对于USB转TTL模块和stm32f103c8t6连接:
GND — GND
3v3 — 3v3
TXD — A10
RXD — A9
红——B5
红——C14
黄——A4
烧录文件。笔者使用的是flymcu
记得取消勾选字节区和勾选编程后执行,不然会出现灯不亮的情况(文件没有烧录成功)。
大致效果如上。
使用keil观察波形
先点击,
随后点击
左上角有个setup
,点进去之后按如图点击输入
最后点击跑动一会点×
,关掉就会显示其波形。