为什么使用C++进行MCU开发
我从18年开始在STM32等上使用C++编程,在医疗器械行业进行IVD仪器开发,在此之前的项目开发中我是使用C语言。初次在MCU上使用C++,我有很多疑惑:C语言不挺好的吗?MCU上居然可以使用C++? 为什么选择C++?
工作七八年了,以前都没写过博客,现在开始记录一点东西吧!
尽管18年时使用C语言进行MCU开发已经相当熟练,但C++我是刚入茅庐,才会有那些疑问,并还专门请教了部门经理。这几年,随着工作经验的积累,愈发的认通C++在产品开发中的优点,那些疑惑也随之解开。
使用C++进行MCU开发,不代表只用C++,C语言也是可以混用的,特别是原厂提供的一些SDK,可以用C++封装这层SDK,后续、上层驱动业务进行C++开发。
场景描述
这里使用NXP的S32K1系列MCU,使用TI的TMP101温度传感器做示例。开发环境使用NXP的S32DS,使用其C库SDK,编程语言为C++。为了使用C++演示,建立工程时选择C++语言,不选择SDK,SDK部分由我们自行导入工程。

软件架构
这里进行演示,架构较为简单,在SDK基础上封装IIC驱动CI2C(C++),基于IIC驱动实现TMP101驱动CTmp(C++),板级相关时钟、引脚封装在CBoard中(C++),最后App中的main.cpp实现读取温度。

工程结构
基于上述软件架构[在SDK基础上封装IIC驱动CI2C(C++),基于IIC驱动实现TMP101驱动CTmp(C++),板级相关时钟、引脚封装在CBoard中(C++),最后App中的main.cpp实现读取温度。]实现工程结构:

CI2C类
参见NXP S32K1 IIC Driver接口与实现实现该C++类。
头文件:CI2C.h中主要实现初始化、读从机数据、写从机数据三大接口,为了省事,将板机相关的从机枚举、从机地址和波特率等也塞在了这里。
#ifndef CI2C_H_
#define CI2C_H_
#include "stdint.h"
#include "lpi2c.h"
class CI2C{
public:
void init(void);
void deinit(void);
bool read(uint8_t slave, uint8_t addr, uint8_t *data, uint16_t len);
bool write(uint8_t slave, uint8_t addr, const uint8_t *data, uint16_t len);
static CI2C *getInstance(void);
enum SLAVE
{
SLAVE_TMP101 = 0x00,
SLAVE_COUNT
};
private:
static CI2C *pI2CInstance;
void config(uint8_t slave);
const uint32_t I2C_NO = INST_LPI2C;
const uint32_t I2C_MAX_LEN = 128U;
const uint32_t I2C_TOUT = 100U;
uint8_t addr[SLAVE_COUNT] =
{
0x4A,//SLAVE_TMP101
};
uint32_t buad[SLAVE_COUNT] =
{
400000,//SLAVE_TMP101
};
};
#endif /* CI2C_H_ */
源文件:CI2C.cpp则是上述接口的具体实现。
void CI2C::init(void)
{
LPI2C_DRV_MasterInit(CI2C::I2C_NO, &lpi2c_MasterConfig0, &lpi2c_MasterState);
}
void CI2C::deinit(void)
{
LPI2C_DRV_MasterDeinit(CI2C::I2C_NO);
}
bool CI2C::read(uint8_t slave, uint8_t addr, uint8_t *data, uint16_t len)
{
bool rtv = true;
config(slave);
if( STATUS_SUCCESS == LPI2C_DRV_MasterSendDataBlocking(CI2C::I2C_NO, &addr, 1, false, CI2C::I2C_TOUT))
{
if(data && len && (STATUS_SUCCESS == LPI2C_DRV_MasterReceiveDataBlocking(CI2C::I2C_NO, data, len, true, CI2C::I2C_TOUT)))
{
rtv = true;
}
else
{
rtv = false;
}
}
else
{
rtv = false;
}
return rtv;
}
bool CI2C::write(uint8_t slave, uint8_t addr, const uint8_t *data, uint16_t len)
{
bool rtv = true;
config(slave);
uint8_t *ptrans = new uint8_t[CI2C::I2C_MAX_LEN];
uint8_t translen = 1;
if(ptrans)
{
*(ptrans+0) = addr;
if(len != 0)
{
if(data &&(len<CI2C::I2C_MAX_LEN-1))
{
memcpy((uint8_t*)(ptrans+1),data,len);
translen += len;
}
else
{
rtv = false;
}
}
if(rtv && (STATUS_SUCCESS == LPI2C_DRV_MasterSendDataBlocking(CI2C::I2C_NO, ptrans, translen, true, CI2C::I2C_TOUT)))
{
rtv = true;
}
else
{
rtv = false;
}
}
delete ptrans;
return rtv;
}
void CI2C::config(uint8_t slave)
{
lpi2c_baud_rate_params_t baud;
baud.baudRate = CI2C::buad[slave];
LPI2C_DRV_MasterSetBaudRate(CI2C::I2C_NO,LPI2C_FAST_MODE, baud);
LPI2C_DRV_MasterSetSlaveAddr(CI2C::I2C_NO, CI2C::addr[slave], false);
}
由于该款S32K1只有一个IIC模组,为了显得使用C++正规一点,整了一个单例,在其它文件中,只需要通过II2C对象去访问相关函数即可。
#define II2C CI2C::getInstance()
CI2C* CI2C::pI2CInstance = NULL;
CI2C *CI2C::getInstance(void)
{
if(CI2C::pI2CInstance == NULL)
{
CI2C::pI2CInstance = new CI2C;
}
return CI2C::pI2CInstance;
}
CTmp类
这是温度传感器TMP101类,只有几个寄存器,使用简单,在此不赘叙,只需要对照其DataSheet进行IIC访问即可。
头文件:
#ifndef CTMP101_H_
#define CTMP101_H_
#include "CI2C.h"
class CTmp{
public:
float gettmp(void);
private:
const float res = 0.0625;
enum
{
TMP_REG_TMP = 0x00,
TMP_REG_CFG = 0x01,
TMP_REG_TLOW = 0x02,
TMP_REG_THIGH = 0x03
};
};
#endif /* CTMP101_H_ */
源文件:
#include "CTmp101.h"
#include "II2C.h"
float CTmp::gettmp(void)
{
bool rtv = true;
float ftmp = 0.0;
uint16_t uiTmp = 0;
uint8_t ucRead[2] = {0};
rtv = II2C->read(II2C->SLAVE_TMP101, CTmp::TMP_REG_TMP, ucRead, 2);
uiTmp = (ucRead[0]<<0x08)|ucRead[1];
uiTmp >>= 4;
ftmp = res*uiTmp;
return ftmp;
}
App应用
应用层实现在main.cpp中,先完成板卡时钟、引脚初始化,接着进行IIC外设初始化,最后读取温度值。
#include "S32K146.h"
#include "CBoard.h"
#include "II2C.h"
#include "CTmp101.h"
int main()
{
CBoard mybrd;
mybrd.clk_init();
mybrd.pin_init();
mybrd.pwr_Init();
II2C->init();
float fVal = 0.0;
CTmp mTmp;
while(1)
{
fVal = mTmp.gettmp();
}
return 0;
}
结语
时间流逝的好快,一下子就工作了七年,怀念在深圳工作的那5年!
刚开始写博客,语言组织可能不是太好,还望海涵,也欢迎指出博文中不足与改进点。
1758



被折叠的 条评论
为什么被折叠?



