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

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

[复制链接]
2221|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++,所以我们需要去掉此项功能:
aa.JPG
注意选择c++版本:

bb.JPG

新建led.cpp、main.cpp文件,确保文件类型是C++源文件:
00.JPG

C/C++混合编程头文件引用问题:
编译器针对每个源文件不管是.c还是.cpp都编译成.o输出文件再进行链接,所以C语言是可以和C++混合编程的,但是由于C++支持函数重载的特性,使得C++的函数名在C中无法正确识别,因此要在.cpp中使用.c的函数,则必须在引用的头文件中增加extern "C"关键字



新建头文件led.h,定义一个LED类:
  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif

  4. #include "gd32f10x.h"
  5. #include "gd32f10x_gpio.h"
  6. #include "gd32f10x_rcu.h"

  7. #ifdef __cplusplus
  8. }
  9. #endif


  10. class LED
  11. {
  12. private:
  13.         uint32_t port;
  14.         uint32_t pin;
  15. public:
  16.         LED(rcu_periph_enum rcc,uint32_t port, uint32_t pin);
  17.         ~LED();
  18.         void on(void);
  19.         void off(void);
  20.         void toggle(void);
  21. };
新建led.cpp文件,实现头文件中定义的方法:
  1. #include "led.h"

  2. LED::LED(rcu_periph_enum rcc,uint32_t port, uint32_t pin)
  3. {
  4.         this->port =  port;
  5.         this->pin = pin;
  6.         
  7.          rcu_periph_clock_enable(rcc);
  8.    gpio_init(this->port,GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, this->pin);
  9. }

  10. LED::~LED()
  11. {

  12. }

  13. void LED::on(void)
  14. {
  15.         gpio_bit_set(this->port, this->pin);
  16. }

  17. void LED::off(void)
  18. {
  19.         gpio_bit_reset(this->port, this->pin);
  20. }

  21. void LED::toggle(void)
  22. {
  23.     gpio_bit_write(this->port, this->pin, (bit_status)(1-gpio_input_bit_get(this->port,this->pin)));
  24. }
新建测试文件main.cpp:

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif

  4. #include "delay.h"

  5. #ifdef __cplusplus
  6. }
  7. #endif
  8.                
  9. #include "gd32f10x.h"
  10. #include "led.h"

  11. int main (void)
  12. {        
  13.         delay_init();
  14.         
  15.         LED led0(RCU_GPIOB,GPIOB,GPIO_PIN_12);
  16.         LED led1(RCU_GPIOA,GPIOA,GPIO_PIN_0);
  17.         
  18.         while(1)
  19.         {
  20.                 led0.toggle();
  21.                 led1.toggle();
  22.                 delay_ms(500);
  23.         }
  24. }

第一次编译肯定会报错:
11.JPG
错误详情:
  1. ../../Firmware/CMSIS/GD/GD32F10x/Include\gd32f10x.h(315): error: expected ';' after enum
  2. typedef enum {FALSE = 0, TRUE = !FALSE} bool;
这是由于C++标准库里面定义了bool,与GD32外设库里面产生了冲突,我们注释掉即可,重新编译无错误:
22.JPG

烧录到开发板后,就能看的led闪烁起来了。

打赏榜单

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

评论

感谢分享基于GD32F103单片机的C++开发。  发表于 2022-12-30 18:16
tpgf 发表于 2023-1-5 10:10 | 显示全部楼层
请问现在的keil以及iar都支持c++开发单片机吗

评论

都支持  发表于 2023-2-24 17:39
木木guainv 发表于 2023-1-5 10:24 | 显示全部楼层
咱们平时使用的编译器 可以对c++的语句进行正常编译吗
晓伍 发表于 2023-1-5 10:42 | 显示全部楼层
在单片机的应用中 使用c++会提高我们的工作效率吗
八层楼 发表于 2023-1-5 11:18 | 显示全部楼层
这个把高级语言转化成低级语言的压力转化给哪里了呢
guanjiaer 发表于 2023-1-5 12:42 | 显示全部楼层
基本上是不是所有型号的单片机都支持c++开发呀
heimaojingzhang 发表于 2023-1-5 12:51 | 显示全部楼层
这种c++语言开发的可以在四位机以及八位机上使用吗

评论

四位不可以, C支持都很困难,8位可以比如AVR  发表于 2023-2-8 15:39
内政奇才 发表于 2023-2-23 10:18 来自手机 | 显示全部楼层
C和c++区别在哪里
 楼主| dql2015 发表于 2023-2-23 12:10 | 显示全部楼层
八层楼 发表于 2023-1-5 11:18
这个把高级语言转化成低级语言的压力转化给哪里了呢

编译器
szt1993 发表于 2023-2-24 15:17 | 显示全部楼层
C语言是面向过程的,而C++是面向对象的
C语言的标准的函数库很松散,而C++对于大多数的函数都是集成的很紧密
C语言中结构只有成员变量,而在C++中结构中,可以有成员变量和成员函数
Jacquetry 发表于 2023-3-2 19:36 | 显示全部楼层
c++写起来确实很舒服
您需要登录后才可以回帖 登录 | 注册

本版积分规则

104

主题

384

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部