在51和STM32单片机上使用面向对象的编程,第一篇:炫酷地点亮一盏LED灯

xiaoxiao2021-02-28  94

我们学单片机,第一个程序就是点亮一盏LED灯,那么我单片机开启面向对象方式的第一步也是点亮一盏LED灯,这里主要是用到了继承和封装的2个概念;

这里我们先讲一下,使用传统的一些LED操作,并分析这些操作有什么问题:

以前我点亮一盏LED是这样的

#define LED1 PAout(1) #define LED_ON 1 #define LED_OFF 0 void LED1_Init() { ......;//初始化IO口之类的函数 } LED1 = LED_ON; //点亮 这样写有这么几个问题点击打开链接

1:我每增加一个灯,就要写一段LED初始化代码,要定义一个端口;

void SetLedGPIOCMD(struct CLASS_LED * p, GPIO_TypeDef* GPIOx, u16 GPIO_Pin) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOx, &GPIO_InitStructure); p->_GPIOx = GPIOx; p->_GPIO_Pin = GPIO_Pin; list.AddList(&LED_ListHead,p); }

2:我要实现LED功能的拓展不方便,比如我要实现LED的闪烁;

所以我现在这样点亮一盏LED灯,以及让它闪烁起来

首先创建一个结构体,或者我们叫做 定义一个 LED类

typedef struct CLASS_LED { void (* const SetLedGPIOCMD)(struct CLASS_LED * p, GPIO_TypeDef* GPIOx, u16 GPIO_Pin); //设置LED端口 void (* const LED_SetST)(struct CLASS_LED * p,u8 LED_ST); //struct CLASS_LEDBlink * LEDBlink; //这里是继承了 LED闪烁类,我们下面再来编写,先不看,有需要详细了解的朋友,可以下载工程文件查看源码 GPIO_TypeDef* _GPIOx; //LED端口 u16 _GPIO_Pin; //LED端口 u8 _LED_ST; //记录LED灯当前的状态 }typ_CLASS_LED;

然后我们来编写相关的函数

void SetLedGPIOCMD(struct CLASS_LED * p, GPIO_TypeDef* GPIOx, u16 GPIO_Pin) //初始化LED指定的端口 { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOx, &GPIO_InitStructure); p->_GPIOx = GPIOx; p->_GPIO_Pin = GPIO_Pin; } void LED_SetST(struct CLASS_LED * p,u8 LED_ST) { switch(LED_ST) { case LED_ON: GPIO_ResetBits(p->_GPIOx, p->_GPIO_Pin); break; case LED_OFF: GPIO_SetBits(p->_GPIOx, p->_GPIO_Pin); break; case LED_RE: GPIO_WriteBit(p->_GPIOx, p->_GPIO_Pin,!GPIO_ReadOutputDataBit(p->_GPIOx, p->_GPIO_Pin)); default: break; } }

然后我们来定义一个宏定义,来给这个结构体赋值(面向对象里面叫实例化这个类)

#define NewLed()    {            \   SetLedGPIOCMD,                 \ //这里我们把上面定义的函数名赋值过来,也就是 赋值函数指针   LED_SetST,                     \   NULL,                          \   0,                             \   0,                              \   0\ } 

好了,这些我们就来创建(实例化)这个LED对象,以及操作它

typ_CLASS_LED led0 = NewLed(); //创建了一个led0的对象 led0.SetLedGPIOCMD(&led0, GPIOB, GPIO_Pin_5); //设置指定的端口,这样是不是很方便,不用重新去写了,这就是面向对象的一个思维,把很类似的代码提取出来,减少代码的重复率 led0.LED_SetST(&led0,LED_ON);//点亮led0, 这样逻辑是不是很清楚,而且你想要增加功能,就往结构体里面增加相关的方法,比如你可以增加blink功能

好了,这下我们就完成了点亮一盏LED灯,虽然代码量比传统的大了很多,一开始也会觉得比较复杂,但是你想一下 我们以后这样操作就可以了,想要增加一个LED,只要定义一个LED对象,然后指定其端口就可以随意操作了(比较起来,好像传统的方式也可以,但是这主要是一个思维上的进步,这里的进步主要体现在封装的概念,而且你要想拓展都很方便,而且逻辑很清楚),在实际的工程中,功能增加了很多,比如继承了led_blink类,比如使用了链表结构

第一篇,写的很多地方可能不是很清楚,以后尽量把它理顺吧。。。有兴趣的请看源码工程,我随后上传。。。里面有操作说明和相关注释,有什么问题欢迎交流

第一篇相关工程源码下载:https://download.csdn.net/download/qq_32079231/10387107

转载请注明原文地址: https://www.6miu.com/read-2600144.html

最新回复(0)