七、I2C通信读取LM75B温度

news2025/4/22 11:27:57

7.1 概述

I2C(Inter-Integrated Circuit)是一种同步、多主从、串行通信协议,由飞利浦公司开发,主要用于短距离通信,尤其在集成电路之间。

7.1.1 主要特点

两线制:仅需SDA(数据线)和SCL(时钟线)两根线。

多主从结构:支持多个主设备和从设备。

地址寻址:每个从设备有唯一地址,主设备通过地址选择通信对象。

低速到中速:标准模式100 kbps,快速模式400 kbps,高速模式3.4 Mbps。

7.1.2 通信过程

I²C 总线可以连接多个从设备,每个从设备都有一个唯一的地址(7 位或 10 位)。

主设备通过发送从设备地址来选择与之通信的从设备。

当主设备发送从设备地址时,从设备会将自己的地址与接收到的地址进行比较。

如果地址匹配,从设备会响应主设备并参与后续通信;如果不匹配,从设备会忽略通信。

        主机发送起始信号拉低总线,然后再发送一个字节来指明跟哪个从机通信(从机地址)以及通信的方向(主机收信息还是主机发信息),然后被寻址的从机发送应答信号回应主机,之后就开始发收了,主发从收,或者从收主发,发送器发一个,接收器应答一下。在发送完后,主机发送停止信号释放总线。

起始条件:SCL高电平时,SDA从高到低跳变。

地址传输:主设备发送7位或10位从设备地址和读写位。

数据传输:每8位数据后跟一个ACK/NACK确认位,即9位。

停止条件:SCL高电平时,SDA从低到高跳变。

在发送过程中,数据只在SCL为高电平时发送,每一个SCL的高电平发送一位(位数高到低),除了起始和停止信号,在数据传输期间,SCL为高电平时,SDA必须保持稳定,不允许改变,在SCL低电平时才可以进行变化。

发送器发8个信号,接收器应答一下,应答为低电平,非应答高电平,可能没收到,或者不收了

7.2 引脚及温度传感器介绍

7.2.1 SCL、SDA

        如下图左边,SCL对应CPU引脚为PIO0_4, SDA对应CPU引脚为PIO0_5。

7.2.2 LM75B温度传感器

将测量到的温度通过数据线发出,发两次,高8位,低8位,拼接起来就行

7.3 寄存器

7.3.1 控制置位寄存器 I2C0CONSET

        通过写1使相应位置位,写0无效

符号描述
1:0保留
2AA声明应答标志,为0返回非应答信号
3SII2C中断标志,I2C状态改变时SI置位
4STO

停止标志,总线检测到停止条件自动清零

主模式下发送停止条件

从模式下从错误状态中恢复

5STA开始标志,进入主模式,发送起始条件或重复起始条件
6I2EN接口使能
7保留

7.3.2 I2C控制清零寄存器 I2C0CONCLR

        写1将I2C0CONSET中的寄存器相应位清零

符号描述
1:0保留
2AAC声明应答清零
3SIC中断清零
4

保留

5STACSTART标志位清零
6I2ENC接口禁能
7保留

7.3.3 状态寄存器 I2C0STAT

        只读寄存器。 [7:3]位存状态码,0xF8时SI不置位,其他状态码对应一个I2C状态,这些状态对应其中任一状态时,SI置位。

7.3.4 数据寄存器 I2C0DAT

        包含要发送的数据或刚接收的数据。收发都是从右向左移位,先高位7MSB,再低位

        [7:0]存已接收或将要发送的数据值

7.3.5 监控模式寄存器 I2C0MMCTRL

在I2C总线的监控模式下,设备可以监视I2C总线上正在进行的所有通信活动,包括读取数据、写入数据等,但不会对总线进行控制。

1有效
0MM_ENA

监控模式使能

SDA输出被强制为高电平,防止I2C模块向总线输出数据

1ENA_SCL

SCL输出使能

模块可以与正常操作中相同方式控制时钟线

