以面向对象的方式编写单片机程序

以面向对象的方式编写单片机程序

通过触发按键控制 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;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值