以面向对象的方式编写单片机程序
通过触发按键控制 LED 的亮灭
- Traditional way
int main(void)
{
while(1)
{
if (read_gpio_pin_key())
{
write_gpio_pin_led();
}
}
}
- OOP way
typedef struct LEDDevice {
int group;
int pin;
void (*Init)(struct LEDDevice *pDev);
void (*Control)(struct LEDDevice *pDev, int iStatus);
} LEDDevice, *pLEDDevice;
void autumn_LED_Init(struct LEDDevice *pDev)
{
// 配置为输出引脚
HAL_write_Init();
}
void autumn_LED_Control(struct LEDDevice *pDev, int iStatus)
{
// 设置引脚电平
HAL_GPIO_WritePin();
}
static LEDDevice g_tLEDDev = {
PORTA, PIN5, autumn_LED_Init, autumn_LED_Control
};
int main(void)
{
pLEDDevice pLEDDev = &g_tLEDDev;
pLEDDev->Init(pLEDDev);
while(1)
{
if (read_gpio_pin_key())
{
pLEDDev.control(pLEDDev, 1);
}
}
}
示例:为公司编写显示 LCD 函数
- Traditional way
void draw_logo_lcda(void)
{
printf("display logo on lcd a\r\n");
}
void draw_logo_lcdb(void)
{
printf("display logo on lcd b\r\n");
}
// 使用面向对象的方法
struct lcd_ops {
int type;
void (*draw_logo)(void);
void (*draw_text)(char *str);
};
struct lcd_ops autumn_lcds[] = {
{0, draw_logo_lcda, NULL},
{1, draw_logo_lcdb, NULL},
{2, draw_logo_lcdc, NULL},
{3, draw_logo_lcdd, NULL}
};
struct lcd_ops *get_lcd_for_type(void)
{
int i;
int type = get_lcd_type();
for(i = 0; i < 4; i++)
{
if (autumn_lcds[i].type == type)
{
return autumn_lcds[i];
}
}
return NULL;
}
int main(void)
{
struct lcd_ops *plcd = get_lcd_for_type();
plcd->draw_logo();
while(1);
return 0;
}
// 只有两款LCD的情况下
int main1(void)
{
#ifndef LCD_TYPE_A
draw_logo_lcda();
#else
draw_logo_lcdb();
#endif
while(1);
return 0;
}
// 同时可以显示两款LCD
int main2(void)
{
int type = get_lcd_type();
if (type == 0)
{
draw_logo_lcda();
}
else if (type == 1)
{
draw_logo_lcdb();
}
// 如果还有很多款,那么往后继续添加 if-else 语句即可
while(1);
return 0;
}
对按键抽象出结构体
#define BUFFER_SIZE 10
typedef struct
{
InputEvent buffer[BUFFER_SIZE];
volatile unsigned int pW;
volatile unsigned int pR;
} InputEventBuffer;
typedef enum
{
INPUT_EVENT_TYPE_KEY,
INPUT_EVENT_TYPE_TOUCH,
INPUT_EVENT_TYPE_NET,
INPUT_EVENT_TYPE_STUDIO
} INPUT_EVENT_TYPE;
typedef struct InputEvent {
TIME_T time;
INPUT_EVENT_TYPE eType;
int iX;
int iY;
int iKey;
int iPressure;
char str[INPUT_BUF_LEN];
} InputEvent, *pInputEvent;
typedef struct InputDevice {
char *name;
int (*GetInputEvent)(PInputEvent ptInputEvent);
int (*DeviceInit)(void);
int (*DeviceExit)(void);
struct InputDevice *pNext;
} InputDevice, *PInputDevice;