使用结构体指针点亮led灯(RGB灯)-学习笔记2

1、使用结构体设定结构体指针GPIO和RCC

2、将GPIO基地址强制转换为结构体类型的首地址,从而进行指针操作。

3、在主函数里直接使用结构体指针操作GPIO相应端口。

4、本次的LED灯集成了红灯、绿灯、蓝灯。

5、本次用到的delay延迟函数随意定的,能达到亮灭即可。


//外设perirhral
#define PERIPH_BASE						0x40000000//外设总基地址
#define APB1_PERIPH_BASE			PERIPH_BASE//外设低速APB1基地址
#define APB2_PERIPH_BASE			(PERIPH_BASE+0x10000)//外设高速APB2基地址
#define AHB_PERIPH_BASE				(PERIPH_BASE+0x20000)//外设超高度AHB基地址

#define RCC_BASE 							(AHB_PERIPH_BASE+0x1000)//外设时钟控制寄存器
#define GPIO_A_BASE 					(APB2_PERIPH_BASE+0x0800)//外设GPIO_X的基地址
#define GPIO_B_BASE 					(APB2_PERIPH_BASE+0x0c00)
#define GPIO_C_BASE 					(APB2_PERIPH_BASE+0x1000)
#define GPIO_D_BASE 					(APB2_PERIPH_BASE+0x1400)
#define GPIO_E_BASE 					(APB2_PERIPH_BASE+0x1800)
#define GPIO_F_BASE 					(APB2_PERIPH_BASE+0x1c00)
#define GPIO_G_BASE 					(APB2_PERIPH_BASE+0x2000)

//寄存器映射,下面使用结构体重新定义了
//#define RCC_APB1ENR						*(unsigned int *)(RCC_BASE+0x1c)//APB1外设时钟使能寄存器
//#define RCC_APB2ENR						*(unsigned int *)(RCC_BASE+0x18)//APB2外设时钟使能寄存器

#define GPIO_A_CRL						*(unsigned int *)(GPIO_A_BASE+0x00)//端口低8口输出配置寄存器
#define GPIO_B_CRL						*(unsigned int *)(GPIO_B_BASE+0x00)
#define GPIO_C_CRL						*(unsigned int *)(GPIO_C_BASE+0x00)
#define GPIO_D_CRL						*(unsigned int *)(GPIO_D_BASE+0x00)
#define GPIO_E_CRL						*(unsigned int *)(GPIO_E_BASE+0x00)
#define GPIO_F_CRL						*(unsigned int *)(GPIO_F_BASE+0x00)
#define GPIO_G_CRL						*(unsigned int *)(GPIO_G_BASE+0x00)

#define GPIO_A_CRH						*(unsigned int *)(GPIO_A_BASE+0x04)//端口高8口输出配置寄存器
#define GPIO_B_CRH						*(unsigned int *)(GPIO_B_BASE+0x04)
#define GPIO_C_CRH						*(unsigned int *)(GPIO_C_BASE+0x04)
#define GPIO_D_CRH						*(unsigned int *)(GPIO_D_BASE+0x04)
#define GPIO_E_CRH						*(unsigned int *)(GPIO_E_BASE+0x04)
#define GPIO_F_CRH						*(unsigned int *)(GPIO_F_BASE+0x04)
#define GPIO_G_CRH						*(unsigned int *)(GPIO_G_BASE+0x04)

#define GPIO_A_ODR						*(unsigned int *)(GPIO_A_BASE+0x0c)//IO端口输出数据寄存器
#define GPIO_B_ODR						*(unsigned int *)(GPIO_B_BASE+0x0c)
#define GPIO_C_ODR						*(unsigned int *)(GPIO_C_BASE+0x0c)
#define GPIO_D_ODR						*(unsigned int *)(GPIO_D_BASE+0x0c)
#define GPIO_E_ODR						*(unsigned int *)(GPIO_E_BASE+0x0c)
#define GPIO_F_ODR						*(unsigned int *)(GPIO_F_BASE+0x0c)
#define GPIO_G_ODR						*(unsigned int *)(GPIO_G_BASE+0x0c)
							
#define GPIO_A_BSRR						*(unsigned int *)(GPIO_A_BASE+0x10)//IO端口输出位清除数据寄存器,只能更改对应gpio端口为1不能更改为0
#define GPIO_B_BSRR						*(unsigned int *)(GPIO_B_BASE+0x10)
#define GPIO_C_BSRR						*(unsigned int *)(GPIO_C_BASE+0x10)
#define GPIO_D_BSRR						*(unsigned int *)(GPIO_D_BASE+0x10)
#define GPIO_E_BSRR						*(unsigned int *)(GPIO_E_BASE+0x10)
#define GPIO_F_BSRR						*(unsigned int *)(GPIO_F_BASE+0x10)
#define GPIO_G_BSRR						*(unsigned int *)(GPIO_G_BASE+0x10)

#define GPIO_A_BRR						*(unsigned int *)(GPIO_A_BASE+0x14)//IO端口输出位清除数据寄存器,只能更改对应gpio端口为0不能更改为1
#define GPIO_B_BRR						*(unsigned int *)(GPIO_B_BASE+0x14)
#define GPIO_C_BRR						*(unsigned int *)(GPIO_C_BASE+0x14)
#define GPIO_D_BRR						*(unsigned int *)(GPIO_D_BASE+0x14)
#define GPIO_E_BRR						*(unsigned int *)(GPIO_E_BASE+0x14)
#define GPIO_F_BRR						*(unsigned int *)(GPIO_F_BASE+0x14)
#define GPIO_G_BRR						*(unsigned int *)(GPIO_G_BASE+0x14)

