一.开发环境配置
1.在默认情况下,IAR会选择C作为开发语言,但可以手动选择以C++作为开发语言。具体配置步骤如下:打开option选项框,修改下面方框中指出的配置项,注意4处一定要选择这个,否则会报错。
2.为了使系统支持stdout等标准输入输出流,也就是使cout,cin,printf函数可用,我们需要做一些配置,具体配置如下:
首先需要将library选择为full,也就是使用c/c++的全库,支持c/c++的系列标准函数。
其次需要在预定义中添加_DLIB_FILE_DESCRIPTION定义,也就是支持我们实现fputc函数的重写。
最后重写fputc函数,定向到具体的串口:
/**
* @brief 重定义fputc函数
*
* @param ch 输出字符量
*
* @return void
*/
int fputc(int ch, FILE *f)
{
while((USART1->ISR & 0X40) == 0); //循环发送,直到发送完毕
USART1->TDR = (u8) ch;
return ch;
}
3.更改配置之后重新编译工程,可能会提示一些错误或警告,基本都是C语法和C++语法不兼容的问题,或类型转换存在问题,对于能够修改的错误按照C++语法规则进行修改。对于不能修改的错误继续看第3点。
4.对于需按照C语言规则编译的代码无法进行修改,可以使用声明C编译的方式将该代码段嵌入到C++工程中。
extern "C"{ //声明用C的方式编译下列代码段
.........................................
.........................................
.........................................
/* c语言代码段 */
.........................................
.........................................
.........................................
}
5.将c工程文件的头文件以extern “C”{ }的方式包含在C++工程中
extern "C"{ //声明用C的方式引用下列头文件
#include "main.h"
#include "lptim.h"
#include "usart.h"
#include "gpio.h"
#include "delay.h"
}
6.添加c++头文件以及命名空间
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<iterator>
using namespace std;
7.现在C++开发环境基本配置完成,可按照C++的开发方式进行开发,支持STL及类编程,举例用法如下:
//1.类的使用
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<iterator>
extern "C"{ //声明用C的方式引用下列头文件
#include "main.h"
#include "lptim.h"
#include "usart.h"
#include "gpio.h"
#include "delay.h"
#include "class.h"
}
using namespace std;
class person
{
public:
//默认构造函数
person()
{}
//有参构造函数
person(string m_name,int m_age):name(m_name),age(m_age)
{}
//拷贝构造函数
person(person &p1)
{
this->name=p1.name;
this->age=p1.age;
}
//析构函数
~person()
{
cout<<"person类的析构\r\n"<<endl;
}
//公有函数
void show(void)
{
cout<<"name= "<<this->name<<"\r\n"<<endl;
cout<<"age= "<<this->age<<"\r\n"<<endl;
}
private:
string name;
int age;
};
//2.类的继承
class student:public person
{
public:
//默认构造函数
student()
{}
//有参构造函数
student(string m_name,int m_age,float m_score):person(m_name,m_age),score(m_score)
{}
//析构函数
~student()
{
cout<<"student类的析构\r\n"<<endl;
}
//公有函数
void display()
{
person::show();
cout<<"score= "<<this->score<<"\r\n"<<endl;
}
private:
float score;
};
//5.vector容器的使用
vector<int> vec={1,2,3,4,5};
back_inserter(vec)=66; //back_inserter的使用,需要包含<>
vec.push_back(77);
cout<<"vec.size()="<<vec.size()<<"\r\n"; //输出size()
cout<<"vec.capacity()="<<vec.capacity()<<"\r\n"; //输出capacity()
for(auto result:vec)
{
cout<<result<<" "; //打印1
}
8.可以使用cout代替printf函数做io输出,但需要给出putchar函数,这里使用USART2做IO输出路径。
int putchar(int ch)
{
while((USART2->ISR & 0X40) == 0); //循环发送,直到发送完毕
USART2->TDR = (u8) ch;
return ch;
}
二.开发建议
由于C++丰富的STL编程资源以及类封装、继承、多态的特点可以极大方便开发。容器及迭代器的使用使得对于常见算法的支持十分友好,而且c++具有更加丰富的外部资源库,因此可以提高开发效率。
但是由于单片机的资源十分有限,因此一些泛型算法的使用会较为耗系统资源,所以主要推荐使用C++的类功能做开发,对于泛型算法的使用要小心内存溢出及内存管理的事项。
另外对于单片机底层驱动以及BSP的开发一般固定为C语言写的。因此建议使用extern “C”{ }将原BSP文件包含进工程,若是程序运行出现莫名其妙的错误,考虑给C程序添加extern “C”{ }或许能解决问题。