发新帖本帖赏金 30.00元(功能说明)我要提问
返回列表
打印

GD32F103使用C++开发错误解决经验及注意事项

[复制链接]
1118|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dql2015|  楼主 | 2022-12-20 17:06 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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闪烁起来了。

使用特权

评论回复

打赏榜单

21小跑堂 打赏了 30.00 元 2022-12-30
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2022-12-30 18:16 回复TA
感谢分享基于GD32F103单片机的C++开发。 
沙发
tpgf| | 2023-1-5 10:10 | 只看该作者
请问现在的keil以及iar都支持c++开发单片机吗

使用特权

评论回复
评论
sjnh 2023-2-24 17:39 回复TA
都支持 
板凳
木木guainv| | 2023-1-5 10:24 | 只看该作者
咱们平时使用的编译器 可以对c++的语句进行正常编译吗

使用特权

评论回复
地板
晓伍| | 2023-1-5 10:42 | 只看该作者
在单片机的应用中 使用c++会提高我们的工作效率吗

使用特权

评论回复
5
八层楼| | 2023-1-5 11:18 | 只看该作者
这个把高级语言转化成低级语言的压力转化给哪里了呢

使用特权

评论回复
6
guanjiaer| | 2023-1-5 12:42 | 只看该作者
基本上是不是所有型号的单片机都支持c++开发呀

使用特权

评论回复
7
heimaojingzhang| | 2023-1-5 12:51 | 只看该作者
这种c++语言开发的可以在四位机以及八位机上使用吗

使用特权

评论回复
评论
尹小舟 2023-2-8 15:39 回复TA
四位不可以, C支持都很困难,8位可以比如AVR 
8
内政奇才| | 2023-2-23 10:18 | 只看该作者
C和c++区别在哪里

使用特权

评论回复
9
dql2015|  楼主 | 2023-2-23 12:10 | 只看该作者
八层楼 发表于 2023-1-5 11:18
这个把高级语言转化成低级语言的压力转化给哪里了呢

编译器

使用特权

评论回复
10
szt1993| | 2023-2-24 15:17 | 只看该作者
C语言是面向过程的,而C++是面向对象的
C语言的标准的函数库很松散,而C++对于大多数的函数都是集成的很紧密
C语言中结构只有成员变量,而在C++中结构中,可以有成员变量和成员函数

使用特权

评论回复
11
Jacquetry| | 2023-3-2 19:36 | 只看该作者
c++写起来确实很舒服

使用特权

评论回复
发新帖 本帖赏金 30.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

372

帖子

7

粉丝