STM32的GPIO输出编程
使用寄存器编程进行GPIO输出(PA0口输出为例)
在STM32的GPIO编程中,其本质就是通过操作寄存器来进行I/O口的控制,在STM32中,存在着许多外设且每个外设都有其对应的寄存器。
要想进行寄存器操作,首先需要知道寄存器的地址,在STM32参考手册 2.3 存储器映像 中有个寄存器组起始地址表,此处我截取本文所需的寄存器地址信息,在查阅参考手册得知,GPIOA外设是挂载在APB2总线上的,所以我们需要操作APB2外设时钟的使能寄存器以及GPIOA寄存器,操作寄存器的代码形式:*(uint32_t *)(基址+偏移量) = 位操作数。
配置时钟信号
在STM32中,由于存在许多的外设,操作外设寄存器需要有时钟信号,如果所有外设均默认开启时钟将会造成资源浪费,因此为了能按需控制外设,在操作外设寄存器之前,首先需要进行时钟配置:
查阅手册得知,RCC寄存器基址为 0x40021000,APB2外设时钟使能寄存器偏移地址为 0x18,由于需要开启GPIOA时钟,因此IOPAEN位为1。
方法一:赋值操作,直接对寄存器进行赋值
1 | *(uint32_t *)(0x40021000 + 0x18) = 4; |
方法二:位操作(与或非)
1 | *(uint32_t *)(0x40021000 + 0x18) |= (1<<2); // 将寄存器址与0100相与,将第2位置1,其他位不变 |
GPIO工作模式配置
在配置完成时钟后,还要先配置GPIO的工作模式,如本次采用GPIOA的PA0进行输出,所以查阅端口配置低位寄存器,如下图,在低寄存器的32位中,每4位对应每一个端口,如需使用PA0端口进行推挽输出操作,则CNF0=00,MODE0=11(这里选择50MHz),即十六进制码为 0x3,所以具体操作代码如下:
方法一:赋值操作,直接对寄存器进行赋值
1 | // GPIOA寄存器基址为:0x40010800,端口配置低寄存器基址:0x00 |
方法二:位操作(与或非)
1 | // 如配置PA0口的工作模式,即操作0~3位,二进制值为0011 |
GPIO口输出
在前面进行基本配置后,便可以进行端口输出,对应的端口输出数据寄存器偏移地址为:0xC,基于GPIOA基址:0x40010800,在进行编程时此16位可以十六进制进行赋值,每4位对应十六进制的1位,如:
- 仅将PA0输出高电平,则为0x1;
- 仅将PA0输出低电平,则为0xfffe。
方法一:赋值操作,直接对寄存器进行赋值
1 | *(uint32_t *)(0x40010800 + 0x00) = 0xfffe; // PA0输出低电平 |
方法二:位操作(与或非)
1 | *(uint32_t *)(0x40010800 + 0x00) &= ~(1<<0); // PA0输出低电平 |
完整代码
实现PA0和PA1都输出低电平
直接赋值方法
1 |
|
位操作(与或非)
1 |
|
直接赋值:直接对寄存器进行赋值操作,会改变寄存器所有的位,会影响该寄存器的其他外设。
位操作:对寄存器的值进行与、或、非等操作,能精确到寄存器的对应位进行操作,而不影响其他位。