STM32L051测试 (三、I2C协议设备的添加测试)

2023-10-28

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

本系列博文目录:

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 bits
	u8Bit = 0x80;  //msb first  
	while(u8Bit) {
		if(u8Data&u8Bit) { 
			sda_high();
			delay_us(20);
		} 
		//& compare every bit
		else{ 
			sda_low();
			delay_us(20);
		}			
		scl_high();
		delay_us(30);
		u8Bit >>= 1; 
		//next bit
		scl_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 SCSEDIO0
	delay_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 first
	u8Data = 0;
	while(u8Bit){
		scl_high();
		
		delay_us(20);
	
		u8Bit >>= 1;    //next bit
		u8Data <<= 1;
	
		u8Data |= sda_read();         //(sda_port & sda_pin)? 1 :0      sda_port gpio0   sda_pin SCSEDIO0
		delay_us(20);
	
		scl_low();
		delay_us(50);
    }
	// 9th bit acknowledge
	if(u8Ack==I2C_ACK) {
		sda_low();
		delay_us(20);
	}     
	//I2C_ACK=0
	else {
		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              1

void 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读写操作是怎么实现的,明天我们拭目以待!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • HAL 锁定和解锁函数如何使用以及为什么?

    我试图理解另一位程序员编写的代码 它使用了I C http en wikipedia org wiki I C2 B2C通信以将数据写入 STM32 微控制器的 EEPROM 一般来说 我理解他的代码是如何工作的 但我不明白他为什么使用HA
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐

  • SpringBoot对接支付宝当面付和手机网站支付

    一 前期准备 1 注册商家账号 支付宝 2 登录进入 在产品中心选择自己所需要对接的功能 3 进入对接功能 选择立即开通 4 填写商户信息 5 开通成功之后 产品中心 gt gt 开发设置 gt gt 创建应用并关联 进行应用创建 6 应用
  • Kubernetes 弹性伸缩全场景解析(三) - HPA 实践手册

    在上一篇文章中 给大家介绍和剖析了 HPA 的实现原理以及演进的思路与历程 本文我们将会为大家讲解如何使用 HPA 以及一些需要注意的细节 autoscaling v1 实践 v1 的模板可能是大家平时见到最多的也是最简单的 v1 版本的
  • 【Audio音频兴趣拓展】Pop音的几种原因及解决方案

    1 硬件贴片错误可能会导致pop音 比如两个输入电容的容值相差过大 一个33nf 一个1uf 这时在播放音乐的开始阶段可能会发生POP音 2 时序控制不合理也会导致POP音 正确的时序应该为 开启时 先开启BB音源 delay 20 30m
  • idea之热部署插件jrebel的使用

    背景 一个java web项目 在写的过程中我们需要不断调试 如果没有热部署 则我们每修改一次项目要重启一次 验证问题有没有得到解决 如果项目很小 启动只要几秒或十几秒 可能感觉影响不是很大 但当项目变大了 重启一次需要几十秒 几分钟 甚至
  • 利用python进行数据分析,学习笔记1(numpy) ndarray的创建与修改

    我是通过学习mooc上嵩天老师的数据分析与展示和阅读 利用python进行数据分析 做出的笔记 import numpy as np 为了缩小代码量 公认约定使用np作为numpy from numpy import 往往实不可取的 因为它
  • Ubuntu时间显示不准确的解决方案

    参考 解决ubuntu里面时间不正确的办法 作者 三速何时sub20 发布时间 2020 12 08 16 24 27 网址 https blog csdn net weixin 44234294 article details 11087
  • Android 图片拖拽、放大缩小的自定义控件

    需求 像相册中的图片跟随手指拖动 双指的放大和缩小 相册中拖出范围之后有弹回的动画 感觉上很圆润 很舒服 我写的例子中并没有加动画 思路 1 自定义DragImageView java 2 自定义中先画图片 图片大于屏幕就把图片缩小后显示
  • [HCTF 2018]admin

    HCTF 2018 admin 一开始发现两个页面 登录页面和注册页面 页面源码说的意思应该是需要admin登录 二话不说 先用 top3000 跑了一下 发现没作用 可能不是考弱口令 看抓包的数据 也不是考xxe 没啥思路了 看看网上说的
  • 本地及远程rsync同步

    问题 本案例要求通过rsync命令工具来完成本地 远程同步操作 了解增量同步的效果 相关命令选项的用途 需要完成的配置任务如下 测试rsync上传 下载同步的基本用法 测试rsync的命令选项 a v delete n的用途 使用rsync
  • 安卓逆向一分钟app脱壳

    免责声明 做视频的初衷是为了学习交流 是想让自己在分享过程中学习到更多的东西 所发布的视频 环境 软件 脚本 文章 资料等 都是为了 粉丝们群友们能够更好的去理解安全测试的知识点 本人发布的视频 环境 软件 脚本 文章 资料等 都只用于学习
  • 如何用python开发app —— 前言

    来了 听说你要学用python开发app的本事 算你来对地方了 我这里有两种 一种是36般变化 一种是72般变化 你要学哪种 哈哈 闲话不多说 直接进入主题 首先说明 笔者 喝卤小夫 本篇文章不是教你具体的制作步骤 具体的步骤请参阅其它博文
  • python DataFrame获取行数、列数、索引及第几行第几列的值

    1 df DataFrame A 11 B 12 A 111 B 121 A 1111 B 1211 print df columns size 列数 2 print df iloc 0 size 行数 3 print df ix 0 in
  • 获取x-sign/x-mini-wua/x-sgext/x-umt

    文章目录 获取x sign x mini wua x sgext x umt 获取应用上下文 获取Mtop 获取MtopConfig 从MtopConfig获得sign对象 创建参数并调用 获取x sign x mini wua x sge
  • Redis第十二讲 Redis之zset底层数据结构实现

    zset zset中的每个元素包含数据本身和一个对应的分数 score ZSet 为有序的 自动去重的集合数据类型 ZSet 数据结构底层实现为 ziplist 或跳表 skiplist zset的数据本身不允许重复 但是score允许重复
  • 【报错】No module named ‘imutils‘

    1 No module named imutils imutils是整合了opencv numpy和matplotlib的相关操作的一个python工具包 主要是用来进行图形图像的处理等等 后又加入了针对视频的处理等 imutils同时支持
  • 从零实现DevOps(一):Centos7安装gitlab详解

    从今日起 开始更新 从零实现DevOps 系列 内容丰富且完整 预计内容包括Gitlab安装 环境变量配置 Jenkins安装和配置 本地 远程 部署单体项目 本地 远程 部署Vue项目 本地 远程 部署微服务项目等 希望能帮助大家 在技术
  • 物美智能系统

    物美智能系统 项目介绍 物美智能 wumei smart 是一个简单易用的生活物联网平台 可用于搭建物联网平台以及二次开发和学习 设备接入使用EMQX消息服务器 加密认证 后端采用Spring boot 前端采用Vue 移动端采用Uniap
  • VBA-读取文件的几种方法用时对比

    不同方法的其他优劣可以参考其余文档 本文仅对比用时 并且由于文件以其他方式读取过会影响下次读取速度 本次结果仅供参考 本人小白 欢迎指正 方法 用时 s 备注 workbook open 0 14 0 39 execut Excel 1 5
  • R语言生存数据进行中介分析(2)--手动推导cox回归中介分析

    中介变量 mediator 是一个重要的统计概念 如果自变量 X 通过某一变量 M 对因变量 Y 产生一定影响 则称 M 为 X 和 Y 的中介变量 目前国内外研究大部分都借鉴因果逐步回归法检验 因果步骤法由 Baron 和 Kenny 1
  • STM32L051测试 (三、I2C协议设备的添加测试)

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