前言
C语言在各类单片机开发中占据着重要的地位,不管是学习51、STC还是STM32等单片机,都需要学习者有一个良好的C语言基础,至少要懂得基本数据结构、逻辑判断、指针等基础的知识点。如果想要学的更深一些,就需要了解结构体、枚举、函数指针、回调函数等一些C语言高级用法。
以STM32来说,目前主流的HAL库将诸多外设都进行了抽象化,硬生生的将底层和用户层进行了分离,从它的源码中我们可以看到好多的结构体,各种函数指针、回调函数满天飞。可以说,用C语言确实能够实现面向对象的编程思路,但同样的,需要耗费很大的精力去写程序。
在网上也经常看到C++效率低,不能用于单片机编程的说法。但是随着科技发展,单片机的性能也是飞速提高,包括内存空间也是越来越大,一般的项目用起来绰绰有余,C++比C低的那点效率基本可以忽略不计。
大名鼎鼎的Arduino,其各式各样的库都是用C++写的,创客用起来都非常的方便。而且常用的Arduino开发板,芯片是8位的。因此,对于STM32这类单片机来说,使用C++编程是肯定能够带起来的。
本篇文章主要介绍如何在Clion中使用C和C++混合编程的方法开发STM32。
本文的另一目的是对开发的文件进行管理,形成一种编程框架,方便阅读以及后期的维护工作
一、开发准备
1.硬件平台
-
STM32F103ZET6
-
ST-link V2
2.软件平台
参考前一篇文章的配置,本文程序在该篇文章基础上进行修改。
二、C与C++程序是如何相互调用的
关于C文件和C++文件相互调用的方法,在网上也有较多的解答。因此这里我就简单的介绍一下方法。
关键就是使用extern "C"的指令,其中的C,表示的是一种编译和连接规约,而不是一种语言。C表示符合C语言的编译和连接规约的任何语言。
由于C和C++的特性不同,一个是面向过程的语言,一个是面向对象的语言。因此,C++中的很多特性,比如函数的重载,在使用时就给我们带来了很大的便利。而为了实现C++中的这些特性,程序在编译后就会对函数“改名”,比如在C++中定义一个函数:
void func(int i,char c)
那么编译后,函数的名称可能就会变为:
_func_i_c
而对于C语言来说,并没有C++中的重载和类这些特性,因此上述函数编译后名称可能直接就是:
_func
非常简单粗暴。
正是这两种语言编译方式的不同,就会导致两种程序在调用的时候出现错误。因此就需要我们采用C++中的指令extern “C” 来实现两种语言文件的互相调用。
注意一下,extern “C” 关键字是在C++中的,如果在.C文件中使用,会出现以下错误:
error: expected identifier or ‘(’ before string constant
三、编程框架搭建
1.新建STM32CubeMX工程项目
主函数里存在while(1)无尽循环,clion这个大聪明会按照一般的编程检查方法将它给标记,我们可以将这个警告给去掉,当然不去管它也没关系。
把Endless loop去掉即可。
2.创建用户文件夹
新建目录“MyApplication”,并在该目录下新建4个文件:
LED.cpp和LED.h两个文件存放我们测试用的C++编写的LED试例;
Mymain.cpp 该文件主要是来存放主程序的,就是替换掉程序生成的main.c文件中的大循环while(1),相当于是扮演了一个搭桥的角色,这样的话我们就可以把主函数标准化,main.c文件就不需要进行大量修改,可以大大提高程序的可移植性;
MyApplication.h 文件主要用来存放所有使用的头文件,以及Mymain.cpp文件的主函数对外接口,所有源文件统一使用一个头文件,而且当有新的用户文件添加时,只需要修改这一个文件即可。
3.模板搭建
MyApplication.h
Mymain.cpp
Mymain()函数就是用户想要实现的主程序功能,此处是简单写了一个LED闪烁程序。
LED.h
LED.cpp
main.c
修改项目自动生成的main.c文件,标准化代码,
主要修改两处:
(1)头文件
删除项目自动生成的,包含自己写的的项目头文件
(2)添加Mymain()主程序
四、案例测试
按照前面用C++编写的闪烁LED程序,下载程序测试通过: