stm32f4点灯

#include "stm32f4xx.h"
#define MY_PERIPH_BASE ((uint32_t)(0x40000000UL))												// 外设基地址
#define MY_AHB1PERIPH_BASE ((uint32_t)(MY_PERIPH_BASE + 0x20000UL))			// AHB1总线基地址
#define MY_RCC_BASE        ((uint32_t)(MY_AHB1PERIPH_BASE + 0x3800UL))  // RCC基地址
#define MY_RCC_AHB1ENR     ((uint32_t *)(MY_RCC_BASE + 0x30UL))       	// AHB1外设时钟使能寄存器

#define MY_GPIOF_BASE      ((uint32_t)(MY_AHB1PERIPH_BASE + 0x1400UL))  // GPIOF基地址


#define MY_GPIOF_MODER     ((uint32_t *)(MY_GPIOF_BASE + 0x00UL))    // GPIOF端口模式寄存器
#define MY_GPIOF_ODR       ((uint32_t *)(MY_GPIOF_BASE + 0x14UL))    // GPIOF输出数据寄存器


int main(void)
{		// AHB1外设时钟使能寄存器
    *MY_RCC_AHB1ENR |= (1 << 5);      // 让第5位置1,其它位不变	
			
		//配置pd9为输出模式
		*MY_GPIOF_MODER &=~(1<<19);
		*MY_GPIOF_MODER |= (1 << 18);    // 让第18位置1,其它位不变
	
		*MY_GPIOF_ODR &=~(1<<9);
		return 0;

}

这段代码是基于 STM32F4 系列单片机的寄存器级底层初始化代码,核心功能是:配置 GPIOF 端口的第 9 号引脚(PF9)为推挽输出模式,并将其电平拉低(输出低电平)9号引脚接了个灯泡其实就是点灯

一、宏定义:地址映射

这部分代码的作用是给STM32F4的特定寄存器地址起一个易记的名字,是寄存器操作的基础。

STM32 的所有外设(如 GPIO、RCC)都被映射到内存的特定地址上,我们可以通过指针直接访问这些地址来控制硬件。

  1. 外设基地址

    #define MY_PERIPH_BASE ((uint32_t)(0x40000000UL))
    
    • 0x40000000UL 是 STM32F4 系列单片机所有外设的起始地址。可以把它想象成一个巨大的仓库,里面存放着所有的硬件设备(GPIO、定时器、串口等)。
    • uint32_tUL 都是为了明确这是一个32位的无符号长整型地址,避免编译时出现类型或溢出问题。
  2. AHB1 总线基地址

    #define MY_AHB1PERIPH_BASE ((uint32_t)(MY_PERIPH_BASE + 0x20000UL))
    
    • STM32 的外设被挂在不同的总线上,其中 AHB1 总线主要挂载高速外设,如 GPIO 端口、RCC 等。
    • 这个宏定义了 AHB1 总线外设的起始地址,它是在外设基地址的基础上偏移了 0x20000
  3. RCC 基地址

    #define MY_RCC_BASE        ((uint32_t)(MY_AHB1PERIPH_BASE + 0x3800UL))
    
    • RCCReset and Clock Control(复位和时钟控制)的缩写。它是整个单片机的“心脏”,负责配置和分发系统时钟。任何外设要想工作,都必须先通过 RCC 为其使能时钟。
    • 这个宏定义了 RCC 外设的基地址。
    • 在这里插入图片描述
  4. RCC AHB1 外设时钟使能寄存器

    #define MY_RCC_AHB1ENR     ((uint32_t *)(MY_RCC_BASE + 0x30UL))
    
    • 这是一个非常关键的寄存器。它的全称是 RCC AHB1 peripheral clock enable register
    • 这个寄存器的每一个 bit 都对应一个挂在 AHB1 总线上的外设。当我们将某个 bit 置为 1 时,就意味着给对应的外设“通电”(使能时钟)。
    • (uint32_t *) 将计算出的地址强制转换为一个指向 32 位整数的指针,这样我们才能通过 * 来读写这个寄存器的值。
      在这里插入图片描述
  5. GPIOF 基地址

    #define MY_GPIOF_BASE      ((uint32_t)(MY_AHB1PERIPH_BASE + 0x1400UL))
    
    • GPIOF 是指 Port F,即 F 组 GPIO 端口。STM32F4 有多个 GPIO 端口(A, B, C, …, K 等),每个端口都有 16 个引脚(Pin 0 ~ Pin 15)。
    • 这个宏定义了 GPIOF 端口控制器的基地址。
  6. GPIOF 模式寄存器

    #define MY_GPIOF_MODER     ((uint32_t *)(MY_GPIOF_BASE + 0x00UL))
    
    • MODERMode Register 的缩写,用于配置每个 GPIO 引脚的工作模式(输入、输出、复用功能等)。
    • 它是一个 32 位寄存器,每两位(bit)控制一个引脚。例如:
      • Pin 0 由 bit 0 和 bit 1 控制。
      • Pin 1 由 bit 2 和 bit 3 控制。
      • Pin 9 由 bit 18 和 bit 19 控制。 (这与我们后面的代码密切相关)
  7. GPIOF 输出数据寄存器

    #define MY_GPIOF_ODR       ((uint32_t *)(MY_GPIOF_BASE + 0x14UL))
    
    • ODROutput Data Register 的缩写,用于控制 GPIO 引脚的输出电平。
    • 它是一个 32 位寄存器,每一位(bit)对应一个引脚。
    • 当引脚被配置为输出模式时,将 ODR 的某一位置 1,对应的引脚就输出高电平(VCC);置 0 则输出低电平(GND)。
    • Pin 9 对应 ODR 的 bit 9。

