STM32笔记2:建库操作之点亮LED

本文详细介绍了如何使用STM32F429开发板控制LED灯的过程,包括GPIO配置、寄存器操作等核心步骤,并解释了相关寄存器的含义及其在代码中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

秉火系列视频之F429开发板————挑战者

侵删

/**新建工程模板
	建库之点亮LED灯
**/

#include "stm32f4xx.h"
//总线
#define PERIPH_BASE				((unsigned int)0x40000000)
#define AHB1PERIPH_BASE			 (PERIPH_BASE+0x00020000)			 
#define GPIOH_BASE				(AHBPERIPH_BASE+0x00001c00)			 


#define GPIOH_MODER				*(unsigned int*)(GPIOH_BASE+0x00)	 
#define GPIOH_ODR				*(unsigned int*)(GPIOH_BASE+0x14)	 
#define RCC_BASE				(AHB1PERIPH_BASE+0X00003800)
#define RCC_AHB1ENR			    *(unsigned int *)(RCC_BASE+0x30)		 

int main(void)
{
	RCCAHB1PERIPH_BASE |= (1<<7);
	 
	GPIOH_MODER &= ~(3<<2*10); 
	GPIOH_MODER |= (1<<2*10); 
	
	//PH10输出低电平
	GPIOH_ODR &= ~(1<<10); 
	while(1);
}

void  SystemInit(void)
{
	
}

下面是我的一堆乱七八糟的解析:

/**新建工程模板
	建库之点亮LED灯
**/

#include "stm32f4xx.h"
//总线
#define PERIPH_BASE				((unsigned int)0x40000000)
#define AHB1PERIPH_BASE			 (PERIPH_BASE+0x00020000)			//AHB1PERIPH_BASE基于总线偏移
#define GPIOH_BASE				(AHBPERIPH_BASE+0x00001c00)			//GPIOH_BASE基于AHB1总线偏移

#define GPIOH_MODER				*(unsigned int*)(GPIOH_BASE+0x00)	//GPIOH_MODER寄存器基于GPIOH基地址的偏移//(unsigned int*)(GPIOH_BASE+0x00)强制指针转换,意义:将该整数转化为一个地址
#define GPIOH_ODR				*(unsigned int*)(GPIOH_BASE+0x14)	//括号外的*号可以放在第16行,17,20行的寄存器前面//*GPIOH_ODR = (unsigned int*)(GPIOH_BASE+0x14)			
//外设基地址 :PERIPH_BASE    ->总线基地址:APB1PERIPH_BASE		->GPIO外设基地址: GPIOA_BASE	 ->寄存器基地址 :GPIOH_ODR 
#define RCC_BASE				(AHB1PERIPH_BASE+0X00003800)
#define RCC_AHB1ENR			    *(unsigned int *)(RCC_BASE+0x30)		//访问一个绝对地址把一个整型数强制转换为一个指针是合法的
																		//*(int *)(0x67a9) = 0xaa55; 或者这样写:
																		//int *ptr;		ptr = (int *)0x67a9;
int main(void)
{
	RCCAHB1PERIPH_BASE |= (1<<7);
	//STM32为了降低功耗,刚开始上电复位时,每个外设始终都是关闭的
	//PH10配置为输出
	//Q1:清零 ?ANS:与零与
	//Q2:置1 ? ANS:与1或	:如果是两位,则操作受原来该位数据影响(假如两位为10,想要变成01,那么单纯的10与01相或不能时结果变为01.),所以为了实现置1操作,先清零,再与1或。
	//总结:
	将寄存器的某一位eg:GPIOH_ODR清零,与该位与0相与GPIOH_ODR &= ~(1<<10),GPIOH_ODR置1,该位与1相或GPIOH_ODR |= (1<<10)。
	将寄存器的某两位eg:GPIOH_MODER变为00时,即清零型,			将该两位与11或之后再取反		
	//								  01时,即置1型,			将该两位清零GPIOH_MODER &= ~(3<<2*10),再与1左移X位的值相或。
	//								  10时,即置1型,			将该两位清零GPIOH_MODER &= ~(3<<2*10),再与1左移X位的值相或。
	//								  11时,即置1型,			将该两位清零GPIOH_MODER &= ~(3<<2*10),再与3左移X位的值相或。
	
	GPIOH_MODER &= ~(3<<2*10);
	GPIOH_MODER |= (1<<2*10);
	
	//PH10输出低电平
	GPIOH_ODR &= ~(1<<10); 
	while(1);
}

void  SystemInit(void)
{
	
}

// 逻辑左移时,最高位丢失,最低位补0;
// 逻辑右移时,最高位补0,最低位丢失;
// 算术左移时,依次左移一位,尾部补0,最高的符号位保持不变。
// 算术右移时,依次右移一位,尾部丢失,符号位右移后,原位置上复制一个符号位;
// 循环左移时,将最高位重新放置最低位
// 循环右移时,将最低位重新放置最高位
// 1010100010101  逻辑左移一位结果为  0101000101010
// 逻辑右移一位结果为 0101010001010
// 算术左移一位结果为 1101000101010
// 算术右移一位结果为 1101010001010
// 循环左移一位结果为 0101000101011
// 循环右移一位结果为 1101010001010

//关于双重指针的问题:

 *(unsigned int*)(0x4002 1C14) = 0xFFFF;
 0x4002 1C14 在我们看来是 GPIOH 端口 ODR 的地址,但是在编译器看来,这只是一
个普通的变量,是一个立即数,要想让编译器也认为是指针,我们得进行强制类型转换,
把它转换成指针,即(unsigned int *)0x4002 1C14,然后再对这个指针进行 * 操作

/* 控制 GPIOH 引脚 10 输出低电平(BSRR 寄存器的 BR10 置 1) */
*(unsigned int *)GPIOH_BSRR |= (0x01<<(16+10));
 
/* 控制 GPIOH 引脚 10 输出高电平(BSRR 寄存器的 BS10 置 1) */
*(unsigned int *)GPIOH_BSRR |= 0x01<<10;

unsigned int temp;
/* 控制 GPIOH 端口所有引脚的电平(读 IDR 寄存器) */
temp = *(unsigned int *)GPIOH_IDR;

使用 (unsigned int *) 把 GPIOH_BSRR 宏的数值强制转换成了地址,然后再用
“*”号做取指针操作,对该地址的赋值,从而实现了写寄存器的功能。同样,读寄存器也
是用取指针操作,把寄存器中的数据取到变量里,从而获取 STM32 外设的状态

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值