可以使得有足够时间相应I2C中断

3MATCHALL

选择中断寄存器匹配

0:只有在4个地址寄存器中的一个出现匹配才产生中断

1:可在任意接收地址上产生中断,监控总线上所有通信

7.3.6 数据缓冲寄存器 I2C0DATABUFFER

[7:0]位保存I2C0DAT数据寄存器中高8位内容

在监控模式下,ENA_SCL不置位,则I2C模块不能控制时钟线,接收数据的时间有限,I2C0DAT中老内容会被覆盖,为使处理器有更多时间相应,就在总线每接收9位(8位数据1位应答),就把高8位内容自动传输到DATABUFFER

7.3.7 从地址寄存器 I2C0ADR[0, 1, 2, 3]

        I2C从模式下可用,主模式无效

在 I²C 通信中,从地址寄存器(Slave Address Register)用于存储 I²C 从设备(Slave Device)的地址。这个地址是 I²C 主设备(Master Device)与从设备通信时的重要标识。

符号
0GC通用调用使能位,识别通用调用地址0x00
7:1地址从模式的I2C器件地址,若值为0x00,则总线上任意地址匹配(课本上不与好像错了)

7.3.8 屏蔽寄存器 I2C0MASK[0, 1, 2, 3]

        进行地址匹配时会把屏蔽寄存器中的地址忽略,也就是我如果是从机,我屏蔽了我的地址I2C0ADR,那么我就当没有这个地址,主机匹配这个地址时匹配不到我

四个屏蔽寄存器各包含7个有效位[7:1] 

        通用调用地址0x00无法屏蔽,因为默认就是屏蔽这个地址,有违通用调用之名

7.3.9 高电平占空比寄存器,低电平占空比寄存器 I2C0SCLH,I2C0SCLL

I2C时钟不分频就是系统时钟 48MHz 标准480 快速120 快速plus48

I2C0SCLH,I2C0SCLL值可以随便取,但是单个值必须大于等于4

7.4 获取温度

        获取LM75中的温度

照样,移植上次的UART工程,修改代码如下

main.c

#include <LPC11xx.h>
#include "LED.h"
#include "Button.h"
#include "TIMER.h"
#include "UART.h"
#include "string.h"
#include "I2C.h"
char buf[7];

void Get_temputerature(void);
int32_t Temputerature_Test(void);

int main(void)
{
	LED_Init();
    LED_ON();
    UART_Init();
    I2CInit();
	
	// 定义要发送的数据
    char message[] = "Hello, world!";

    // 计算数据长度,不包括结束符 '\0'
    int length = strlen(message);
	// 调用UART_Send函数发送数据
    UART_Send(message, length);	
	
	//发送换行
	UART_Send_Bit(0x0d);
	UART_Send_Bit(0x0a);
	
    while (1)
    {
		Get_temputerature();
		UART_Send("Temputerature = ",16);
		UART_Send(buf,7);  //发送温度到pc
		UART_Send_Bit('C');
		delay_ms(1000);
    }
}


/*
*********************************************************************************************************
*	函 数 名: Temputerature_Test()
*	功能说明: 读取温度数据
*	形    参:无
*	返 回 值: 温度值*1000的整数值
*********************************************************************************************************
*/
int32_t Temputerature_Test(void)
{
	uint16_t Temputerature_8,Temputerature_16;
	float Temputerature;
	I2C_Start();//start
	I2C_Send_Byte(0x91);//读
	LPC_I2C->CONSET =(1<<2);//AA=1
	Temputerature_8=I2C_Recieve_Byte();//高八位
	LPC_I2C->CONCLR =(1<<2);//AA=0
	Temputerature_16=(Temputerature_8<<8)+I2C_Recieve_Byte();//合成温度
	I2C_Stop();//STOP
	//温度转换
	Temputerature_16=Temputerature_16>>5;
	if(Temputerature_16&0x0400)
	{
		Temputerature=-(~(Temputerature_16&0x03ff)+1)*0.125;
	}else
	{
		Temputerature=0.125*(float)(Temputerature_16);
	}
	return (int32_t)(Temputerature*1000);
}