//结构体优化寄存器映射
typedef unsigned int uint32;//重定义
typedef unsigned short uint16;//重定义

typedef struct
{
	uint32 CRL;//低8位端口配置寄存器
	uint32 CRH;//高8位端口配置寄存器
	uint32 IDR;//端口输入寄存器
	uint32 ODR;//端口输出寄存器
	uint32 BSRR;//端口输出清为1寄存器
	uint32 BRR;//端口输出清为0寄存器
	uint32 LCKR;//锁定端口配置使其不能更改
}GPIO_TYPEDEF;

#define GPIOA  ((GPIO_TYPEDEF *)GPIO_A_BASE)
#define GPIOB  ((GPIO_TYPEDEF *)GPIO_B_BASE)
#define GPIOC  ((GPIO_TYPEDEF *)GPIO_C_BASE)
#define GPIOD  ((GPIO_TYPEDEF *)GPIO_D_BASE)
#define GPIOE  ((GPIO_TYPEDEF *)GPIO_E_BASE)
#define GPIOF  ((GPIO_TYPEDEF *)GPIO_F_BASE)
#define GPIOG  ((GPIO_TYPEDEF *)GPIO_G_BASE)

typedef struct
{
	uint32 RCC_CR;//stm32时钟控制寄存器
	uint32 RCC_CFGR;//stm32时钟配置寄存器
	uint32 RCC_CIR;//stm32时钟中断寄存器
	uint32 RCC_APB2RSTR;//APB2外设时钟复位寄存器
	uint32 RCC_APB1RSTR;//APB1外设时钟复位寄存器
	uint32 RCC_AHBENR;//AHB外设时钟使能寄存器
	uint32 RCC_APB2ENR;//APB2外设时钟使能寄存器
	uint32 RCC_APB1ENR;//APB1外设时钟使能寄存器
	uint32 RCC_BDCR;//备份域控制寄存器
	uint32 RCC_CSR;//控制/状态寄存器
}RCC_TYPEDEF;

#define RCC ((RCC_TYPEDEF *)RCC_BASE)

#include "stm32f10x.h"

void delay(unsigned int z)
{
	unsigned int x;
	unsigned int y;
	for(x=z;x>0;x--)
	for(y=0;y<114;y++);
}

int main(void)
{
	RCC->RCC_APB2ENR |=1<<3;

	//使用结构体封装配置GPIO
	GPIOB->CRL |=1<<(4*0);//配置CRL IO0口为输出
	GPIOB->CRL |=1<<(4*1);//配置CRL IO1口为输出
	GPIOB->ODR &=~(1<<0);//控制ODR寄存器,灯亮
	while(1)
	{
		delay(5000);//延迟一段时间
		GPIOB->ODR |=1<<0;//控制ODR寄存器,灯灭
		delay(5000);//延迟一段时间
		GPIOB->ODR &=~(1<<0);//控制ODR寄存器,灯亮
	}

}
void SystemInit(void)//配置系统时钟函数,芯片内部时钟SHI=8M时钟
{
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您解答这个问题。 假设LED1-3-4-2依次连接在单片机的P0口上,可以通过以下代码实现点LED1-3-4-2的顺序循环: ``` #include <reg52.h> // 导入单片机头文件 sbit LED1 = P0^0; // 定义LED1连接的端口 sbit LED2 = P0^1; // 定义LED2连接的端口 sbit LED3 = P0^2; // 定义LED3连接的端口 sbit LED4 = P0^3; // 定义LED4连接的端口 void main() { unsigned char count = 0; // 定义计数器变量count,初始值为0 while(1) { // 无限循环 count++; // 计数器自增 switch(count) { // 判断计数器的值 case 1: // 当计数器为1时,点LED1 LED1 = 0; LED2 = 1; LED3 = 1; LED4 = 1; break; case 2: // 当计数器为2时,点LED3 LED1 = 1; LED2 = 1; LED3 = 0; LED4 = 1; break; case 3: // 当计数器为3时,点LED4 LED1 = 1; LED2 = 1; LED3 = 1; LED4 = 0; break; case 4: // 当计数器为4时,点LED2 LED1 = 1; LED2 = 0; LED3 = 1; LED4 = 1; break; default: // 当计数器大于4时,将计数器重置为0 count = 0; break; } DelayMs(500); // 延时500毫秒 } } void DelayMs(unsigned int ms) { // 定义延时函数 unsigned int i, j; for(i = 0; i < ms; i++) { for(j = 0; j < 110; j++); } } ``` 以上代码中,使用了一个无限循环,每次循环时计数器count自增。当计数器的值为1时,点LED1;当计数器的值为2时,点LED3;当计数器的值为3时,点LED4;当计数器的值为4时,点LED2。当计数器的值大于4时,将计数器重置为0。同时,为了让LED灭效果更加明显,使用了一个延时函数DelayMs实现了500毫秒的延时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

金丝草

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

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

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

打赏作者

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

抵扣说明:

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

余额充值