前面两篇文章,把L051基本功能都测试过了,确实感觉到ST的CubeMX工具真是好用,
对应换芯片的应用来说,着实方便,底层库封装好,上层应用程序基本都一样~~
今天我们就来把 I2C 设备添加一下,今天正好借这个机会,把I2C的代码优化一下。

目录

  • 1、CubeMX IO口的设置
  • 2、HAL库中的us延时函数
  • 3、移植I2C代码
    • 3.1 SHT21温湿度传感器
    • 3.1 欧姆龙红外测温D6T系列传感器

本系列博文目录:

STM32L051测试 (一、使用CubeMX生成工程文件 — ST系列芯片通用)
STM32L051测试 (二、开始添加需要的代码)

1、CubeMX IO口的设置

模拟I2C的IO口都设置为开漏输出,因为电路图上有外部上拉。
初始化的时候,2个SDA和SCL都得拉高。所以设置如下:

2、HAL库中的us延时函数

在HAL库中,只有ms的延时函数HAL_Delay,没有us的延时函数,今天用了网上一个延时函数,发现有问题,搞得整个时钟出了问题,郁闷,折腾了一下午。

时间浪费了,通讯模块那边因为这个时钟设置也出了点问题,一直返回复位信息,用了怎么多年的芯片还第一次遇到,Enocean 的TCM310模块,主要这个技术支持也不太好找。
= =!

还是快速找一个us函数,不是那么精确也可以,直接用空语句测试,后面已经经过测试,下面这个函数做的us延时可以正常移植以前的I2C程序。

/* USER CODE BEGIN 4 */
void delay_us(uint32_t Delay)
{uint32_t cnt = Delay * 8;  uint32_t i = 0;for(i = 0; i < cnt; i++)__NOP();
}
/* USER CODE END 4 */

3、移植I2C代码

3.1 SHT21温湿度传感器

代码移植没什么问题,

i2c.c:

#include "i2c.h"// ------------------------------------------------------------------
void i2c_init(void)  {// the SDA and SCL pins are defined as input with pull up enabled// pins are initialized as inputs, ext. pull => SDA and SCL = high}
// ------------------------------------------------------------------
// send start sequence (S)void i2c_start(void)  {                                    sda_high(); delay_us(10);scl_high();       delay_us(10);sda_low(); delay_us(10);scl_low();                                                   delay_us(10);
}
// ------------------------------------------------------------------
// send stop sequence (P)
void i2c_stop(void)  {                             sda_low();                                                                          delay_us(10);scl_low();                                       delay_us(10);                                 scl_high();                                         delay_us(10);                                       sda_high();delay_us(10);
}
// ------------------------------------------------------------------
// returns the ACK or NACK
uint8 i2c_write(uint8 u8Data)
{uint8 u8Bit;uint8 u8AckBit;// write 8 data bitsu8Bit = 0x80;  //msb first  while(u8Bit) {if(u8Data&u8Bit) { sda_high();delay_us(20);} //& compare every bitelse{ sda_low();delay_us(20);}         scl_high();delay_us(30);u8Bit >>= 1; //next bitscl_low();delay_us(30);}// read acknowledge (9th bit) sda_high();                                               delay_us(10);     scl_high();delay_us(10);u8AckBit= sda_read();  //#define sda_read()  (sda_port & sda_pin)? 1 :0  ack on bus is low -> u8AckBit = 1   sda_port gpio0   sda_pin SCSEDIO0delay_us(10);scl_low();                                              delay_us(10);return u8AckBit;
}
// ------------------------------------------------------------------
// pass the ack/nack
// returns the read data
uint8 i2c_read(uint8 u8Ack)
{uint8 u8Bit;uint8 u8Data;u8Bit = 0x80;       // msb firstu8Data = 0;while(u8Bit){scl_high();delay_us(20);u8Bit >>= 1;    //next bitu8Data <<= 1;u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0delay_us(20);scl_low();delay_us(50);}// 9th bit acknowledgeif(u8Ack==I2C_ACK) {sda_low();delay_us(20);}     //I2C_ACK=0else {sda_high();delay_us(20);}scl_high();delay_us(20);scl_low();delay_us(20);sda_high();delay_us(20);                                 return u8Data;
}

