这篇文章主要讲解了“C++设备模板怎么声明和定义”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++设备模板怎么声明和定义”吧!
将片上外设进行封装,可以使用如下三种技术:
使用类定义外设,然后创建对象。
POD类实现
普通的类
静态模板(所有的成员都是静态的)
这两种模板共同的特点是不需要动态分配内存,区别在于一个是静态访问成员,一个是对象方法访问,POD类型无法添加自定义的数据成员。
将一个MCU的全部寄存器声明好以后,如果是简单的mcu,那么就可以直接使用了,例如:PORTA.DDR.v |= 0x01 或者USART0.UCSRC.UPM = 0x00;但是总有一些重复步骤和相关的代码,我们就可以将其封装起来,例如异步计数器的配置步骤就是可以复用的。C++可以使用对象封装这些操作,但遗憾的是,像avr编译器并不支持对象的生成和删除,定义好类之后,是不能用的,因为未定义delete操作符和其他基础的类库,这时可以自定义或者引用一些第三方的类库来解决这些问题,如果不想引用第三方类库的话,那么使用静态类模板也是一个不错的选择。如下所示:
template<typename U, volatile U* u, bool base = false> class USART { public: struct SerialConfig { word baud = 115200; byte data = USART_DATABIT_8; byte stop = USART_STOP_1; byte parity = USART_PARITY_DISABLE; }; __f__ void init(const SerialConfig& conf) { ... } __f__ hword calUBRR(const word baud) { ... } ... // 其他操作 private: };
使用模板参数传递寄存器是为了提高代码效率,base是为了复用模板,__f__是一个宏,他将函数成员定义成静态的。在定义完基本模板后,可以对其进行功能扩展或者功能的特化。例如,在初始化时,除了对USART功能寄存器进行设置之外,还要设置rx,tx管脚,这时,可以利用模板的特化技术来实现:
template<> void u0::init(const SerialConfig& conf) { rx::init(INPUT); tx::init(OUTPUT); u0_base::init((u0_base::SerialConfig&) conf); } template<> void u1::init(const SerialConfig& conf) { ... } // 其实可以再次简化,在模板参数总增加管脚定义。
usart0h和usart1的初始化函数可以加进对管脚的初始化,u0_base就是复用模板,我不用在写一遍USART的基本的初始化代码了。使用方法如下:
using u0 = USART<USART0_t, &USART0>; u0::SerialConfig sc; sc.baud = 115200; sc.data = USART_DATABIT_8; sc.parity = USART_PARITY_DISABLE; sc.stop = USART_STOP_1; u0::init(sc); u0::start();
感谢各位的阅读,以上就是“C++设备模板怎么声明和定义”的内容了,经过本文的学习后,相信大家对C++设备模板怎么声明和定义这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。