以面向对象的方式编写单片机程序
时间:2023-10-18 12:07:01
以面向对象的方式编写单片机程序
触发按钮控制 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 (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;