STM32学习笔记——结构体

寄存器结构体定义

头文件

当我们完成了第一个试验后,或许会发现在头文件的部分,如果我们只用到一个端口,定义的量还尚可,但如果当我们有多个端口需要定义时,那我们就需要重复上面的所有定义再改去端口名,这样会比较麻烦且程序看着过于冗余,因此,我们可以用到结构体。

结构体的一般表达式为:

struct
{
	成员表名;
}变量表名;

结构体在我的理解当中就类似于一个数组,与数组不同的是,结构体中的元素可以是我们自定义的不同类型的变量,更确切地来说,结构体就像是个大集合,这个集合中能够包含我们想要的任何元素。

因此,按此思路,我们就能将I/O口所有的寄存器用结构体包含起来,如下所示:

typedef struct
{
	unsigned int MODER;
	unsigned int OTYPER;
	unsigned int OSPEEDER;
	unsigned int PUPDR;
	unsigned int IDR;
	unsigned int ODR;
	unsigned short BSRRL; 
	unsigned short BSRRH;
	unsigned int LCKR;
	unsigned int AFRL;
	unsigned int AFRH;
}GPIO_TypeDef;

这段代码包含了两步操作:

  1. 定义了一个结构体,其中包含了所有的寄存器名。
  2. 将本结构体去一个新的变量名为GPIO_TypeDef。(变量名可任取,不要与关键字重就行)

这样,结构体就定义完成了。但光有结构体还不够我们还需要将其对应到相应的地址。由之前可得GPIOH的首地址为0x40021C00,因此我们需要一条强制类型转换语句将这个结构体指向对应的地址

#define GPIOH ((GPIO_TypeDef*)0x40021C00)

这句语句就将GPIO_TypeDef这个结构体指向了GPIOH的基地址并将其定义给GPIOH端口,结构体中的各个元素就按照其顺序以及字长逐次排列。按此方法,如果我们以后用到其他的端口,我们只需要更改最后指针指向的基地址就行避免了重复定义。至此我们就完成了头文件的编写接下来就是主程序。

main.c

依旧是闪灯程序,但不同的是,一般我们读取一个结构体的内容时,我们只需要使用变量名.成员名即可,但当我们用一个指针变量去指向结构体成员时,我们就需要用到指向运算符,如下所示:

->

具体代码如下:

GPIOH->MODER &= ~(3<<(2*10));
GPIOH->MODER |= (1<<(2*10)); 
GPIOH->ODR |=(1<<10);
  1. 首先将我们需要操纵的位清零。(为了防止寄存器原有的数值的干扰,最好清空一下)
  2. 将其写入01为输出模式。
  3. 因为是共阳极链接,所以全部置一使其关闭(虽然调试的时候依旧会亮一下)

到此为止,输出口就已经配置好了,只需要将10号位置零就可以使小灯亮起。不过既然我们已经掌握了如何点亮小灯且这个小灯是个RGB小灯,相当于是红绿蓝三个小灯,那我们是否就能将其改写成三种颜色交替闪烁的效果呢。

由前一次实验可知,小灯的3个引脚分别为:

  1. PH10 红色
  2. PH11 绿色
  3. PH12 蓝色

因此我们只需要配置完引脚就能使其闪烁,但我们需要注意的是,当我们点亮后一定记得将其关闭,否则这几种颜色就会混杂在一起,达不到预期效果。具体代码如下所示:

void delay(unsigned int in)
{
	for(;in!=0;in--);
}
int main(void)
{
	RCC |= (1<<7);                    
	GPIOH->MODER &= ~(3<<(2*10));       
	GPIOH->MODER |= (1<<(2*10));       
	GPIOH->ODR |=(1<<10);
	
	GPIOH->MODER &= ~(3<<(2*11));
	GPIOH->MODER |= (1<<(2*11));
	GPIOH->ODR |=(1<<11);
	
	GPIOH->MODER &= ~(3<<(2*12));
	GPIOH->MODER |= (1<<(2*12));
	GPIOH->ODR |=(1<<12);

	GPIOH->ODR &=~(1<<10);            
	delay(0xefffff);
	GPIOH->ODR |=(1<<10);
	delay(0xefffff);
	
	while(1)
	{
		GPIOH->ODR &=~(1<<10);
		delay(0xeffff);
		GPIOH->ODR |= (1<<10);
		GPIOH->ODR &=~(1<<11);
		delay(0xeffff);
		GPIOH->ODR |= (1<<11);
		GPIOH->ODR &=~(1<<12);
		delay(0xeffff);
		GPIOH->ODR |= (1<<12);
	}	
}

void SystemInit(void)      
{
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值