i2c.h:

#ifndef _I2C_H_INCLUDED
#define _I2C_H_INCLUDED#include "main.h"
#include "Datadef.h"// #define I2C_CLK_HIGH()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
// #define I2C_CLK_LOW()    HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);// #define I2C_DATA_HIGH()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
// #define I2C_DATA_LOW()    HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
// #define I2C_DATA_STATE()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET); // #define sda_high()  I2C_DATA_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
// #define sda_low()   I2C_DATA_LOW()
// #define sda_read()  I2C_DATA_STATE()    //ack on bus is low -> u8AckBit = 1// #define scl_high()  I2C_CLK_HIGH()     // set signals to HIGH first before selecting IN -> slew rates
// #define scl_low()   I2C_CLK_LOW() #define sda_high()  HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_SET);
#define sda_low()   HAL_GPIO_WritePin(sht_sda_GPIO_Port,sht_sda_Pin,GPIO_PIN_RESET);
#define sda_read()  (HAL_GPIO_ReadPin(sht_sda_GPIO_Port,sht_sda_Pin) == GPIO_PIN_SET);#define scl_high()  HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_SET);
#define scl_low()   HAL_GPIO_WritePin(sht_scl_GPIO_Port,sht_scl_Pin,GPIO_PIN_RESET);// ------------------------
#define DONOTHING()          {;}// ------------------------
// command's
#define I2C_WRITE             0
#define I2C_READ              1
#define I2C_ACK               0
#define I2C_NACK              1void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
uint8 i2c_write(uint8 u8Data);
uint8 i2c_read(uint8 u8Ack);#endif

SHT21部分的驱动就不用怎么修改了,基本上直接拿过来,把ms延时函数替换一下,就直接用,这里就不贴出来

测试结果:


板载的HTU21D,实际测试下来,一直会比空气问题高一点,这个问题,我倒是有点头疼,虽然做过分割,不铺铜等一些处理,还是不尽如人意。

3.1 欧姆龙红外测温D6T系列传感器

其实有了上面的成功案例,这个也不是什么问题,还是老样子,定义好IO口,写好驱动逻辑,主要是因为板子上接口还没焊接,明天再试试,再接着补充一下。

在后期的测试其他文章中,这个传感器的 I2C 驱动其实已经写好了,可以参考我的博文:
FreeRTOS记录(十、FreeRTOS实现带 I2C 通讯的 ModbusRTU 协议从机实例)

完成了这几个工作,下面一篇文章应该会学习L051 的 flash读写操作,因为项目中总得有一些设置需要掉线不丢失的,以前F103都是直接保存在内部flash中,L051的flash读写操作是怎么实现的,明天我们拭目以待!

