ARM(11) - LM75
一、手册查询
二、温度采集代码编写
start.S 添加
enable_fpu
函数的执行流程遵循 “权限开放 → 硬件激活 → 状态初始化” 的递进逻辑,缺一不可:
- 若不配置 CPACR:核心无法访问 CP10/CP11,执行浮点指令直接触发 “未定义指令异常”;
- 若不激活 FPEXC 的 EN 位:FPU 硬件休眠,即使有访问权限,浮点指令也无法被执行;
- 若不初始化 FPSCR:FPU 可能残留旧的异常标志或错误配置,导致后续浮点运算结果不准确。
lm75.c
#include "lm75.h" // 包含LM75传感器相关宏定义和函数声明
#include "MCIMX6Y2.h" // 包含i.MX6Y2处理器寄存器定义
#include "i2c.h" // 包含I2C通信相关函数声明// 接收缓冲区:用于存储从LM75读取的原始温度数据(2字节)
unsigned char rcv_buffer[2] = {0};/*** @brief 从LM75传感器读取温度值并转换为摄氏度* @return 转换后的温度值(浮点数,单位:°C)*/
float get_temp_value(void)
{unsigned short t = 0; // 用于暂存合并后的16位温度数据/* * 通过I2C读取LM75的温度数据* 参数说明:* I2C1:使用I2C1外设* 0x48:LM75的I2C设备地址(默认地址,可通过硬件引脚修改)* 0x00:要读取的寄存器地址(LM75的温度寄存器地址)* 1:寄存器地址长度为1字节* rcv_buffer:接收数据的缓冲区* 2:读取2字节数据(LM75温度数据为16位)*/i2c_read(I2C1, 0x48, 0x00, 1, rcv_buffer, 2);// 将接收缓冲区的2字节数据合并为16位数据// rcv_buffer[0]是高8位,rcv_buffer[1]是低8位t |= (rcv_buffer[0] << 8) | (rcv_buffer[1] << 0);/* * LM75温度数据格式:* 16位数据中,前11位为有效温度数据(补码形式),分辨率为0.5°C* 右移7位是为了丢弃低7位无效数据,保留高9位有效数据(符号位+8位整数+1位小数)*/t = t >> 7;// 乘以0.5得到实际温度值(因为分辨率为0.5°C)return t * 0.5;
}
main.c
#include "MCIMX6Y2.h" // 处理器寄存器定义
#include "fsl_iomuxc.h" // IO复用配置头文件
#include "core_ca7.h" // Cortex-A7内核相关函数
#include "led.h" // LED驱动
#include "beep.h" // 蜂鸣器驱动
#include "key.h" // 按键驱动
#include "interrupt.h" // 中断相关配置
#include "clock.h" // 时钟配置
#include "epit.h" // EPIT定时器驱动
#include "gpt.h" // GPT定时器驱动
#include "uart.h" // UART串口驱动
#include "stdio.h" // 标准输入输出函数
#include "i2c.h" // I2C通信驱动
#include "lm75.h" // LM75温度传感器驱动/*** @brief 主函数:初始化硬件并循环读取温度值* @return 无(嵌入式程序通常不返回)*/
int main(void)
{// 初始化系统时钟(配置CPU、外设时钟频率)clock_init();// 初始化系统中断控制器(配置中断优先级、使能中断等)system_interrupt_init();// 初始化LED(配置IO口为输出,用于指示系统状态)led_init();// 初始化蜂鸣器(配置IO口为输出,用于报警等)beep_init();// 初始化按键(配置IO口为输入,用于用户交互)key_init();// 初始化EPIT1定时器(高精度定时器,可用于定时中断)epit1_init();// 初始化GPT1定时器(通用定时器,可用于PWM或定时任务)gpt1_init();// 初始化UART1(配置波特率等参数,用于串口通信打印信息)uart1_init();// 初始化I2C1(配置通信速率等参数,用于与LM75通信)i2c1_init();// 临时缓冲区(原用于I2C测试,当前未使用)unsigned char rcv_buffer[32] = {0};unsigned short t = 0; // 临时变量(未使用)int a = 0; // 用于温度值放大后的整数存储int m = 0, n = 0; // m:温度整数部分;n:温度小数部分float temp = 0; // 存储转换后的温度值// 主循环:持续读取并打印温度while (1){/* 以下为注释掉的I2C测试代码(原用于测试与其他I2C设备通信)// 从串口接收数据//scanf("%s", rcv_buffer);// 获取接收数据长度//unsigned int len = strlen((char *)rcv_buffer);// 打印写入长度//printf("iic ====================================== write:%u\n", len);// 向I2C设备(地址0x50,可能是EEPROM)写入数据//i2c_write(I2C1, 0x50, 0x00, 1, rcv_buffer, len);// 清空缓冲区//memset(rcv_buffer, 0, sizeof(rcv_buffer));// 打印读取长度//printf("iic ====================================== read:%u\n", len);// 从I2C设备读取数据//i2c_read(I2C1, 0x50, 0x00, 1, rcv_buffer, len);// 打印读取结果//printf("read:%s\n", rcv_buffer);// 清空缓冲区//memset(rcv_buffer, 0, sizeof(rcv_buffer));*/// 读取温度值(调用LM75驱动函数)temp = get_temp_value();// 将温度值放大100倍转为整数(避免浮点数打印精度问题)a = temp * 100;// 提取整数部分(如3250 → 32)m = a / 100;// 提取小数部分(如3250 → 50)n = a % 100;// 通过UART打印温度值(格式:temp = X.XX)printf("temp = %d.%d\n", m, n);// 延迟100ms(控制温度读取频率,避免频繁读取)delay_ms(100);}
}
现象
LM75温度传感器关键信息
下面表格总结了LM75温度传感器的关键特性和数据格式:
特性 | 描述 |
---|---|
通信接口 | I2C总线 |
设备地址 | 0x48 (当A2=A1=A0=0时) |
温度寄存器 | 0x00 |
数据格式 | 16位(高字节在前) |
有效数据位 | 高9位(包含符号位) |
分辨率 | 0.5°C/LSB |
测量范围 | -55°C 至 +125°C |
数据格式 | 二进制补码 |
温度数据处理说明
LM75的温度数据采用11位有效位存储(1位符号位+10位数据位),但实际使用中通常只关心高9位。温度值的计算步骤如下:
- 读取原始数据:通过I2C读取2字节温度数据
- 数据组合:将两个字节组合成16位整数
- 移位处理:右移7位,保留高9位有效数据
- 温度转换:乘以0.5°C/LSB得到实际温度值
示例:如果读取的原始数据为0x0190,则:
- 右移7位:0x0190 >> 7 = 0x0032 (十进制50)
- 实际温度:50 × 0.5 = 25.0°C