文章目录
- 前言
- 一、LED原理图
- 二、使用寄存器点灯的步骤
- 三、如何操作寄存器
- 四、实际操作
- 1.使能GPIO端口
- 2.将引脚设置为输出模式
- 3.设置输出状态
- 五、全部代码
- 总结
前言
本篇文章我们来讲解一下如何使用寄存器点亮一个LED灯,一般对于新人来说都是使用HAL库或者标准库来操作的,但是学习寄存器有助于我们了解更加深入的知识,这加会提高我们对ARM架构的理解。
一、LED原理图
首先第一步我们需要先找到LED的原理图,确定对应的引脚,然后知道是高电平点亮还是低电平点亮。
这里我们用到了三个LED,分别是PB0,PB1,PB5。
二、使用寄存器点灯的步骤
1.使能对应的GPIO
2.引脚模式设置
3.引脚方向设置
4.输出电平设置
这个步骤其实和使用那些库的步骤是一样的,只不过在库中我们总是使用一些结构体来完成这些GPIO的初始化。
三、如何操作寄存器
操作寄存器这里我们使用指针来得到对应寄存器的地址,并对他进行操作。
在ARM中,使用指针操作寄存器时,需要进行读取、改写和写入这三个步骤,以确保正确更新寄存器的特定位,同时不影响其他位。
1.读取寄存器:首先,需要读取寄存器中的当前值。
2.改写寄存器:根据需要改写寄存器的对应位。
3.写入寄存器:修改完成后,将修改好的值再次写入对应的寄存器中。
四、实际操作
这里我们来进行实际的操作,首先我们需要找到STM32的数据手册,在数据手册中我们可以查看到对应寄存器的地址,并且知道如何配置对应的寄存器。
1.使能GPIO端口
在数据手册中的第8章找到时钟使能对应的寄存器:
并且可以从其中得到偏移地址为0x18。
在第三章中找到对应寄存器的基地址:
这样我们就可以得到这个寄存器的完整地址了:0x40021000 + 0x18
在这里可以看到将bit3设置为1可以使能GPIOB端口。
/* 使能GPIOB */
pReg = (unsigned int *)(0x40021000 + 0x18);
*pReg |= (1<<3);
2.将引脚设置为输出模式
在数据手册中找到第九章,GPIO的寄存器,设置MODE可以将GPIO设置为输入或者输出模式。
找到基地址:0x40010C00
偏移地址:
最后得到的地址:0x40010C00 + 0x00
/* 设置GPIOB0为输出引脚 */
pReg = (unsigned int *)(0x40010C00 + 0x00);
*pReg |= (1<<1);
/* 设置GPIOB1为输出引脚 */
pReg1 = (unsigned int *)(0x40010C00 + 0x00);
*pReg1 |= (1<<4);
/* 设置GPIOB5为输出引脚 */
pReg2 = (unsigned int *)(0x40010C00 + 0x00);
*pReg2 |= (1<<20);
3.设置输出状态
偏移地址:0x0C
最终地址:0x40010C00 + 0x0C
这里将需要设置为高电平的引脚,设置寄存器对应的位为1即可。
五、全部代码
main.c
void delay(int d)
{
while(d--);
}
int main()
{
unsigned int *pReg;
unsigned int *pReg1;
unsigned int *pReg2;
/* 使能GPIOB */
pReg = (unsigned int *)(0x40021000 + 0x18);
*pReg |= (1<<3);
/* 设置GPIOB0为输出引脚 */
pReg = (unsigned int *)(0x40010C00 + 0x00);
*pReg |= (1<<1);
/* 设置GPIOB1为输出引脚 */
pReg1 = (unsigned int *)(0x40010C00 + 0x00);
*pReg1 |= (1<<4);
/* 设置GPIOB5为输出引脚 */
pReg2 = (unsigned int *)(0x40010C00 + 0x00);
*pReg2 |= (1<<20);
pReg = (unsigned int *)(0x40010C00 + 0x0C);
pReg1 = (unsigned int *)(0x40010C00 + 0x0C);
pReg2 = (unsigned int *)(0x40010C00 + 0x0C);
while (1)
{
/* 设置GPIOB0输出1 */
*pReg |= (1<<0);
delay(500000);
/* 设置GPIOB0输出0 */
*pReg &= ~(1<<0);
delay(500000);
/* 设置GPIOB1输出1 */
*pReg1 |= (1<<1);
delay(500000);
/* 设置GPIOB1输出0 */
*pReg1 &= ~(1<<1);
delay(500000);
/* 设置GPIOB5输出1 */
*pReg2 |= (1<<5);
delay(500000);
/* 设置GPIOB5输出0 */
*pReg2 &= ~(1<<5);
delay(500000);
}
return 0;
}
start.s启动文件:
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD 0
DCD Reset_Handler ; Reset Handler
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT main
LDR SP, =(0x20000000+0x10000)
BL main
ENDP
END
这个启动文件的内容我们后续再来讲解。
总结
本篇文章就讲解到这里,希望大家能够多加练习,学习寄存器的编程对深入了解ARM架构是有好处的。