> 技术文档 > STM32使用寄存器开发实现点灯_stm32寄存器开发手册

STM32使用寄存器开发实现点灯_stm32寄存器开发手册


一 STM32种GPIO外设相关的寄存器

中文手册---通用IO---GPIO寄存器:

中文手册187页:

1.端口模式寄存器

引脚编号:0~15 引脚对应的比特位 :位2y : 2y +1 (一个引脚会占两个比特位)

eg:要设置GPIO引脚的第5个引脚的端口模式为 输出模式(01) 所以第5个引脚对应的比特位为 : 10和11 所以将第10位比特位设置为0,将第11位比特位设置为1(因为是从右往左数)

2.输出类型寄存器

3.输出速度寄存器

速度越快,功耗越高,信号越容易被干扰

4.上下拉寄存器

5.输出数据寄存器

6.输入数据寄存器

输入模式下的引脚的输入数据只能只读,不能设置 通过读取引脚的数据数据来判断是高电平还是低电平:

//循环读取PA5状态 while (1) { uint32_t temp = GPIOA_IDR & (1 << 5); // 提取第5位 if (temp != 0) { state = 1; // 高电平 } else { state = 0; // 低电平 } }

二 寄存器实际地址公式

寄存器实际地址公式:

寄存器实际地址 = 寄存器起始地址 + 对应寄存器的偏移地址

eg:端口模式寄存器的实际地址 = 端口模式寄存器的起始地址 + 它的偏移地址 #define GPIOF_MODER *((volatile unsigned int *) ( 0x40021400 + 0x00 )) (1)因为( 0x40021400 + 0x00 )只是地址的值,需要强转再解引用*,才是我们需要的地址 (2)并且加上volatile关键字,避免被优化

1.寄存器起始地址

中文手册P52

2.寄存器偏移地址

(1)RCC

从设备树图中的可以看出GPIO引脚都是挂在AHB1总线上:

所以RCC时钟的地址为:

RCC时钟寄存器的起始地址 :0x40023800 RCC时钟寄存器的偏移地址:RCC_AHB1ENR 0x30

(2)GPIO

中文参考手册中的---通用IO章节----GPIO寄存器

eg:工作模式的寄存器

偏移地址为 0x00

RCC时钟寄存器的起始地址 :0x40023800 RCC时钟寄存器的偏移地址:RCC_AHB1ENR 0x30 GPIO寄存器起始地址: 0x40021400 GPIO工作模式偏移地址: 0x00 GPIO输出类型偏移地址: 0x04 GPIO输出速度偏移地址: 0x08 GPIO上下拉模式偏移地址:0x0C GPIO输出电平偏移地址: 0x14 计算后的实际寄存器地址: 使能RCC时钟的寄存器实际地址: 0x40023800+0x30 GPIO工作模式寄存器的实际地址: 0x40021400+0x00 GPIO输出类型寄存器的实际地址: 0x40021400+0x04 GPIO输出速度寄存器的实际地址: 0x40021400+0x08 GPIO上下拉模式寄存器的实际地址: 0x40021400+0x00 GPIO输出电平寄存器的实际地址: 0x40021400+0x14

三 LED灯的工作原理

1.电路原理图:

芯片要给LED低电平,它才会亮

2.对应的GPIO引脚

D1-----LED0---------PF9

D2-----LED1---------PF10

D3-----FSMC D10-----PE13

D4-----FSMC D11-----PE14

四 点亮LED灯需要设置的模式

根据LED的工作原理,需要得到低电平,所以需要设置GPIO引脚:

设置GPIO引脚:

1.端口模式:输出模式

2.输出类型:推挽模式(因为开漏模式只能被动输出低电平,推挽模式可以输出高低电平)

3.输出速度:低速或高速

4.上下拉电阻:不加(因为是推挽模式)

5.输出数据:低电平

五 设置功能时进行的位操作

1.因为修改某个比特位的值不能印象别的比特位的值,所以用运算符 位或 | =

进行位移设置引脚功能

因为可以由下面看出,不管原来是0还是1,位或 |= 上1后都能保证结果为1

2.进行位移之前必须清空引脚 用 位与 &= ,再取反~