/*
*********************************************************************************************************
*	函 数 名: Get_temputerature()
*	功能说明: 温度数据转化为十进制
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void Get_temputerature(void)
{
	int32_t temp;
	temp=Temputerature_Test();//获得温度
	//将int 转为char 同时'0'对应00000000 对数值无影响
	buf[0]=temp/100000+'0';//
	if((temp/100000)==0) buf[0]=' ';//不显示0
	else if(temp < 0) buf[0] = '-'; // 小于零
	
	buf[1]=temp/10000%10+'0';
	buf[2]=temp/1000%10+'0';
	buf[3]='.';
	buf[4]=temp/100%10+'0';
	buf[5]=temp/10%10+'0';
	buf[6]=temp%10+'0';
}

I2C.c

#include "I2C.h"

/*
*********************************************************************************************************
*	函 数 名: I2CInit()
*	功能说明: I2C 初始化
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void I2CInit(void)
{
	LPC_SYSCON->PRESETCTRL |= (1<<1); //复位取消
	LPC_SYSCON->SYSAHBCLKCTRL |=(1<<5);//使能I2C
	LPC_SYSCON->SYSAHBCLKCTRL |=(1<<16);//使能IO配置块
	//选择快速模式
	LPC_IOCON->PIO0_4 &=~(0X3F); //选择快速模式
	LPC_IOCON->PIO0_4 |=0X01;//选择SCL
	LPC_IOCON->PIO0_5 &=~(0X3F); //选择快速模式
	LPC_IOCON->PIO0_5 |=0X01;//选择SDA
	//设置SCL频率为400kHZ
	LPC_I2C->SCLH=40;
	LPC_I2C->SCLL=80;
	//使能I2C 同时将其他控制位清0
	LPC_I2C->CONCLR=0XFF;     //清所有标志
	LPC_I2C->CONSET |=(1<<6);    //使能I2C接口
}


/*
*********************************************************************************************************
*	函 数 名: I2C_Start()
*	功能说明: 发送开始信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void I2C_Start(void)
{
	LPC_I2C->CONSET =(1<<5);// 发送开始信号 5位STA起始
	while(!(LPC_I2C->CONSET&(1<<3)));//等待开始信号发送完成 SI置位
	LPC_I2C->CONCLR =(1<<5|1<<3); //清零START 和SI 3位SI中断标志
}


/*
*********************************************************************************************************
*	函 数 名: I2C_Stop()
*	功能说明: 发送停止信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void I2C_Stop(void)
{
	LPC_I2C->CONCLR =(1<<3);
	LPC_I2C->CONSET =(1<<4);// 发送停止信号
	while((LPC_I2C->CONSET&(1<<4)));//等待停止信号发送完成 SI置位
}

/*
*********************************************************************************************************
*	函 数 名: I2C_Send_Byte(uint8_t data)
*	功能说明: 发送一个字节
*	形    参:data 1字节数据
*	返 回 值: 无
*********************************************************************************************************
*/
void I2C_Send_Byte(uint8_t data)
{
	LPC_I2C->DAT=data;
	LPC_I2C->CONCLR =(1<<3); //开始发送数据 清SI
	while(!(LPC_I2C->CONSET&(1<<3)));//等待数据发送完成 SI置位
}

/*
*********************************************************************************************************
*	函 数 名: I2C_Recieve_Byte()
*	功能说明: 接收一个字节
*	形    参:无
*	返 回 值: 一字节接收数据
*********************************************************************************************************
*/
uint8_t I2C_Recieve_Byte(void)
{
	LPC_I2C->CONCLR =(1<<3);//开始接受数据  清SI
	while(!(LPC_I2C->CONSET&(1<<3)));//等待接受数据完成 SI置位
	return (uint8_t)LPC_I2C->DAT;
}

I2C.h

#ifndef _I2C_H_
#define _I2C_H_

#include <LPC11xx.h>

void I2CInit(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Send_Byte(uint8_t data);
uint8_t I2C_Recieve_Byte(void);

#endif

打开串口,效果如下

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

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

相关文章

CSS 属性选择器详解与实战示例

CSS 属性选择器是 CSS 中非常强大且灵活的一类选择器&#xff0c;它能够根据 HTML 元素的属性和值来进行精准选中。在实际开发过程中&#xff0c;属性选择器不仅可以提高代码的可维护性&#xff0c;而且能够大大优化页面的样式控制。本文将结合菜鸟教程的示例&#xff0c;从基础…

2025 游戏试玩打码平台PHP源码

源码介绍 2025 游戏试玩打码平台PHP源码 开发语言&#xff1a;PHP 数据库&#xff1a;MySQL 源码程序采用yii框架phpMysql语言开发 功能完善&#xff0c;无后门 程序功能有: 1.游戏试玩功能 2.广告体验功能 3.打码功能 4.新人任务 5.开启宝箱功能 6.站长联盟功能 7.兑换商城功…

sql难点

一、 假设你有一个查询&#xff0c;需要根据 id 是否为 null 来动态生成 SQL 条件&#xff1a; xml复制 <select id"getResources" resultType"Resource">SELECT * FROM resources<where><if test"id ! null">and id <!…

oracle表分区--范围分区

文章目录 oracle表分区分区的原因分区的优势oracle表分区的作用oracle表分区类型一、范围分区二、 创建分区表和使用&#xff1a;1、按照数值范围划分2、按照时间范围3、MAXVALUE2. 向现有表添加新的分区3、 分区维护和重新组织&#xff08;合并/删除&#xff09; oracle表分区…

mysql读写分离与proxysql的结合

上一篇文章介绍了mysql如何设置成主从复制模式&#xff0c;而主从复制的目的&#xff0c;是为了读写分离。 读写分离&#xff0c;拿spring boot项目来说&#xff0c;可以有2种方式&#xff1a; 1&#xff09;设置2个数据源&#xff0c;读和写分开使用 2&#xff09;使用中间件…

Untiy3d 铰链、弹簧,特殊的物理关节

&#xff08;一&#xff09;铰链组件 1.创建一个立方体和角色胶囊 2.给角色胶囊挂在控制脚本和刚体 using System.Collections; using System.Collections.Generic; using UnityEngine;public class plyer : MonoBehaviour {// Start is called once before the first execut…

Visual Studio 进行单元测试【入门】

摘要&#xff1a;在软件开发中&#xff0c;单元测试是一种重要的实践&#xff0c;通过验证代码的正确性&#xff0c;帮助开发者提高代码质量。本文将介绍如何在VisualStudio中进行单元测试&#xff0c;包括创建测试项目、编写测试代码、运行测试以及查看结果。 1. 什么是单元测…

Leetcode - 周赛435

目录 一、3442. 奇偶频次间的最大差值 I二、3443. K 次修改后的最大曼哈顿距离三、3444. 使数组包含目标值倍数的最少增量四、3445. 奇偶频次间的最大差值 II 一、3442. 奇偶频次间的最大差值 I 题目链接 本题使用数组统计字符串 s s s 中每个字符的出现次数&#xff0c;然后…

算法之 数论

文章目录 质数判断质数3115.质数的最大距离 质数筛选204.计数质数2761.和等于目标值的质数对 2521.数组乘积中的不同质因数数目 质数 质数的定义&#xff1a;除了本身和1&#xff0c;不能被其他小于它的数整除&#xff0c;最小的质数是 2 求解质数的几种方法 法1&#xff0c;根…

docker 导出导入

1第一步骤docker save docker save -o database-export-4.1.0.tar database-export-4.1.0.jar:latest 2检查镜像ls -l, 注意&#xff1a;文件可能没有其他文件导出权限&#xff1a;chmod 644 database-export-4.1.0.tar 3在新的服务器导入&#xff1a; docker load -i databa…

OSPF高级特性(3):安全特效

引言 OSPF的基础我们已经结束学习了&#xff0c;接下来我们继续学习OSPF的高级特性。为了方便大家阅读&#xff0c;我会将高级特性的几篇链接放在末尾&#xff0c;所有链接都是站内的&#xff0c;大家点击即可阅读&#xff1a; OSPF基础&#xff08;1&#xff09;&#xff1a;工…

基于SSM的农产品供销小程序+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、农户功能模块&#xff1a;用户管理、农户管理、产品分类管理、农产品管理、咨询管理、订单管理、收藏管理、购物车、充值、下单等技术选型&#xff1a;SSM&#xff0c;Vue&#xff08;后端管理web&#xff09;&#xff0c;uniapp等测试…

Unity URP的2D光照简介

官网工程&#xff0c;包括2d光照&#xff0c;动画&#xff0c;动效介绍&#xff1a; https://unity.com/cn/blog/games/happy-harvest-demo-latest-2d-techniques https://docs.unity3d.com/6000.0/Documentation/Manual/urp/Lights-2D-intro.html 人物脸部光照细节和脚上的阴影…

Jenkins 部署 之 Mac 一

Jenkins 部署 之 Mac 一 一.Jenkins 部署依赖 JDK 环境 查看 Mac JDK 环境&#xff0c;如果没有安装&#xff0c;先安装 打开终端输入命令:java -version Mac安装配置 JDK 二. 检查 HomeBrew 安装 检查 HomeBrew 是否安装&#xff0c;终端输入命令:brew -v Mac安装HomeB…

钉钉位置偏移解决,钉钉虚拟定位打卡

虚拟定位打卡工具 一&#xff0c;介绍免费获取工具 一&#xff0c;介绍 提到上班打卡&#xff0c;职场人的内心戏估计能拍成一部连续剧。打卡&#xff0c;这俩字仿佛自带“紧箍咒”&#xff0c;让无数打工人又爱又恨。想象一下&#xff0c;你气喘吁吁地冲进办公室&#xff0c;…

使用DeepSeek和Kimi快速自动生成PPT

目录 步骤1&#xff1a;在DeepSeek中生成要制作的PPT主要大纲内容。 &#xff08;1&#xff09;在DeepSeek网页端生成 &#xff08;2&#xff09;在本地部署DeepSeek后&#xff0c;使用chatBox生成PPT内容 步骤2&#xff1a;将DeepSeek成的PPT内容复制到Kimi中 步骤3&…

Webpack包

黑马程序员视频地址&#xff1a; Node.js与Webpack-16.Webpack简介以及体验 前言&#xff1a; 本篇中部分标题后标有数字&#xff0c;代表学习顺序 &#xff0c;同时也可以作为使用顺序参考 webpack包 基础认识 初步使用 下载webpack包和webpack-cli包 注意点&#xff1a; 1…

鸿蒙HarmonyOS NEXT开发:横竖屏切换开发实践

文章目录 一、概述二、窗口旋转说明1、配置module.json5的orientation字段2、调用窗口的setPreferredOrientation方法 四、性能优化1、使用自定义组件冻结2、对图片使用autoResize3、排查一些耗时操作 四、常见场景示例1、视频类应用横竖屏开发2、游戏类应用横屏开发 五、其他常…

基于Spring Security 6的OAuth2 系列之十五 - 高级特性--客户端认证方式

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…

排序合集之快排详解(二)

摘要&#xff1a;快速排序是一种在实践中广泛使用的高效排序算法。它基于分治策略&#xff0c;平均时间复杂度为O(n log n)&#xff0c;使其成为处理大型数据集的理想选择。本文将深入探讨快速排序的各种实现方式、优化技巧以及非递归实现&#xff0c;并通过C语言代码示例进行详…