STM32 GPIO抽象驱动模板类引用及数组存储问题求助
解决方案
1. 定义抽象基类实现接口统一
先创建一个无成员变量的抽象基类,提供GPIO操作的纯虚接口,所有模板化的GPIO实现都继承该基类:
struct Hal_Gpio_Base { virtual bool read() = 0; // 可按需添加write、toggle等其他GPIO操作接口 virtual ~Hal_Gpio_Base() = default; // 基类必须声明虚析构 };
2. 修改模板类继承基类
让你的模板GPIO类继承自Hal_Gpio_Base,这样不同模板参数的实例都会属于同一基类的子类:
基于版本一的修改:
template<uint32_t port, uint32_t pin> struct Hal_Gpio_template : public Hal_Gpio_Base { bool read() override { return reinterpret_cast<GPIO_TypeDef*>(port)->IDR & pin; } };
基于版本二的修改(适配更灵活的类型参数):
template<class Port, Port port, class Pin, Pin pin> struct Hal_Gpio_template : public Hal_Gpio_Base { bool read() override { return reinterpret_cast<GPIO_TypeDef*>(port)->IDR & pin; } };
3. 调整Interface_Gpio类
现在Interface_Gpio可以持有Hal_Gpio_Base的引用,兼容所有模板化的GPIO实例:
struct Interface_Gpio { Hal_Gpio_Base& pin; Interface_Gpio(Hal_Gpio_Base& pin) : pin(pin) {} bool read() { return pin.read(); } };
4. 解决数组存储与循环扫描问题
利用基类指针的多态特性,创建基类指针数组存储不同GPIO实例的地址,即可实现循环扫描:
// 定义具体GPIO实例(以CMSIS宏为例) Hal_Gpio_template<GPIOA_BASE, GPIO_PIN_0> gpio_a0; Hal_Gpio_template<GPIOB_BASE, GPIO_PIN_1> gpio_b1; // 基类指针数组,容纳不同模板实例 Hal_Gpio_Base* gpio_array[] = {&gpio_a0, &gpio_b1}; // 循环扫描所有GPIO for (auto* gpio : gpio_array) { bool state = gpio->read(); // 处理读取到的引脚状态 }
内存开销说明
- 模板类本身无成员变量,不会占用额外RAM,仅虚函数表会占用少量ROM(STM32F0完全可承受)。
- 基类指针数组每个元素占4字节(32位MCU),相比非模板版本每个GPIO实例8字节,仍能有效节省内存,且GPIO数量越多,节省效果越明显。
- 若完全不想使用虚函数,可采用类型擦除技术(如自定义函数指针包装),但实现复杂度更高,虚函数方案是资源受限MCU上的平衡选择。
内容的提问来源于stack exchange,提问作者Nik
相关产品推荐
相关产品推荐

