如果你在开发一个很复杂的项目,把所有的代码都发在一个main.c文件中便有以下缺点:
1.杂乱无章、不美观。
2.不利于移植。
3.不利于查问题(编译出错修改)。
那如何解决?
类的封装:
用ardunio ide开发环境的特色方法:类的封装——简单点说就是把代码局域化,放在各个局域的.h和.c文件中。
所以,
接下来总结一下类的使用:
下面是一段节选示例代码:
.h文件:
class Led {
public:
Led();
Led(int userLedPin); //前两行为构造函数,用来存放初始化内容,对应.c文件理解 !!!重点:构造函数和析构函数的名字要和类的一样,
比如 类为LED,则构造函数要为LED();
~Led(); //第三行为析构函数,用来做初始化内容结束标志。
int ledPin = 2; //在类中声明用到的变量。
void on();
void off();
int getLedPin();
void setLedPin(int userLedPin); //这四行建立函数。 !!!重点:构造函数不同于此部分在于 类型 ,构造函数没有类型!
private:
int ledPin = 2 ;
};
用class建立了一个类LED;
public和private相互对立:public包含部分 表示 类的可供此文件以外的文件使用的部分,相反private包含部分 表示 该部分仅仅能供类内使用,比如 在类建立的函数的.c文件中使用。
下面是一段节选示例代码:
.c文件:
Led::Led(){
pinMode(2, OUTPUT);
}
Led::Led(int userLedPin) {
ledPin = userLedPin;
pinMode(ledPin, OUTPUT);
}
Led::~Led(){
Serial.println("Led Object Deleted.");
}
//这部分为初始化部分(构造函数)
void Led::on(){
digitalWrite(ledPin, HIGH);
}
void Led::off(){
digitalWrite(ledPin, LOW);
}
int Led::getLedPin(){
return ledPin;
}
void Led::setLedPin(int userLedPin){
ledPin = userLedPin;
pinMode(ledPin, OUTPUT);
}
//这部分为函数部分,函数功能。
下面是一段节选示例代码:
主函数main.c:介绍如何应用——主要是两个部分: 1.初始化; 2.函数调用。
void setup() {
Serial.begin(9600);
Led myLed; //建立Led类对象myLed !!!重点:这条语句作用是 让程序执行构造函数、析构函数部分和声明定义的变量部分,注意这条语言和变量一样都有作 用域的概念故 如果在setup()函数中声明,则只能在setup函数中用语法: myLed. 函数名() 来调用类建立的函数,比如myLed.setLedPin(3);
myLed.setLedPin(3);
int myLedPin = myLed.getLedPin();
Led myLed2(7); //建立Led类对象myLed2
int myLed2Pin = myLed2.getLedPin();
for(int i = 0; i < 3; i++){
myLed.on();
myLed2.on();
delay(1000);
myLed.off();
myLed2.off();
delay(1000);
}
}
void loop() {
}
至此,类的学习就完结了。
多说一些:
在学习过程中,不难发现,一些别人的ardunio代码中会经常出现类的应用。
把这些.c .h文件放到开发项目的library里则相当于你建立了一个自己的ardunio第三方库。
还有一点,在学习过程中,你会发现一些代码,比如 unsigned long currentMillis = millis(); 代码中的 millis(); 函数 并没有 类的特征,为什么? 因为它本来就不是类,而是HAL库,这大概也是一种简化代码的方法吧,类似还有ledcSetup();函数等。
我的理解:非常常用的函数(即普遍性强) 会被专业人士集合到HAL库 存在开发环境中,要用时用#include <Arduino.h>声明一下,而用户要实现特定功能的函数(这个要根据需要) ardunio会提供一种 类的封装 的方式给用户,也就是今天的内容,它们的共同点在于都是美化代码。
可能开发软件不同,习惯不同:我对比了ardunio ide和uvision5,发现uvion5的开发者的代码的.h文件直接用于自定义函数的声明,而不用类,我尝试在ardunio上也直接模仿不用类,发现也行,看来类的封装是 可选的,可用可不用。
在这建议,迎合大众的习惯,写ardunio时用类,写uvision5时直接在.h声明在.c使用。
补充:结构体也是一个重要概念,它经常和类 配合使用。
结构体的形式和类的有一点相似,这里提提:
代码:
typedef struct //建立结构体
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef; //结构体名字,可以多个
应用:
GPIO_InitTypeDef GPIO_InitStructure; //建立结构体变量
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //列出结构体成员的结构也是 什么.什么 如GPIO_InitStructure.GPIO_Pin,和类有点相似
GPIO_Init(GPIOA, &GPIO_InitStructure);
谢谢大家观看!