本帖最后由 dql2015 于 2022-12-30 15:51 编辑
#申请原创#@21小跑堂
当前很多工程师习惯用C开发微控制器程序,然而这可能从学生时代学了点C到职场的惯性,因为大多数理工科背景工程师没有过多的学习面向对象、软件工程相关知识。大多数情况下,C也足够使用,毕竟C生万物。 但是随着当前微控制器资源越来越丰富,性能越来越强劲,特别对于复杂的项目来说,利用面向对象语言编程绝对是事半功倍;C++属于面向对象OOP的编程语言,很多编译器早就提供了支持,熟悉的KEIL、IAR等软件已经支持C++11等比较新的版本;C++ 兼容C,可以进行混合编程,好处不言而喻。如果担心现代微控制器资源太小跑C++吃力,那一定是门外汉了。凡是了解过大名鼎鼎的Arduino就不会有这样的疑问,Arduino最畅销的单板Arduino UNO Rev3微控制器采用的是ATmega328P,ATmega328P仅仅是一颗8位AVR单片机,主频只有16MHz,SRAM只有2KB,Flash只有32KB,但是它却能用上C++。 本文使用GD32F103微控制,进行C++程序的开发测试,遇到一些问题特地分享。Keil5更新之后,开始支持ARM V6编译器,新版本的编译器对C++有了更多的支持,已经支持到了C++17。 以建立一个led闪烁的工程为例,说明注意事项。
首先选择V6编译器,然后去掉use microlib 勾选,这个一个C的依赖库,但比标准的库小,它可以减少C代码的大小,因为这个精简库不支持C++,所以我们需要去掉此项功能:
注意选择c++版本:
新建led.cpp、main.cpp文件,确保文件类型是C++源文件:
C/C++混合编程头文件引用问题:
编译器针对每个源文件不管是.c还是.cpp都编译成.o输出文件再进行链接,所以C语言是可以和C++混合编程的,但是由于C++支持函数重载的特性,使得C++的函数名在C中无法正确识别,因此要在.cpp中使用.c的函数,则必须在引用的头文件中增加extern "C"关键字:
新建头文件led.h,定义一个LED类:
#ifdef __cplusplus
extern "C" {
#endif
#include "gd32f10x.h"
#include "gd32f10x_gpio.h"
#include "gd32f10x_rcu.h"
#ifdef __cplusplus
}
#endif
class LED
{
private:
uint32_t port;
uint32_t pin;
public:
LED(rcu_periph_enum rcc,uint32_t port, uint32_t pin);
~LED();
void on(void);
void off(void);
void toggle(void);
};
新建led.cpp文件,实现头文件中定义的方法:
#include "led.h"
LED::LED(rcu_periph_enum rcc,uint32_t port, uint32_t pin)
{
this->port = port;
this->pin = pin;
rcu_periph_clock_enable(rcc);
gpio_init(this->port,GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, this->pin);
}
LED::~LED()
{
}
void LED::on(void)
{
gpio_bit_set(this->port, this->pin);
}
void LED::off(void)
{
gpio_bit_reset(this->port, this->pin);
}
void LED::toggle(void)
{
gpio_bit_write(this->port, this->pin, (bit_status)(1-gpio_input_bit_get(this->port,this->pin)));
}
新建测试文件main.cpp:
#ifdef __cplusplus
extern "C" {
#endif
#include "delay.h"
#ifdef __cplusplus
}
#endif
#include "gd32f10x.h"
#include "led.h"
int main (void)
{
delay_init();
LED led0(RCU_GPIOB,GPIOB,GPIO_PIN_12);
LED led1(RCU_GPIOA,GPIOA,GPIO_PIN_0);
while(1)
{
led0.toggle();
led1.toggle();
delay_ms(500);
}
}
第一次编译肯定会报错:
错误详情:
../../Firmware/CMSIS/GD/GD32F10x/Include\gd32f10x.h(315): error: expected ';' after enum
typedef enum {FALSE = 0, TRUE = !FALSE} bool;
这是由于C++标准库里面定义了bool,与GD32外设库里面产生了冲突,我们注释掉即可,重新编译无错误:
烧录到开发板后,就能看的led闪烁起来了。
|
感谢分享基于GD32F103单片机的C++开发。