点亮LED灯——基于STM32MP157A

本实验仅点亮LED1

一:分析芯片手册:

        LED灯原理

 

        1)首先确定LED1引脚

        

 

 由此可知,LED1对应的引脚为PE10

2)分析引脚寄存器(GPIOE)所在总线

 查手册可知,其为AHB4总线

3)分析RCC寄存器章节

找到RCC章节对应的AHB4总线使能部分

设置GPIOE时钟使能

 易得,GPIOE使能即为把寄存器第四位置 1 :RCC_MP_AHB4ENSETR[4] = 1

4)分析GPIO章节

        点亮LED灯,我们需要把PE10引脚设置为:输出模式、推挽输出模式、低速模式、引脚禁止上下拉

       

1.GPIO_MODER寄存器,设置为输出模式        

 即,把GPIOE_MODER寄存器21、20位置为‘01’ :GPOIE_MODER[21:20] = 01

       

2.GPIOE_OTYPER寄存器,设置推挽输出模式        

 即:GPIOE_OTYPER[10] = 0

     

  3.GPIOE_OSPEEDR寄存器,设置引脚为低速模式        

 即:GPIOE_OSPEEDR[21:20] = 00

       

 4.GPIOE_PUPDR寄存器,设置禁止上下拉         

 即:GPIOE_PUPDR[21:20] = 00

至此,引脚模式设置完毕

5.GPIOE_ODR寄存器,设置灯的亮灭,1为亮,0为灭

 二:代码实现

头文件:gpio.h

因为是第一次实现(虽然对我来说不是第一次了),所以模拟没有对应头文件的情况,由我自己封装GPIO、RCC寄存器的宏定义以及结构体

首先要确定的是,这几个寄存器的地址:

查阅芯片手册

RCC:

RCC_AHB4_ENSETR地址为 0x50000A28 (根据芯片手册知,地址偏移为A28,起始地址为0x50000000)(这个具体参看前面的RCC章节分析,那个Address offset,就是地址的偏移量)

直接进行宏定义

//1.RCC寄存器封装,用宏定义进行封装
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)

GPIO:

由芯片手册可知,AHB4总线的GPIOE的起始地址为:0x50006000,每个功能寄存器(这个具体参看前面的GPIO章节分析,那个Address offset,就是地址的偏移量)的地址偏移量为4,所以,可以把功能寄存器封装为一个结构体,定义为unsigned int类型,要注意,虽然GPIOx_IDR我们并没有使用到,但是因为它在PUPDR和ODR之间,所以要在结构体内加上

//2.GPIO寄存器进行封装,用结构体
typedef struct 
{
	volatile unsigned int MODER; 	//00  ---->地址偏移量
	volatile unsigned int OTYPER;  	//04
	volatile unsigned int OSPEEDR;  //08
	volatile unsigned int PUPDR; 	//0c
	volatile unsigned int IDR; 		//10
	volatile unsigned int ODR; 		//14
}gpio_t;

再将GPIOE宏定义为 gpio_t * 类型的变量,起始地址设定为0x50006000,这样一来,就可以用结构体指针调用的方式来使用

#define  GPIOE  ((gpio_t*)0x50006000)

 最后是三个函数:初始化、开灯、关灯

//3.LED1灯初始化
void LED1_init();

//4.LED1灯点亮
void LED_ON();

//5.LED1灯熄灭
void LED_OFF();

功能函数文件:gpio.c

把分析芯片手册的到的结果具象化

//1..LED1灯初始化PE10

void LED1_init()
{
	//0.设置GPIOE时钟使能
	RCC_AHB4_ENSETR |= (1 << 4);

	//1.设置PE10引脚为输出模式,01
	GPIOE->MODER &= ~(0x3 << 20);  //把21、20位先全部置0,就可以用 |= 直接赋值
	GPIOE->MODER |= (0x1 << 20);

	//2.设置PE10引脚为推挽输出,0
	GPIOE->OTYPER &= ~(0x1 << 10);

	//3.设置PE10引脚为低速模式,00
	GPIOE->OSPEEDR &= ~(0x3 << 20);
	
	//4.设置PE10引脚禁止上下拉,00
	GPIOE->PUPDR &= ~(0x3 << 20);

}

开灯关灯:

//2..LED1点亮
void LED_ON()
{
	//1.设置PE10引脚输出高电平
	GPIOE->ODR |= (1 << 10);
}

//3..LED1熄灭
void LED_OFF()
{
	//1.设置PE10引脚输出低电平
	GPIOE->ODR &= ~(1 << 10);
}

在主函数中编写延时函数,即可实现LED灯的闪烁

int main()
{
    LED1_init();
    while(1)
    {
        LED_ON();
        delay_ms(500);   //500毫秒延时,这个就由读者自己写了
        LED_OFF();
        delay_ms(500);
    }
}

附上头文件与功能函数的完整代码

头文件:

#ifndef __GPIO_H__
#define __GPIO_H__

//1.RCC寄存器封装,用宏定义进行封装
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)
//2.GPIO寄存器进行封装,用结构体
typedef struct 
{
	volatile unsigned int MODER; 	//00
	volatile unsigned int OTYPER;  	//04
	volatile unsigned int OSPEEDR;  //08
	volatile unsigned int PUPDR; 	//0c
	volatile unsigned int IDR; 		//10
	volatile unsigned int ODR; 		//14
}gpio_t;
#define  GPIOE  ((gpio_t*)0x50006000)

//3.LED1灯初始化
void LED1_init();

//4.LED1灯点亮
void LED_ON();

//5.LED1灯熄灭
void LED_OFF();
#endif

功能函数:

#include "gpio.h"

//1..LED1灯初始化PE10

void LED1_init()
{
	//0.设置GPIOE时钟使能
	RCC_AHB4_ENSETR |= (1 << 4);

	//1.设置PE10引脚为输出模式,01
	GPIOE->MODER &= ~(0x3 << 20);   //把21、20位先全部置0,就可以用 |= 直接赋值
	GPIOE->MODER |= (0x1 << 20);

	//2.设置PE10引脚为推挽输出,0
	GPIOE->OTYPER &= ~(0x1 << 10);

	//3.设置PE10引脚为低速模式,00
	GPIOE->OSPEEDR &= ~(0x3 << 20);
	
	//4.设置PE10引脚禁止上下拉,00
	GPIOE->PUPDR &= ~(0x3 << 20);

}

//2..LED1点亮
void LED_ON()
{
	//1.设置PE10引脚输出高电平
	GPIOE->ODR |= (1 << 10);
}

//3..LED1熄灭
void LED_OFF()
{
	//1.设置PE10引脚输出低电平
	GPIOE->ODR &= ~(1 << 10);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老K殿下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值