本文介绍IO驱动的调用方法。本系列文章将系统阐述其开发环境的使用方法,并期待构建基于Arduino的C++嵌入式开发平台。
MCU:ATmega168PA
系统平台:Arduino
github:https://github.com/snmplink/StarrySky
一、开发步骤
1、io.h源码
#ifndef IO_H_
#define IO_H_
#include <Arduino.h>
enum io_port{PortA, PortB, PortC, PortD};
enum io_pin{Pin0, Pin1, Pin2, Pin3, Pin4, Pin5, Pin7};
enum io_direction{Input, Output};
enum io_level{Low, High};
enum io_resistor{no_pull, pull_up, pull_down};
#ifdef __cplusplus
extern "C"{
class CIO
{
public:
io_port PortNumber;
io_pin PinNumber;
io_direction Dircetion;
io_level Level;
io_resistor Resistor;
uint8_t ArduionPinNumber;
public:
CIO(io_port PortNumber, io_pin PinNumber, io_direction Dircetion, io_level Level = High, io_resistor Resistor = no_pull);
void Set_0(void);
void Set_1(void);
void Set_I(void);
};
class CIO_Output:public CIO
{
public:
CIO_Output(io_port PortNumber, io_pin PinNumber, io_level Level = High);
};
class CIO_Output_OST:public CIO_Output
{
public:
CIO_Output_OST(io_port PortNumber, io_pin PinNumber, io_level Level = High);
void Open(void);
void Shut(void);
void Turn(void);
};
class CIO_Output_OST_Low:public CIO_Output_OST
{
public:
CIO_Output_OST_Low(io_port PortNumber, io_pin PinNumber);
};
class CIO_Output_OST_High:public CIO_Output_OST
{
public:
CIO_Output_OST_High(io_port PortNumber, io_pin PinNumber);
};
}
#endif
#endif
2、io.cpp源码
#include "io.h"
CIO::CIO(io_port PortNumber, io_pin PinNumber, io_direction Dircetion, io_level Level = High, io_resistor Resistor = no_pull)
{
this->PortNumber = PortNumber;
this->PinNumber = PinNumber;
this->Dircetion = Dircetion;
this->Level = Level;
this->Resistor = Resistor;
/*
---------------------------------------------------------------------------------
| D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 |
- -------------------------------------------------------------------------------
| PD0 | PD1 | PD2 | PD3 | PD4 | PD5 | PD6 | PD7 | PB0 | PB1 |
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
| D10 | D11 | D12 | D13 | D14 | D15 | D16 | D17 | D18 | D19 |
- -------------------------------------------------------------------------------
| PB2 | PB3 | PB4 | PB5 | PC0 | PC1 | PC2 | PC3 | PC4 | PC5 |
---------------------------------------------------------------------------------
-------------------------
| D20 | D21 | D22 |
- -----------------------
| PB6 | PB7 | PC6 |
-------------------------
*/
if (this->PortNumber == PortB)
{
if (this->PinNumber == 0) this->ArduionPinNumber = 8;
else if (this->PinNumber == 1) this->ArduionPinNumber = 9;
else if (this->PinNumber == 2) this->ArduionPinNumber = 10;
else if (this->PinNumber == 3) this->ArduionPinNumber = 11;
else if (this->PinNumber == 4) this->ArduionPinNumber = 12;
else if (this->PinNumber == 5) this->ArduionPinNumber = 13;
else if (this->PinNumber == 6) this->ArduionPinNumber = 20;
else if (this->PinNumber == 7) this->ArduionPinNumber = 21;
}
else if (this->PortNumber == PortC)
{
if (this->PinNumber == 0) this->ArduionPinNumber = 14;
else if (this->PinNumber == 1) this->ArduionPinNumber = 15;
else if (this->PinNumber == 2) this->ArduionPinNumber = 16;
else if (this->PinNumber == 3) this->ArduionPinNumber = 17;
else if (this->PinNumber == 4) this->ArduionPinNumber = 18;
else if (this->PinNumber == 5) this->ArduionPinNumber = 19;
else if (this->PinNumber == 6) this->ArduionPinNumber = 22;
}
else if (this->PortNumber == PortD)
{
if (this->PinNumber == 0) this->ArduionPinNumber = 0;
else if (this->PinNumber == 1) this->ArduionPinNumber = 1;
else if (this->PinNumber == 2) this->ArduionPinNumber = 2;
else if (this->PinNumber == 3) this->ArduionPinNumber = 3;
else if (this->PinNumber == 4) this->ArduionPinNumber = 4;
else if (this->PinNumber == 5) this->ArduionPinNumber = 5;
else if (this->PinNumber == 6) this->ArduionPinNumber = 6;
else if (this->PinNumber == 6) this->ArduionPinNumber = 7;
}
if (this->Dircetion == Output)
{
//引脚方向为输出,则设置输出方向,并初始化电平
pinMode(this->ArduionPinNumber, OUTPUT);
digitalWrite(this->ArduionPinNumber, this->Level);
}
else
{
//引脚方向为输入
if (this->Resistor == no_pull)
{
//无上拉电阻
pinMode(this->ArduionPinNumber, INPUT);
}
else if (this->Resistor == pull_up)
{
//上拉电阻
pinMode(this->ArduionPinNumber, INPUT_PULLUP);
}
else
{
//下拉电阻,AVR不支持
}
}
}
void CIO::Set_0(void)
{
digitalWrite(this->ArduionPinNumber, LOW);
}
void CIO::Set_1(void)
{
digitalWrite(this->ArduionPinNumber, HIGH);
}
void CIO::Set_I(void)
{
if (digitalRead(this->ArduionPinNumber) == HIGH)
{
this->Set_0();
}
else
{
this->Set_1();
}
}
CIO_Output::CIO_Output(io_port PortNumber, io_pin PinNumber, io_level Level):CIO(PortNumber, PinNumber, Output, Level, no_pull) {}
CIO_Output_OST::CIO_Output_OST(io_port PortNumber, io_pin PinNumber, io_level Level):CIO_Output(PortNumber, PinNumber, Level) {}
void CIO_Output_OST::Open(void)
{
if (this->Level == Low)
{
this->Set_1();
}
else
{
this->Set_0();
}
}
void CIO_Output_OST::Shut(void)
{
if (this->Level == Low)
{
this->Set_0();
}
else
{
this->Set_1();
}
}
void CIO_Output_OST::Turn(void)
{
this->Set_I();
}
CIO_Output_OST_Low::CIO_Output_OST_Low(io_port PortNumber, io_pin PinNumber):CIO_Output_OST(PortNumber, PinNumber, Low) {}
CIO_Output_OST_High::CIO_Output_OST_High(io_port PortNumber, io_pin PinNumber):CIO_Output_OST(PortNumber, PinNumber, High) {}
3、类结构
二、调用方法
1、建立HAL.h文件,可参照以下程序
#ifndef HAL_H_
#define HAL_H_
#include "io.h"
#ifdef __cplusplus
extern "C"{
class CLED:public CIO_Output_OST_High
{
public:
CLED(void);
};
class CHAL
{
public:
CLED LED;
};
}
#endif
#endif
2、建立HAL.cpp文件,可参照以下程序,在此文件中指定端口号和引脚号
#include "hal.h"
CLED::CLED(void):CIO_Output_OST_High(PortB, Pin4) { }
3、接下来,在main.cpp中直接调用即可
#include "target.h"
CTarget Target;
void setup()
{
}
void loop()
{
Target.HAL.LED.Turn();
Target.Delayms(100);
}
4、此程序编译后,与前述两个例子达到的效果是相同的,但程序可读性有极大提升,切按照芯片引脚号,进行程序设计。