STM32F103C8T6使用MLX90614模块

首先说明:

1.SMBus和I2C的区别

        我曾尝试用江科大的I2C底层去直接读取该模块,但是无法成功,之后AI生成的的代码也无法成功。

        思来想去最大的可能就是SMBus这个协议的问题,根据百度得到的结果如下:

SMBus和I2C的区别

链接:

smbus协议_百度百科https://baike.baidu.com/item/smbus%E5%8D%8F%E8%AE%AE/56360572.个人见解(希望有知道的可以补充说明或纠错):

        ①SMBus协议是I2C的pro版本,对时序要求更加严格。

        ②特别是在超时方面,I2C可能是在SCL的对应电平下改变SDA的电平,那就能正常操作,不在意时间多久;但SMBus则是要求了SCL在对应电平下,SDA应该在什么时候做出改变,否则超时。

               

代码:

以下是我用STM32F103C8T6能读取到我认为正常数据的代码,若不满足读者要求,请自行微调。

若对你有帮助,请点赞收藏~

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"//************** 宏定义 **************
#define I2C_SCL_PIN    GPIO_Pin_6
#define I2C_SDA_PIN    GPIO_Pin_7
#define I2C_GPIO_PORT  GPIOB#define Nack_counter   10
#define uint           unsigned int
#define uchar          unsigned char//************** 全局变量 **************
volatile uchar DataH, DataL, Pecreg;
volatile uint temp;
//************** 函数声明 **************
void I2C_GPIO_Init(void);
void start_bit(void);
void stop_bit(void);
void send_bit(uchar bit_val);
uchar rx_byte(void);
uchar tx_byte(uchar dat_byte);
void delay_us(uint us);
uint memread(void);//************** GPIO初始化 **************
void I2C_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  // 使能GPIOB时钟// SCL和SDA配置为开漏输出GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  // 开漏输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStructure);// 初始状态拉高GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN | I2C_SDA_PIN);
}//************** 延时函数(72MHz主频)**************
void delay_us(uint us) {us *= 72/5;  // 72MHz下1us需要72个周期(实测需校准)while(us--) {__NOP();}
}//************** I2C起始信号 **************
void start_bit(void) {GPIO_SetBits(I2C_GPIO_PORT, I2C_SDA_PIN);GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(5);  // 保持时间≥4.7usGPIO_ResetBits(I2C_GPIO_PORT, I2C_SDA_PIN);delay_us(5);GPIO_ResetBits(I2C_GPIO_PORT, I2C_SCL_PIN);
}//************** I2C停止信号 **************
void stop_bit(void) {GPIO_ResetBits(I2C_GPIO_PORT, I2C_SCL_PIN);GPIO_ResetBits(I2C_GPIO_PORT, I2C_SDA_PIN);delay_us(5);GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(5);GPIO_SetBits(I2C_GPIO_PORT, I2C_SDA_PIN);
}//************** 发送单bit **************
void send_bit(uchar bit_val) {if(bit_val) {GPIO_SetBits(I2C_GPIO_PORT, I2C_SDA_PIN);} else {GPIO_ResetBits(I2C_GPIO_PORT, I2C_SDA_PIN);}delay_us(2);GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(5);  // SCL高电平≥4.0usGPIO_ResetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(2);
}//************** 接收单bit **************
uchar receive_bit(void) {uchar bit_val;GPIO_SetBits(I2C_GPIO_PORT, I2C_SDA_PIN);  // 释放SDA线delay_us(2);GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(5);bit_val = GPIO_ReadInputDataBit(I2C_GPIO_PORT, I2C_SDA_PIN);GPIO_ResetBits(I2C_GPIO_PORT, I2C_SCL_PIN);delay_us(2);return bit_val;
}//************** 发送单字节 **************
//void tx_byte(uchar dat_byte) {
//    uchar i, n = Nack_counter;
//    
//TX_again:
//    for(i = 0; i < 8; i++) {
//        send_bit((dat_byte & 0x80) ? 1 : 0);
//        dat_byte <<= 1;
//    }
//    
//    if(receive_bit()) {  // 检测NACK
//        stop_bit();
//        if(n--) {
//            start_bit();
//            goto TX_again;
//        }
//    }
//}uchar tx_byte(uchar dat_byte)
{for(uchar i = 0; i < 8; i++) {send_bit((dat_byte & 0x80) ? 1 : 0);dat_byte <<= 1;}return !receive_bit();  // 返回1=ACK, 0=NACK
}//************** 接收单字节 **************
uchar rx_byte(void) {uchar i, dat = 0;for(i = 0; i < 8; i++) {dat <<= 1;if(receive_bit()) dat |= 0x01;}send_bit(0);  // 发送ACKreturn dat;
}//************** 读取温度数据 **************
//uint memread(void) {
//    start_bit();
//    tx_byte(0x00);  // MLX90614地址+写
//    tx_byte(0x07);  // 读取RAM命令
//    
//    start_bit();
//    tx_byte(0xB5);  // MLX90614地址+读
//    
//    DataL = rx_byte();
//    DataH = rx_byte();
//    Pecreg = rx_byte();
//    
//    stop_bit();
//    return (DataH << 8) | DataL;
//}
uint memread(void) {start_bit();if (!tx_byte(0xB4)) {  // 发送地址+写stop_bit();return 0xFFFF;}if (!tx_byte(0x07)) {  // 发送命令(读取RAM)stop_bit();return 0xFFFF;}start_bit();if (!tx_byte(0xB5)) {  // 发送地址+读stop_bit();return 0xFFFF;}DataL = rx_byte();  // 低字节DataH = rx_byte();  // 高字节Pecreg = rx_byte(); // PEC(可选)stop_bit();return ((DataH << 8) | DataL)*0.02 - 273.15;
}//************** 主函数 **************
int main(void) {SystemInit();  // 系统时钟配置为72MHzI2C_GPIO_Init();while(1) {temp = memread();// 此处添加温度处理代码delay_us(20000);  // 延时20ms}
}

使用方法:

①直接copy到自己的main.c

②下载到STM32F103C8T6板子上,并保持连接。根据下面代码接线,供电3.3V

#define I2C_SCL_PIN    GPIO_Pin_6
#define I2C_SDA_PIN    GPIO_Pin_7
#define I2C_GPIO_PORT  GPIOB

③使用debug模式查看数据,具体如下:

若点击运行后temp数据不变,则需要进行下面这一步:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tp5 php获取农历年月日干支甲午

# 切换为国内镜像源 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/# 再次尝试安装 composer require overtrue/chinese-calendar核心写法一个农历转公历&#xff0c;一个公历转农历 农历闰月可能被错误标记&#xff08;例如 闰四月 应表示…

Ubuntu搭建Conda+Python开发环境

目录 一、环境说明 1、测试环境为ubuntu24.04.1 2、更新系统环境 3、安装wget工具 4、下载miniconda安装脚本 二、安装步骤 1、安装miniconda 2、source conda 3、验证版本 4、配置pip源 三、conda用法 1、常用指令 一、环境说明 1、测试环境为ubuntu24.04.1 2、更…

Vscode+git笔记

1.U是untracked m是modify modified修改了的。 2.check out 查看观察 3 status changed 暂存区 4.fetch v 取来拿来 5.orangion 起源代表远程分支 git checkout就是可以理解为进入的意思。

模拟SIP终端向Freeswitch注册用户

1、简介 使用go语言编写一个程序&#xff0c;模拟SIP-T58终端在Freeswitch上注册用户 2、思路 以客户端向服务端Freeswitch发起REGISTER请求&#xff0c;告知服务器当前的联系地址构造SIP REGISTER请求 创建UDP连接&#xff0c;连接到Freeswitch的5060端口发送初始的REGISTER请…

DeepSeek实战--LLM微调

1.为什么是微调 &#xff1f; 微调LLM&#xff08;Fine-tuning Large Language Models&#xff09; 是指基于预训练好的大型语言模型&#xff08;如GPT、LLaMA、PaLM等&#xff09;&#xff0c;通过特定领域或任务的数据进一步训练&#xff0c;使其适应具体需求的过程。它是将…

Docker与WSL2如何清理

文章目录 Docker与WSL2如何清理一、docker占据磁盘空间核心原因分析1. WSL2 虚拟磁盘的动态扩展特性2. Docker 镜像分层缓存与未清理资源 二、解决方案步骤 1&#xff1a;清理 Docker 未使用的资源步骤 2&#xff1a;手动压缩 WSL2 虚拟磁盘1. 关闭 WSL2 和 Docker Desktop2. 定…

在 IDEA 中写 Spark 程序:从入门到实践

在大数据处理领域&#xff0c;Apache Spark 凭借其出色的性能和丰富的功能受到广泛欢迎。而 IntelliJ IDEA 作为一款功能强大的 Java 集成开发环境&#xff0c;为编写 Spark 程序提供了极大的便利。本文将详细介绍如何在 IDEA 中搭建 Spark 开发环境并编写运行 Spark 程序&…

Unity 使用 ADB 实时查看手机运行性能

Unity 使用 ADB 实时查看手机运行性能 前言操作步骤ADB工具下载ADB工具配置手机进入开发者模式并开启USB调试使用ADB连接手机Unity打包设置使用Profiler实时查看性能情况优化建议 常见问题 前言 通过 ADB&#xff08;Android Debug Bridge&#xff09;连接安卓设备&#xff0c…

深入理解 HttpExchange_Java 中构建 HTTP 服务的基础组件

1. 引言 1.1 Java 中的轻量级 HTTP 服务需求 随着微服务、工具类应用和嵌入式系统的兴起,开发者对轻量级 HTTP 服务的需求日益增长。相比引入庞大的框架(如 Spring Boot),使用 JDK 原生 API 构建 HTTP 服务成为一种快速、低依赖的替代方案。 JDK 提供了 com.sun.net.htt…

【RocketMQ NameServer】- NameServer 启动源码

文章目录 1. 前言2. RocketMQ 通信架构3. NameServer 启动流程3.1 创建 NameServerController3.2 启动 NameServerController3.3 NamesrvController#initialize3.3.1 Netty 通信的整体流程3.3.2 创建 NettyRemotingServer 3.4 this.remotingServer.start()3.4.1 this.remotingS…

【算法题】荷兰国旗问题[力扣75题颜色分类] - JAVA

一、题目 二、文字解释 1.1 前言 本题是经典的「荷兰国旗问题」&#xff0c;由计算机科学家 Edsger W. Dijkstra 首先提出。如同图中所示的荷兰国旗&#xff0c;其由红、白、蓝三色水平排列组成。在算法领域&#xff0c;该问题可类比为将一个由特定的三种元素&#xff08;可抽…

MySQL数据操作全攻略:DML增删改与DQL高级查询实战指南

知识点4【MySQL的DDL】 DDL&#xff1a;主要管理数据库、表、列等操作。 库→表&#xff08;二维&#xff09;→列&#xff08;一维&#xff09; 数据表的第一行是 列名称 数据库是由一张或多张表组成 我们先学习在数据库中创建数据表 0、常见的数据类型&#xff1a; 1、…

AtCoder AT_abc404_g [ABC404G] Specified Range Sums

前言 赛时想到了差分约束&#xff0c;随手写了个 SPFA 结果挂的很惨……还是太菜了&#xff0c;赛后 Bellman-Ford 又调了半天。 题目大意 给定整数 N , M N,M N,M 和长度为 M M M 的三个整数序列 L ( L 1 , L 2 , … , L M ) , R ( R 1 , R 2 , … , R M ) , S ( S 1…

如何基于HAL库进行STM32开发

一、初识HAL库 STM32 开发中常说的 HAL 库开发&#xff0c;指的是利用 HAL 库固件包里封装好的 C 语言编写的驱动文件&#xff0c;来实现对 STM32 内部和外围设备的控制。但只有 HAL 库还不能直接驱动一个 STM32 的芯片&#xff0c;其它的组件已经由 ARM 与众多芯片硬件、软件厂…

Qt:(创建项目)

目录 1. 使⽤QtCreator新建项⽬ 1.1 新建项⽬ 1.2 选择项⽬模板 1.3 选择项⽬路径 1.4 选择构建系统 1.5 填写类信息设置界⾯ ​编辑 1.6 选择语⾔和翻译⽂件 1.6 选择Qt套件 1.7 选择版本控制系统 1.8 最终效果 1. 使⽤QtCreator新建项⽬ 1.1 新建项⽬ 打开Qt…

WPF之Slider控件详解

文章目录 1. 概述2. 基本属性2.1 值范围属性2.2 滑动步长属性2.3 刻度显示属性2.4 方向属性2.5 选择范围属性 3. 事件处理3.1 值变化事件3.2 滑块拖动事件 4. 样式和模板自定义4.1 基本样式设置4.2 控件模板自定义 5. 数据绑定5.1 绑定到ViewModel5.2 同步多个控件 6. 实际应用…

mysql索引及数据库引擎

顺序io&#xff08;不需要每次都磁盘寻址&#xff0c;效率高&#xff09;&#xff0c;随机io&#xff08;需要每次都磁盘寻址&#xff0c;效率低&#xff09; 如何正确的创建合适的索引&#xff1f; 索引是一种分散存储的数据结构 磁盘io特性&#xff1a;每次交互是以页为单位&…

网络安全:sql注入练习靶场——sqli_labs安装保姆级教程

网络安全&#xff1a;sql注入练习靶场——sqli_labs安装保姆级教程 前言 sqli-labs靶场是一个开源的sql注入练习的综合靶场&#xff0c;包含大部分sql注入漏洞以及注入方式 网络安全学习者可以通过在sqli-labs靶场练习提升对sql注入的理解&#xff0c;以及学习各种绕过姿势。…

平台介绍-开放API接口-鉴权

平台的理念是一个组织内部只建一套系统。但是现实情况是&#xff0c;组织内部已经建立了很多系统&#xff0c;是不能一次性替代的&#xff0c;只能先搭起平台&#xff0c;然后逐步开始替换。这样就不可避免的存在其他系统和平台进行交互的问题。 平台为此设计了开放API接口。其…

多端定制系统开发:打造高效全平台覆盖的APP解决方案

在移动互联网时代&#xff0c;用户需求日益多样化&#xff0c;企业若想触达更广泛的受众&#xff0c;仅靠单一平台的应用已远远不够。无论是iOS、Android、Web端&#xff0c;还是智能手表、车载设备等新兴终端&#xff0c;多端适配已成为企业数字化转型的刚需。多端定制系统开发…