STM32L051测试 (三、I2C协议设备的添加测试)相关推荐

  1. OPEN ALLIANCE TC2和TC9线束以太网测试标准?何种设备可以满足测试?除了矢量网分之外

    OPEN ALLIANCE TC2和TC9线束以太网测试标准? 联盟中TC2汽车线束以太网线束定义标准: 100BASE-T1 Ethernet Channel & Components 10 ...

  2. Aurora 8B/10B、PCIe 2.0、SRIO 2.0三种协议比较

    在高性能雷达信号处理机研制中,高速串行总线正逐步取代并行总线.业界广泛使用的Xilinx公司Virtex-6系列FPGA支持多种高速串行通信协议,本文针对其中较为常用的Aurora 8B/10B和PC ...

  3. xboxone硬盘坏的表现_你的机械硬盘有RV振动传感器吗?三款2.5寸HDD测试

    机械硬盘人人都用,虽然SSD的价格逐年下降,可是就容量/价格比来说,离机械硬盘还有不少距离.尽管HDD有着大容量的优势,可是如今硬盘存储密度越来越高,磁头距离盘片太近,现在的硬盘也越来越脆弱,经常能见 ...

  4. 宇视录像机多种协议添加摄像机(只介绍常用的宇视、onvif、GB28181三种协议)

    一种协议:相机宇视协议添加至宇视录像机 IPV4地址:相机地址 端口:80 用户名:admin 密码:摄像机admin登录web界面的密码(此处的用户名.密码是摄像机的参数不是录像机的用户名.密码) ...

  5. 第三章 rt-thread设备驱动模型-i2c驱动

    rt-thread设备驱动模型-i2c驱动 1. 回顾 前面两章分别介绍了rt-thread设备驱动框架的实现原理,以及介绍了一个简单的看门狗驱动程序,用来加深对驱动框架的理解.看门狗驱动程序最终归纳 ...

  6. 【linux iic子系统】i2c设备的添加方法(四)

    文章目录 前言 一.静态注册 二.动态注册 三.用户空间注册 四.i2c驱动扫描注册 前言 I2C设备的4种添加方法: 1)静态注册 2)动态注册 3)用户空间注册 4)i2c驱动扫描注册 一.静态注 ...

  7. 海思Hi3531A芯片设备添加测试UART1-3

    Hi3531A芯片共有四个uart单元,uart0是调试串口默认是打开的,uart1-3需要重新配置.操作如下. 1.确定内核加载了串口uart驱动程序 可以参考 "hi3531 添加uar ...

  8. STM32CubeIDE开发(十六),I2C协议采集传感器数据(SHTC1、LTR-553ALS、BMP280、LSM6DSL、MMC3680KJ)

    目录 一.I2C总线协议 二.I2C协议的两种从机应对方式 三.传感器信息 四.工程创建及引脚配置 五.STCH1传感器实现 六.LTR_553ALS传感器(light sensor [ALS] an ...

  9. I2C协议详解 (Based Philips I2C spec)

    前言 Version 1.0 - 1992 此版本的 1992 I2C 总线规范包括以下修改: 省略了软件对从地址的编程. 这个功能的实现比较复杂,没有使用过. 省略了"低速模式" ...

  10. 基于I2C协议利用STM32进行温湿度传感器的数据采集

    目录 一.I2C总线通信协议的介绍 1.I2C简介 2.I2C总线时序图 3.五种速率 4.四种信号 5.I2C的优缺点 6.软件IIC和硬件IIC 二.创建工程 1.实验目的 2.工具的选择 3.相 ...

最新文章

  1. 极虎病毒创造四个“之最”
  2. ubuntu中使用VsCode+Eigen创建Eiegn应用程序
  3. 数学建模——TOPSIS综合评价模型Python代码
  4. 加油python_力扣——gas station (加油站) python实现
  5. C++学习笔记之对文件的操作1
  6. 【软件开发底层知识修炼】二十八 C/C++中volatile的作用
  7. 装入归档文件时出现了一个错误linux_静态链接与动态链接(Linux)
  8. 解决Error: That port is already in use.
  9. 如何在 Mac、iphone 中快速清除已完成的提醒?
  10. 主板bios修改、刷新
  11. 什么叫操作系统啊 | 战术后仰
  12. python问题 Traceback (most recent call last)
  13. 谷歌支付 googleplay API权限相关设置
  14. 删除电脑上重复备份的图片
  15. linux中的文件夹压缩文件,linux将文件拷贝到目录下Linux下文件的压缩与打包详解...
  16. 品味30句对爱情的经典认识
  17. oracle成批事务处理,Oracle EBS OPM 生产批创建事务处理
  18. 408计算机组成原理大题方向,2019考研408计算机组成原理选择题及答案(36)
  19. autodesk系列产品无法安装解决方案
  20. 【应用安全】什么是联合身份管理?

热门文章

  1. 久贺谷亮《高效休息法》读书笔记
  2. 分享收集网络上的免费0元虚拟主机
  3. Android rom开发:recovery取消校验Vbmeta version和framework matrix
  4. 世界的是非对错,永远都是强者说的算!
  5. 2021年最新微博移动版网页链接自动跳转pc版网页链接软件【私信版】
  6. 阿里云短信校验注册完整版
  7. 不爱,就收起暧昧走开...
  8. oracle10g 数据库导入dmp数据
  9. 关闭防火墙步骤(详细)
  10. 微信小程序:微擎开发飞鹅打印机配置