eg:想要向PF9的18 19比特位进行位操作的话,应该先将这两位清0,这样才能达到效果 而这两个比特位转换为二进制就是0011,再转换为十六进制就是0x03 所以例如:清空PF9的18和19比特位的话就是: GPIOF_MODER &= ~( 0x03 <0011----->0x03 所以清空18比特位就可以一起清空19

六 步骤

总步骤:

1.宏定义GPIO的RCC时钟和需要配置的GPIO功能的寄存器

2.使能GPIO的RCC时钟

3.设置GPIO引脚的参数:

        (1)设置端口模式GPIOF_MODER:输出模式

        (2)设置输出类型GPIOF_OTYPE:推挽输出

        (3)设置输出速度GPIOF_SPEED:低速或中速

        (4)设置上下拉电阻GPIOF_PUPD:浮空模式(无上下拉电阻)

        (5)设置输出电平GPIOF_ODR:低电平

详细步骤:

1.宏定义GPIO的RCC时钟和需要配置的GPIO功能的寄存器

因为根据公式算出来的只是寄存器地址的值,而我们要用的是这个地址,所以要进行强转 并加上volatile关键字:防止被优化 #define RCC_AHB1EN *( (volatile unsigned int *)(0x40023800+0x30) ) //RCC使能时钟 #define GPIOF_MODER *( (volatile unsigned int *)(0x40021400+0x00) ) //端口模式 #define GPIOF_OTYPE *( (volatile unsigned int *)(0x40021400+0x00) ) //输出类型 #define GPIOF_SPEED *( (volatile unsigned int *)(0x40021400+0x00) ) //输出速度 #define GPIOF_PUPD *( (volatile unsigned int *)(0x40021400+0x00) ) //上下拉模式 #define GPIOF_ODR *( (volatile unsigned int *)(0x40021400+0x00) ) //输出电平

2.使能GPIO的RCC时钟

因为它是一个比特位,不管原来是0还是1,位或 |= 上1后 都变成1,所以不需要清空

RCC_AHB1EN |= (1<<5); //使能GPIOF的设备时钟

3.设置GPIO引脚的参数:

(1)设置端口模式GPIOF_MODER:输出类型

根据手册,PF9引脚对应的比特位是18和19,所以要设置这两个比特位才能设置对应的端口模式

我们需要设置为输出模式,所以将18比特位置1(输出模式是置1)左移18位,然后再位或

GPIOF_MODER &= ~(0x03<<18); //先清空引脚 GPIOF_MODER |= (1<<18); //设置PF9工作模式为 输出模式

(2)设置输出类型GPIOF_OTYPE:推挽输出

因为推挽模式是置0,清空了之后那两个比特位就已经是0了,所以不用再置0了

GPIOF_OTYPE &= ~(1<<9); //设置PF9输出类型为 推挽模式

(3)设置输出速度GPIOF_SPEED:低速或中速

点亮LED灯只需要低速或者中速就可以了,不然速度越高越不稳定,我们可以设置为50HZ

50hz是将18和19比特位设置为10,所以是将19位(从右往左数)置1(左移19位)

GPIOF_SPEED &= ~(0x03<<18); //先清空 GPIOF_SPEED |= (1<<19); //设置输出速度为 50MHz

(4)设置上下拉电阻GPIOF_PUPD:浮空模式(无上下拉电阻)

因为浮空模式是置0,清空了之后那两个比特位就已经是0了,所以不用再置0了

GPIOF_PUPD &= ~(0x03<<18); //设置PF9上下拉模式为 浮空电路

(5)设置输出电平GPIOF_ODR:低电平

因为低电平是置0,清空了之后那两个比特位就已经是0了,所以不用再置0了

GPIOF_ODR &= ~(1<<9); //清空就等于置0

七 完整代码示例

#include /*------------------------------------------------------------ 端口模式寄存器的实际地址 = 端口模式寄存器的起始地址 + 它的偏移地址对应引脚:D1-----LED0---------PF9D2-----LED1---------PF10D3-----FSMC D10-----PE13D4-----FSMC D11-----PE14总线:GPIO---AHB1*/ //1.宏定义GPIO的RCC时钟和需要配置的GPIO功能的寄存器#define RCC_AHB1EN *( (volatile unsigned int *)(0x40023800+0x30) ) //RCC使能时钟#define GPIOF_MODER *( (volatile unsigned int *)(0x40021400+0x00) ) //端口模式#define GPIOF_OTYPE *( (volatile unsigned int *)(0x40021400+0x04) ) //输出类型#define GPIOF_SPEED *( (volatile unsigned int *)(0x40021400+0x08) ) //输出速度#define GPIOF_PUPD *( (volatile unsigned int *)(0x40021400+0x0C) ) //上下拉模式#define GPIOF_ODR *( (volatile unsigned int *)(0x40021400+0x14) ) //输出电平 int main(){ //2.使能GPIO的RCC时钟 RCC_AHB1EN |= (1<<5); //3.设置GPIO引脚的参数: //(1)设置端口模式GPIOF_MODER:输出模式 GPIOF_MODER &= ~(0x03<<18); //先清空引脚 GPIOF_MODER |= (1<<18);  //(2)设置输出类型GPIOF_OTYPE:推挽输出 GPIOF_OTYPE &= ~(1<<9);  //(3)设置上下拉电阻GPIOF_PUPD:浮空模式(无上下拉电阻) GPIOF_PUPD &= ~(0x03<<18);  //(4)设置输出速度GPIOF_SPEED:50MHz GPIOF_SPEED &= ~(0x03<<18); //先清空 GPIOF_SPEED |= (1<<19); //(5)设置输出电平GPIOF_ODR:低电平 GPIOF_ODR &= ~(1<<9); //清空就等于置0 while(1) {  } }