【前言】
这几天在B站学习了基于stm32的面向对象驱动,我试着用GD32F527进行了实现。在此记录如下:
【基础工程】
我在这篇帖子【GD32F527】创建工程模版-电子产品世界论坛的础之上进行编写。
【LED的端口】
在原理图上,得知开发板有4个LED,高电平点亮。

【面向对象的程序实现】
1、作为面向对象,最好我们使用的是一个结构体指针,通过对这个结构体进行操作。首先创建一个led的描述头文件led_desc.h,在这个文件中把led需要操作的属性添加进去:
#ifndef __LED_DESC_H__
#define __LED_DESC_H__
#include "gd32f5xx.h"
struct led_desc{
	rcu_periph_enum periph;  //时钟
	uint32_t PORT;           //端口
	uint32_t mode;           //模式
	uint32_t pull_up_down;   //输出模式
	uint32_t pin;            
	FlagStatus Onbit;
	FlagStatus Offbit;
};
#endif /* end __LED_DESC_H__ */2、添加led.h
#ifndef __LED_H__ #define __LED_H__ #include <stdint.h> #include <stdbool.h> struct led_desc; typedef struct led_desc *led_desc_t; void led_init(led_desc_t led); void led_set(led_desc_t led, bool onoff); void led_on(led_desc_t led); void led_off(led_desc_t led); #endif /* end __LED_H__ */
在这个文件中,声明一个结构体,并声明一个led_desc_t的指针。同时声明一些led的初始化、设置电平,开、关的函数。
3、添加led.c
#include "led.h"
#include "led_desc.h"
void led_init(led_desc_t led)
{
	if(led == NULL)
	{
		return;
	}
    rcu_periph_clock_enable(led->periph);
    gpio_mode_set(led->PORT, led->mode, led->pull_up_down,led->pin);
    gpio_output_options_set(led->PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,led->pin);
    GPIO_BC(led->PORT) = led->pin;
}
void led_set(led_desc_t led, bool onoff)
{
	if(led == NULL)
	{
		return;
	}
	gpio_bit_write(led->PORT, led->pin, onoff ? led->Onbit : led->Offbit);
	
}
void led_on(led_desc_t led)
{
	if(led == NULL)
	{
		return;
	}
	GPIO_BOP(led->PORT) = (uint32_t)led->pin;
//	led_set(led,true);
	
}
void led_off(led_desc_t led)
{
	if(led == NULL)
	{
		return;
	}
	//led_set(led,false);
	GPIO_BC(led->PORT) = led->pin;
}在led.c中,实现了led操作函数,操作均为led_desc_t 的结构体指针。
4、添加board.c
#include "board.h"
#include "led_desc.h"
#include "led.h"
static struct led_desc led1_desc = {RCU_GPIOF,GPIOF,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_7,SET,RESET};
static struct led_desc led2_desc = {RCU_GPIOF,GPIOF,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_8,SET,RESET};
static struct led_desc led3_desc = {RCU_GPIOE,GPIOE,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_3,SET,RESET};	
static struct led_desc led4_desc = {RCU_GPIOE,GPIOE,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_2,SET,RESET};
led_desc_t led1 = &led1_desc;
led_desc_t led2 = &led2_desc;
led_desc_t led3 = &led3_desc;
led_desc_t led4 = &led4_desc;在这里主要声明4个小led的时钟、端口、PIN等。并将led1指向这四个led
5、添加board.h
#ifndef __BOARD_H__ #define __BOARD_H__ #include "led.h" #include "systick.h" extern led_desc_t led1; extern led_desc_t led2 ; extern led_desc_t led3 ; extern led_desc_t led4 ; #endif /* end __LED_H__ */
在这里主要把4个led进行extern ,开放给相关的程序进行调用。
到些led的面向对象的就实现了。
【使用】
在main.c中,首先对Led进行初始化,然后编写一个闪灯的程序
#include "board.h"
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    systick_config();
    led_init(led1);
    led_init(led2);
    led_init(led3);
    led_init(led4);
    while(1) {
        /* turn on led1, turn off led4 */
			led_on(led1);
			led_on(led2);
			led_on(led3);
			led_on(led4);
			delay_1ms(500);
			led_off(led1);
			led_off(led2);
			led_off(led3);
			led_off(led4);
			delay_1ms(500);
    }
}【总结】
在GD32F527的例程中,其实也有官方的的led初始化程序。但是通过这次面向对象的重构,实现驱动,与应用的分离,使得主程序中可阅读性提高,同时也实现比较好的解耦。
【思考】
通过阅读,其实面向对象还是不是很完整,比如只有初始化,但是没有去初始化,还有就是还是没有完全的解耦,移植到其他的平台上,还需要修改led.c这里的程序。
后期我准备进行进一步的修改,比如添加led的状态、去初始化、操作函数的注册等。
						
			
			
			
						
			
 我要赚赏金
