ARM点灯实验-C语言实现

目录

  • led.h
  • led.h
  • main.c

led.h

#ifndef __LED_H__
#define __LED_H__

//RCC控制器将对应组的控制器设置使能【RCC控制器地址】
//通过此来确定是E组还是F组的使能
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)

//GPIOx组内部寄存器的结构体封装
//各寄存器地址连续,结构体地址也连续
typedef struct{
	volatile unsigned int MODER;
	volatile unsigned int OTYPER;
	volatile unsigned int OSPEEDER;
	volatile unsigned int PUPDR;
	volatile unsigned int IDR;
	volatile unsigned int ODR;
}gpio_t;

//GPIO组的宏定义【组号的封装】
//结构体的定义,相当于实例化对象,每个结构体的初始地址不同
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)


//封装模式的寄存器
typedef enum{
	INPUT,
	OUTPUT,
	ALT,
	ANALOG
}gpio_moder_t;
//封装输出类型寄存器
typedef enum{
	PUSH_PULL,
	OPEN_DRAIN
}gpio_type_t;
//输出封装速率寄存器
typedef enum{
	LOW,
	MEDIUM,
	HIGHT,
	HIGHTER
}gpio_speeder_t;
//封装是否上下拉电阻寄存器
typedef enum{
	NO,
	PULL_UP,
	PULL_DOWN,
	RESERVED
}gpio_puper_t;

//封装输出高低电平寄存器【正好是写的值】
typedef enum{
	GPIO_RESET_T,
	GPIO_SET_T
}gpio_status_t;

//使用结构体将寄存器放在一起
typedef struct{
	gpio_moder_t moder;    //封装的模式寄存器
	gpio_type_t typer;     //输出类型寄存器
	gpio_speeder_t speeder;    //输出速率寄存器
	gpio_puper_t puper;     //是否上下拉电阻寄存器
}gpio_init_t;

//引脚封装
#define GPIO_PIN_0 0
#define GPIO_PIN_8 8
#define GPIO_PIN_10 10


//初始化函数(GPIO组号,初始化值,引脚编号)
void hal_gpio_init(gpio_t*gpiox, gpio_init_t* init, unsigned int pin_t);

//操作GPIO的接口写函数(GPIO组号,写的值,引脚编号)
void hal_gpio_write(gpio_t* gpiox,gpio_status_t status,unsigned int pin_t);

#endif

led.h

#include "led.h"

void hal_gpio_init(gpio_t*gpiox, gpio_init_t* init, unsigned int pin_t)
{
	//确定是E组还是F组的寄存器使能
	if(gpiox == GPIOE)
	{
		RCC_AHB4_ENSETR |= (0x1 << 4);  //设置GPIOE组的使能
	}
	else if(gpiox == GPIOF)
	{
		RCC_AHB4_ENSETR |= (0x1 << 5);  //设置GPIOF组的使能
	}

	//将MODER设置为输出模式,21,20设置为01
	gpiox->MODER &= ~(0x3 << (pin_t*2));  //先清零
	gpiox->MODER |= (init->moder << (pin_t*2));   //再置1
	//设置输出类型,设置为推挽输出模式
	gpiox->OTYPER &= ~(0x1 << pin_t);
	gpiox->OTYPER |= (init->typer << pin_t);
	//设置输出速率
	gpiox->OSPEEDER &= ~(0x3 << (pin_t*2));
	gpiox->OSPEEDER |= (init->speeder << (pin_t*2));
	//PUPDR寄存器
	gpiox->PUPDR &= ~(0x3 << (pin_t*2));
	gpiox->PUPDR |= (init->puper << (pin_t*2));

}

void hal_gpio_write(gpio_t* gpiox,gpio_status_t status,unsigned int pin_t)
{
	gpiox->ODR &= ~(0x1 << pin_t);
	gpiox->ODR |= (status << pin_t);
}

main.c

#include "led.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}

int main()
{
	//led1灯初始参数赋值
	gpio_init_t led1_init = {OUTPUT, PUSH_PULL, LOW, NO};
	//对相应的寄存器初始化
	hal_gpio_init(GPIOE, &led1_init, GPIO_PIN_10);

	//led2灯初始参数赋值
	gpio_init_t led2_init = {OUTPUT, PUSH_PULL, LOW, NO};
	//对相应的寄存器初始化
	hal_gpio_init(GPIOF, &led2_init, GPIO_PIN_10);

	//led3灯初始参数赋值
	gpio_init_t led3_init = {OUTPUT, PUSH_PULL, LOW, NO};
	//对相应的寄存器初始化
	hal_gpio_init(GPIOE, &led3_init, GPIO_PIN_8);

	//循环灯的亮灭
	while(1)
	{
		hal_gpio_write(GPIOE, GPIO_SET_T, GPIO_PIN_10);
		delay_ms(500);
		hal_gpio_write(GPIOE, GPIO_RESET_T, GPIO_PIN_10);
		delay_ms(500);

		hal_gpio_write(GPIOF, GPIO_SET_T, GPIO_PIN_10);
		delay_ms(500);
		hal_gpio_write(GPIOF, GPIO_RESET_T, GPIO_PIN_10);
		delay_ms(500);

		hal_gpio_write(GPIOE, GPIO_SET_T, GPIO_PIN_8);
		delay_ms(500);
		hal_gpio_write(GPIOE, GPIO_RESET_T, GPIO_PIN_8);
		delay_ms(500);
	}

	return 0;
}

你可能感兴趣的:(c语言,单片机,stm32)