1.I2C函数中HAL_I2C_Mem_Write和HAL_I2C_Master_Transmit有啥区别?{

使用HAL_I2C_Mem_Write等于

先使用HAL_I2C_Master_Transmit传输第一个寄存器地址,再用HAL_I2C_Master_Transmit传输写入第一个寄存器的数据。

HAL_I2C_Mem_Write一样可以传输多个数据,有一个参数设置数据大小。

在传输过程,寄存器地址和源数据地址是会自加的。

至于读函数也是如此,因此用HAL_I2C_Mem_Write和HAL_I2C_Mem_Read,来写读指定设备的指定寄存器数据是十分方便的,已在SH1106和BMP280上验证成功,让设计过程省了好多步骤。

}

2._Error_Handler(__FILE__, __LINE__);函数的分析

{

我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除,而一旦需要再次调试的时候,这些语句又不得不一条条的加上,这给我们带来了很大的不便,浪费了我们很多的时间,也造成了调试的效率低下。所以,很多人会选择使用宏定义的方式来输出调试语句。

比如,定义一个宏开关:

#define __DEBUG

当需要调试的时候,使用语句:

#ifdef __DEBUG

printf(xxx);

#endif

这种方式的调试,可以通过undef __DEBUG的方式让告知编译器不编译这些语句,从而不再输出这些语句。但是这种方式的麻烦之处也是显而易见的,每一条调试语句都需要使用两条宏定义来包围,这不但在代码的编写上不便,源码结构也不好看,工作量依然不小。

如果我们能够把这三条语句编程一条,那该多舒服呀~,于是,我们想到使用这样的语句:

#ifdef __DEBUG

#define DEBUG(info)    printf(info)

#else

#define DEBUG(info)

#endif

这样,我们在编写代码的时候,使用DEBUG一条语句就可以了,我们把宏开关__DEBUG打开,所有的DEBUG(info)宏定义信息都会被替换为printf(info),关上则会被替换成空,因此不会被编译。嗯,这次方便多了,一条语句就可以了~~~ 但是,问题也随之而来了,printf是支持多个参数的,而且是不定参数,当你使用下面这样的语句时就会报错:

DEBUG("%s",msg)

这是因为,DEBUG(info)这条宏定义只支持一个参数的替换。

因此,我们希望DEBUG能够像printf那样,支持多个参数,并且这些参数刚好展开成为printf语句本身使用的参数,譬如:我们希望DEBUG("%s",msg)能够展开为printf("%s",msg)

正文:

通过网上的资料查阅,发现自C99规范以后,编译器就开始支持不定参数的宏定义,就像printf一样。

大家可以看看这篇文章:http://blog.csdn.net/aobai219/archive/2010/12/22/6092292.aspx

(这个链接也转的,我已经找不到原始作者到底是谁了,唉,互联网啊。。。)

于是,我们定义了一个这样的东东:

#define DEBUG(format, ...) printf (format, ##__VA_ARGS__)(' ## '的意思是,如果可变参数被忽略或为空,将使预处理器( preprocessor )去除掉它前面的那个逗号。)

于是乎,我们神奇地发现,DEBUG完全取代了printf,所有的DEBUG(…)都被完成的替换成了printf(…),再也不会因那个可恶的逗号而烦恼了。

但是,我们发现,光有printf还不够,虽然调试信息是输出了,可是很多的调试信息输出,我们并不能一下子知道这条信息到底是在那里打印出来的,于是,我们又想,能不能把当前所在文件名和源码行位置也打印出来呢,这样不就一目了然了吗,哪里还用的着去想,去找调试信息在哪里输出的呢,都已经打印出来了!

于是我们就有了下面的故事。。。

编译器内置宏:

先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息。

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

__DATE__:在源文件中插入当前的编译日期

__TIME__:在源文件中插入当前编译时间;

__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

编译器在进行源码编译的时候,会自动将这些宏替换为相应内容。

看到这里,你的眼睛应该一亮了吧,嗯,是的,__FILE__和__LINE__正是我们前面想要的输出的,于是,我们的每一条语句都变成了:

DEBUG("FILE: %s, LINE: %d…",__FILE__,__LINE__,…)

其实没有必要,__FILE__本身就会被编译器置换为字符常量,于是乎我们的语句又变成了这样:

DEBUG("FILE:"__FILE__", LINE: %d…",__LINE__,…)

但是,我们还是不满足,依然发现,还是很讨厌,为什么每条语句都要写"FILE:"__FILE__", LINE: %d 以及,__LINE,这两个部分呢?这不是浪费我们时间么?

哈哈,是的,这就是本次大结局,把DEBUG写成这样:

DEBUG(format,...) printf("FILE: "__FILE__", LINE: %d: "format"/n", __LINE__, ##__VA_ARGS__)

没错,就是这样!下面,所有的DEBUG信息都会按照这样的方式输出:

FILE: xxx, LINE: xxx, …….

最后:

最后,老规矩,coding测试。

  1. //============================================================================
  2. // Name : debug.cpp
  3. // Author : boyce
  4. // Version : 1.0
  5. // Copyright : pku
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include
  9. #define __DEBUG__
  10. #ifdef __DEBUG__
  11. #define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"/n", __LINE__, ##__VA_ARGS__)
  12. #else
  13. #define DEBUG(format,...)
  14. #endif
  15. int main() {
  16. char str[]="Hello World";
  17. DEBUG("A ha, check me: %s",str);
  18. return 0;
  19. }

测试结果:

}

STM32 HAL库的使用心得的更多相关文章

  1. stm32 HAL库笔记(零)

    最近在设计四旋翼飞行器,用stm32f407,有三种开发方式可以选择:一.寄存器开发.二:库函数开发.三:HAL库开发,考虑了一下,选择了HAL库,原因如下: 1. 寄存器开发相对较慢,寄存器很多,配 ...

  2. STM32 HAL库详解 及 手动移植

    源: STM32 HAL库详解 及 手动移植

  3. 【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章

    从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章  如何使用本书 1.1  本书的参考资料 本书参考资料为:<STM32 ...

  4. 【有趣的全彩LED | 编程】用STM32 HAL库让WS2812B为你所动

    一.效果展示 观看演示效果:https://www.bilibili.com/video/BV1dv411Y7x3 使用STM32 HAL库编程 PWM+DMA控制输出,CubeMX生成初始工程 实现 ...

  5. 【情人节选帽子】TCS34725颜色传感器和Python图形界面编程(STM32 HAL库)

    截图 描述: l  STM32 HAL库编程 l  使用模拟IIC通信,方便程序移植 l  Python界面编写,蘑菇头的帽子是什么颜色 l  STM32 HAL库串口通信 l  Python界面使用 ...

  6. 【春节歌曲回味 | STM32小音乐盒 】PWM+定时器驱动无源蜂鸣器(STM32 HAL库)

    l  STM32通过PWM与定时器方式控制无源蜂鸣器鸣响 l  STM32小音乐盒,歌曲进度条图形显示与百分比显示,歌曲切换 l  编程使用STM32 HAL库 l  IIC OLED界面编程,动画实 ...

  7. STM32 HAL库利用DMA实现串口不定长度接收方法

    参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...

  8. STM32 HAL库 UART 串口读写功能笔记

    https://www.cnblogs.com/Mysterious/p/4804188.html STM32L0 HAL库 UART 串口读写功能 串口发送功能: uint8_t TxData[10 ...

  9. WS2812B彩灯详细讲解篇(STM32 PWM+DMA控制 STM32 HAL库编程 循环延时控制多种控制方式)

    一.效果展示 观看演示效果:https://www.bilibili.com/video/BV1JT4y1P72Q 二. 基础认识 (一)  小理论 WS2812B是一种智能控制LED光源,将控制电路 ...

随机推荐

  1. linux 安装java环境

    1.检查是否安装或者linux系统自带jdK 命令:java -version 查找JDK相关包是否被安装: rpm -qa |grep jdk rpm -qa |grep gcj 删除JDK相关包: ...

  2. innodb 关键特性(insert buffer)

    一.insert buffer 性能改善 insert buffer和数据页一样,也是物理页的一个组成部分. 在innodb存储引擎中,主键是行唯一的标识符.通常应用程序中行记录的插入顺序是按照主键递 ...

  3. 微软必应Bing搜索引擎这几天无法访问!

    一.用必应(Bing)临时域名: www2.bing.com 或者 www4.bing.com 临时域名博主验证有效 二.修改hosts文件: 用户只需要暂时修改下host然后坐等微软服务器恢复后再删 ...

  4. UDP广播 MAC地址

    enduser_setup.start() ListenPort = wifi.setmode(wifi.STATIONAP) wifi.sta.autoconnect() clientid = wi ...

  5. Hillstone设备管理-恢复出厂设置

    1.CLI命令行操作 unset all: 根据提示选择是否保存当前配置y/n: 选择是否重启y/n: 系统重启后即恢复到出厂设置. 2.webUI操作 “系统”—“配置”,点击“清除”按钮,系统会提 ...

  6. @Autowired注解和静态方法

    @Autowired注解入static属性时,出现NullPointerException异常. 使用构造方法可解决: @Component public class Test { private s ...

  7. PEP8 规范

    Python PEP8 编码规范中文版   原文链接:http://legacy.python.org/dev/peps/pep-0008/ item detail PEP 8 Title Style ...

  8. MVC htmlAttributes and additionalViewData

    @Html.TextBoxFor(m => m.UserName, new { title = "ABC" }) // 输出结果为 <input data-val=&q ...

  9. .net webapi 接收 xml 格式数据的三种情况

    webapi 接收 xml 的三种方法 前段时间接到一个任务写一个小接口,要接收java端返回过来的短信xml数据. 刚拿到项目,我的第一想法是对方会以什么形式发送xml格式的数据给我呢,设想三种情况 ...

  10. logstash 修改配置不重启的方法

    1.修改好yml配置 2.进入logstash 容器内,或服务器上 3.ps -ef | grep logstash 拿到进程号 4.kill -1 <pid> 5.logstash 会重 ...