二、main 函数:核心逻辑

main 函数是程序的入口,所有代码从这里开始执行。

  1. 使能 GPIOF 时钟

    *MY_RCC_AHB1ENR |= (1 << 5);
    
    • 这是操作寄存器的标准写法。MY_RCC_AHB1ENR 是一个指向时钟使能寄存器的指针,* 是解引用操作,代表访问该地址上的值。
    • (1 << 5) 的意思是将数字 1 向左移动 5 位,得到一个只有第 5 位为 1 的二进制数 0b100000
    • |= 是按位或赋值操作。它会将 (1 << 5) 的值与 MY_RCC_AHB1ENR 寄存器的当前值进行“或”运算,然后将结果写回寄存器。
    • 为什么是第 5 位? 根据 STM32F4 的芯片手册,RCC_AHB1ENR 寄存器的第 5 位(Bit 5)是 GPIOFEN,专门用于使能 GPIOF 端口的时钟。
    • 这一步是所有 GPIO 操作的前提! 如果不使能时钟,后续对 GPIOF 寄存器的所有操作都将无效。
  2. 配置 PF9 为输出模式

    *MY_GPIOF_MODER &= ~(1 << 19);
    *MY_GPIOF_MODER |=  (1 << 18);
    
    • 这两行代码共同配置了 GPIOF 的第 9 号引脚(PF9)。
    • 回顾一下,MODER 寄存器中,Pin 9 由 bit 18 和 bit 19 控制。
    • 第一行 *MY_GPIOF_MODER &= ~(1 << 19);
      • (1 << 19) 创建一个只有 bit 19 为 1 的掩码。
      • ~ 是按位取反操作,将这个掩码变成只有 bit 19 为 0,其余都为 1
      • &= 是按位与赋值操作。这个操作可以保证 bit 19 被清零,而不影响其他位的值。这是一种安全的清位方法。
    • 第二行 *MY_GPIOF_MODER |= (1 << 18);
      • (1 << 18) 创建一个只有 bit 18 为 1 的掩码。
      • |= 操作可以保证 bit 18 被置为 1,同样不影响其他位。
    • 最终结果:经过这两步,控制 PF9 的两位(bit 18 和 bit 19)被设置为 01。根据 MODER 寄存器的定义,01 就代表该引脚被配置为 推挽输出模式(General purpose output push-pull)。
  3. 设置 PF9 输出低电平

    *MY_GPIOF_ODR &= ~(1 << 9);
    
    • 现在 PF9 已经是输出模式了,这行代码用来控制它的输出电平。
    • (1 << 9) 对应 ODR 寄存器的 bit 9。
    • &= ~ 操作将 bit 9 清零
    • 因此,GPIOF 的第 9 号引脚(PF9)会输出低电平(0V)。
  4. 程序结束

    return 0;
    
    • 在嵌入式系统中,main 函数通常不会返回。返回 0 在这里只是一个形式,表示程序“正常”执行完毕。在实际的工程项目中,这里通常会是一个无限循环 while(1),让单片机持续运行。

核心功能是:初始化并将 GPIOF 端口的第 9 号引脚(PF9)设置为推挽输出低电平

这样就完成点亮一个灯泡

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值