硬汉嵌入式论坛

 找回密码
 立即注册
查看: 8093|回复: 5
收起左侧

[MDK] 介绍STM32使用C和C++混合编程的方法,送给有需要的人

[复制链接]

25

主题

287

回帖

367

积分

高级会员

积分
367
发表于 2020-3-25 10:54:23 | 显示全部楼层 |阅读模式
本帖最后由 爱恋之燕 于 2020-3-25 11:24 编辑

STM32使用C和C++混合编程的方法,很多网站都有介绍,我在这里重新整理一下,送给有需要的人
使用C++就是为了使用面向对象编程,使用面向对象编程的优势在这里就不多说了,正题开始。
1.使用cubemx生成一个最基本的项目,时钟和SWD配置好就行,这里以MDK为例说明;
2.打开项目,打开魔术棒工具,选择Target选项卡,ARM Compiler改成AC6,将USE MicroLIB去掉,因为C++不支持MicroLIB;
1.png
再选择C/C++(AC6)选项卡,把Short enums/wchar选中;
2.png
3.STM32的库文件已经做了对C++的兼容支持,每个H文件在开头和结尾都有
  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
复制代码
  1. #ifdef __cplusplus
  2. }
  3. #endif
复制代码
这样的预编译定义,extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
中断函数定义前也要加上 extern "C";
4.再将main.c文件改成main.cpp,再加入项目中,可以看到File Type默认是C++,如果不是请修改,对C++文件,编译器就默认使用C++方式编译;
3.png
5.此时编译一下应该不会有错误;
6.C++有new关键字,类似C的malloc,使用new来新建对象时,默认在堆里面申请内存,可以利用函数重载,重载new操作符,代码如下,将malloc和free换成自己的malloc和free即可。
  1. /** Implement C++ new/delete operators using the heap  */
  2. void *operator new(size_t size)
  3. {
  4.        return malloc(size);
  5. }

  6. void *operator new[](size_t size)
  7. {
复制代码
7.环境搭建好了,就可以发挥C++的优势,这里我就牛刀小试,将一个LED抽象为一个对象,先定义类
  1. class LED_Class{
  2.         private:
  3.                 GPIO_TypeDef *gpio;
  4.                 uint16_t pin;
  5.         
  6.         public:
复制代码
成员变量有gpio和pin,用来定义LED的GPIO和PIN,成员函数有init、open、close,分别对LED进行初始化、打开、关闭的操作。
使用方法:
  1. LED_Class LED1(GPIOA,GPIO_PIN_11);
  2.         LED_Class LED2(GPIOA,GPIO_PIN_12);
  3.         
  4. LED1.init();
  5. LED2.init();
  6.         
  7.         while(1){        
  8.   LED1.open();
  9.   LED2.open();
  10.   HAL_Delay(500);
  11.   LED1.close();
  12.   LED2.close();
  13.   HAL_Delay(500);
  14.         }<span style="background-color: rgb(255, 255, 255);"> </span>
复制代码
这里创建了两个LED对象,可以看到,使用对象操作后,代码逻辑就很简洁,也可以将init函数放到构造函数里,这样在创建对象时,就可以自动初始化GPIO了,还可以将GPIO复位加入析构函数,当对象不用时,自动将GPIO复位,
完整代码如下
  1. #include "main.h"

  2. /*
  3. * Implement C++ new/delete operators using the heap
  4. */

  5. void *operator new(size_t size) {
  6.   return pvPortMalloc(size);
  7. }

  8. void *operator new[](size_t size) {
  9.   return pvPortMalloc(size);
  10. }

  11. void operator delete(void *p) {
  12.   vPortFree(p);
  13. }

  14. void operator delete[](void *p) {
  15.   vPortFree(p);
  16. }

  17. class LED_Class{
  18.         private:
  19.                 GPIO_TypeDef *gpio;
  20.                 uint16_t pin;
  21.         
  22.         public:
  23.                 LED_Class(GPIO_TypeDef *gpio,uint16_t pin){
  24.                         LED_Class::gpio = gpio;
  25.                         LED_Class::pin = pin;
  26.                 }
  27.                
  28.                 void init(void){
  29.                         GPIO_InitTypeDef GPIO_InitStruct;
  30.         
  31.                         GPIO_InitStruct.Pin                 =         pin;
  32.                         GPIO_InitStruct.Mode                 =         GPIO_MODE_OUTPUT_PP;
  33.                         GPIO_InitStruct.Pull                 =         GPIO_PULLUP;
  34.                         GPIO_InitStruct.Speed                 =         GPIO_SPEED_FREQ_LOW;
  35.                         HAL_GPIO_Init(gpio, &GPIO_InitStruct);
  36.                 }
  37.                
  38.                 void open(void){
  39.                         HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_RESET);
  40.                 }
  41.                
  42.                 void close(void){
  43.                         HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_SET);
  44.                 }
  45. };

  46. int main(void){
  47. HAL_Init();
  48.         System_ClockConfig();
复制代码


评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 赞一个!

查看全部评分

回复

使用道具 举报

6

主题

92

回帖

110

积分

初级会员

积分
110
发表于 2020-3-25 11:12:31 | 显示全部楼层
以前做国密SM2加密算法的时候用过C与C++混合编译,方法和你这个有点区别
回复

使用道具 举报

25

主题

287

回帖

367

积分

高级会员

积分
367
 楼主| 发表于 2020-3-25 11:41:33 | 显示全部楼层
  1. #include "main.h"

  2. /*
  3. * Implement C++ new/delete operators using the heap
  4. */

  5. void *operator new(size_t size) {
  6.   return pvPortMalloc(size);
  7. }

  8. void *operator new[](size_t size) {
  9.   return pvPortMalloc(size);
  10. }

  11. void operator delete(void *p) {
  12.   vPortFree(p);
  13. }

  14. void operator delete[](void *p) {
  15.   vPortFree(p);
  16. }

  17. class LED_Class{
  18.         private:
  19.                 GPIO_TypeDef *gpio;
  20.                 uint16_t pin;
  21.         
  22.         public:
  23.                 LED_Class(GPIO_TypeDef *gpio,uint16_t pin){
  24.                         LED_Class::gpio = gpio;
  25.                         LED_Class::pin = pin;
  26.                 }
  27.                
  28.                 void init(void){
  29.                         GPIO_InitTypeDef GPIO_InitStruct;
  30.         
  31.                         GPIO_InitStruct.Pin                 =         pin;
  32.                         GPIO_InitStruct.Mode                 =         GPIO_MODE_OUTPUT_PP;
  33.                         GPIO_InitStruct.Pull                 =         GPIO_PULLUP;
  34.                         GPIO_InitStruct.Speed                 =         GPIO_SPEED_FREQ_LOW;
  35.                         HAL_GPIO_Init(gpio, &GPIO_InitStruct);
  36.                 }
  37.                
  38.                 void open(void){
  39.                         HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_RESET);
  40.                 }
  41.                
  42.                 void close(void){
  43.                         HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_SET);
  44.                 }
  45. };

  46. int main(void){
  47. HAL_Init();
  48.         System_ClockConfig();
  49.         //LED_Class LED1(GPIOA,GPIO_PIN_11);
  50.        // LED_Class LED2(GPIOA,GPIO_PIN_12);
  51.        //也可以这样 ,这样就是将对象创建在内存池中,而不是栈中
  52.         LED_Class *LED1 = new LED_Class ;
  53.         LED_Class *LED2 = new LED_Class ;
  54. LED1->init();
  55. LED2->init();
  56.         
  57. while(1){        
  58.   LED1->open();
  59.   LED2->open();
  60.   HAL_Delay(500);
  61.   LED1->close();
  62.   LED2->close();
  63.   HAL_Delay(500);
  64. }
  65. }

复制代码
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2020-3-25 11:48:53 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

4

主题

160

回帖

172

积分

初级会员

积分
172
发表于 2020-3-25 13:16:19 | 显示全部楼层
不错,期待后续教程
回复

使用道具 举报

73

主题

1193

回帖

1412

积分

至尊会员

积分
1412
发表于 2024-1-4 15:06:49 | 显示全部楼层

硬汉哥,你认为单片机用cpp有这个必要嘛?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 13:05 , Processed in 0.173692 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表