为什么使用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年!

刚开始写博客,语言组织可能不是太好,还望海涵,也欢迎指出博文中不足与改进点。

【使用C++开发MCU】02-IIC实例之读取温度相关推荐

  1. 【使用C++开发MCU】05-CAN实例之NXP S32K1 FlexCAN模块

    文章目录 概述 FlexCAN模块框图 协议引擎Protocol Engine (PE) 控制器主机接口Controller Host Interface (CHI) 总线接口单元Bus Interf ...

  2. 【使用C++开发MCU】04-CAN实例之CAN FD协议快速入门

    概述 随着现代技术的进步,自90年代开始使用的CAN协议[Classical CAN protocol (ISO 11898-1:2015) ]在各个邻域具有广泛应用但也面临巨大的压力. 因此,本专栏 ...

  3. python基础代码事例-零基础学习Python开发练习100题实例(2)

    零基础学习Python开发练习100题实例(2) 2018-02-26 13:11:39 1934浏览 11.题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个 ...

  4. ST官方的IIC实例解析(第一部分)

    ST官方的IIC实例解析 LM75A的管脚描述 输入/输出(引脚属性) 引脚标识 描述 输入 VCC 供电电压 输入 GND 参考地 输入 A2~A0 低3位地址引脚 输入 SDA IIC的数据总线 ...

  5. delphi2010 开发及调试WebService 实例

    delphi2010 开发及调试WebService 实例 基于Delphi的WebService编写 Delphi编写soap服务器与客户端程序 Delphi XE5通过WebService开发We ...

  6. 3万6千字爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行

    3w6爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行 认识函数式编程 函数相关复习 函数是一等公民 高级函数 函数作为参数 案例 1,模拟 forEach 案例 2, ...

  7. python零基础实例-零基础学习Python开发练习100题实例(1)

    零基础学习Python开发练习100题实例(1) 2018-02-25 09:37:59 2864浏览 1.题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序 ...

  8. 企业级的开发组件02 - DevExpress DXperience Universal 2011.2.5 Final

    郑重声明,如果引用,请注明出处:(原创 博客园:天之子) 企业级的开发组件02 - DevExpress DXperience Universal 2011.2.5 Final(2011-12-01 ...

  9. Android开发中StackOverflowError错误实例分析

    http://blog.csdn.net/mozhizun/article/details/7051300 http://blog.csdn.net/gaomatrix/article/details ...

最新文章

  1. 开源代码“All in One”:6 份最新「Paper + Code」等你复现 | PaperDaily #12
  2. access如何保存小数点后_跟宇哥学习Access数据库是怎样一种体验?(1)
  3. Linux 安装卸载软件及管理软件仓库
  4. 飞鸽传书(IPMSG)协议(翻译稿)
  5. Java-三元运算符
  6. BugkuCTF-Crypto题给你私钥吧
  7. 理论基础 —— 排序 —— 归并排序
  8. Magento教程 23:如何获取销售报表?
  9. mysql中起飞到达城市查询_让mysql慢慢起飞 - 初识慢日志
  10. MySQL C 语言应用程序接口开发教程
  11. 【源码小记】jQueryの事件绑定
  12. (转)财富取决于极少的大高潮,幸福取决于较多的小高潮
  13. java中的常见算法
  14. JavaSE基础学习
  15. SPSS教程:手把手教你设置哑变量以及解读结果
  16. 对抗 | 利用de4dot解密被混淆的.NET代码
  17. 几种常见的距离计算公式
  18. [bzoj4874]筐子放球
  19. XCTF 3rd-HITB CTF-2017 arrdeepee 复现
  20. Source must not be null\n\tat org.springframework.util.Assert.notNull(Assert.java:101)

热门文章

  1. 常见Linux系统下载站
  2. IOC和DI到底是什么?
  3. 通俗易懂地了解 Bloom filter
  4. 通过坐标点位,计算多边形面积
  5. 从模拟信号到数字信号
  6. 如何创建数据链接文件
  7. C 程序设计语言(第2版)
  8. Openstack-实践4.Manila 部署及功能验证
  9. 在iOS应用中使用字体图标及制作字体库
  10. Java毕业设计_基于HTML5的摄影社区的设计与实现