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协议设备的添加测试) 的相关文章

  • STM32在Debug时程序运行时间不对,Debug时定时器中断每次进入断点时间不对,定时器一开启就进入中断的解决办法

    一 Debug时程序时间不对解决办法 1 点击魔术棒 2 点击Debug 点击Settings 3 点击Trace 在Core Clock里修改为你的系统时钟 二 Debug时定时器中断每次进入断点时间不对 在Debug时 程序停下来 定时
  • 处理器指令周期执行时间

    我的猜测是 no operation 内在 ARM 指令应花费 1 168 MHz 来执行 前提是每个NOP在一个时钟周期内执行 我想通过文档验证这一点 有关处理器指令周期执行时间的信息是否有标准位置 我试图确定 STM32f407IGh6
  • 以字符串形式接收数字(uart)

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

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了
  • 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
  • STM32超声波——HC_SR04

    文章目录 一 超声波图片 二 时序图 三 超声波流程 四 单位换算 五 取余计算 六 换算距离 七 超声波代码 一 超声波图片 测量距离 2cm 400cm 二 时序图 1 以下时序图要先提供一个至少10us的脉冲触发信号 告诉单片机我准备
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 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的代码优化一下 目