《嵌入式硬件(十七):基于IMX6ULL的温度传感器LM75a操作》

一、LM75a

三号引脚可以设置一个阈值,采集到的温度超过阈值时,会使电平进行翻转。也可以连接gpio,当温度到达阈值时,发出中断。

1.设备地址

2.寄存器

0x00是温度传感器的温度,只读

0x07是产品ID

读取俩个字节,0-6位需要去掉,读取的数乘0.5,为实际温度

3.时序

二、代码

1.start.S

加入cp11的(FPU,计算浮点数)使能代码(进入主函数之前调用)

cs 复制代码
_enable_fpu:
    // 1. 设置CPACR寄存器使能FPU访问
    mrc     p15, 0, r0, c1, c0, 2   // 读取CPACR
    orr     r0, r0, #(0xF << 20)    // 设置CP10和CP11为完全访问
    mcr     p15, 0, r0, c1, c0, 2   // 写回CPACR
    
    // 2. 使能FPU
    mov     r0, #0x40000000         // 设置FPEXC的EN位
    vmsr    fpexc, r0               // 写入FPEXC
    
    // 3. 配置FPSCR
    mov     r0, #0x00000000         // 清除所有标志位
    vmsr    fpscr, r0               // 写入FPSCR
    
    bx      lr                      // 返回

2.i2c.c

修改了寄存器地址,因为他不一定是一个字节

cs 复制代码
#include "i2c.h"
#include "fsl_iomuxc.h"
#include "delay.h"

#define IEN         (7)
#define MSTA        (5)
#define MTX         (4)
#define TXAK        (3)
#define RSTA        (2)

#define ICF         (7)
#define IBB         (5)
#define IAL         (4)
#define IIF         (1)

void init_i2c1(void)
{
    IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1);
    IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1);

    IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0xF0B0);
    IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0xF0B0);  
    
    I2C1->I2CR &= ~(1 << 7);
    I2C1->IFDR = 0x15;
    I2C1->I2CR |= (1 << 7);    

}

void i2c_write(I2C_Type *base, unsigned char device_address, unsigned short reg_address, int reg_len, const unsigned char *data, int len)
{
    base->I2SR &= ~((1 << IAL) | (1 << IIF));
    while((base->I2SR & (1 << ICF)) == 0);
    base->I2CR |= (1 << MSTA) | (1 << MTX);
    base->I2CR &= ~(1 << TXAK);

    base->I2SR &= ~(1 << IIF);
    base->I2DR = device_address << 1;
    while((base->I2SR & (1 << IIF)) == 0);

    int i;  
    for(i = 0;i < reg_len;++i)
    {
        base->I2SR &= ~(1 << IIF);
        base->I2DR = reg_address >> (reg_len - i - 1) * 8;
        while((base->I2SR & (1 << IIF)) == 0);          
    }
    
    while(len--)
    {
        base->I2SR &= ~(1 << IIF);
        base->I2DR = *data++;
        while((base->I2SR & (1 << IIF)) == 0);         
    }
    base->I2CR &= ~(1 << MSTA);
    while((base->I2SR & (1 << IBB)) != 0)
    {
        delayus(100);
    }
}

void i2c_read(I2C_Type *base, unsigned char device_address, unsigned short reg_address, int reg_len, unsigned char *data, int len)
{
    base->I2SR &= ~((1 << IAL) | (1 << IIF));
    while((base->I2SR & (1 << ICF)) == 0);
    base->I2CR |= (1 << MSTA) | (1 << MTX);
    base->I2CR &= ~(1 << TXAK);

    base->I2SR &= ~(1 << IIF);
    base->I2DR = device_address << 1;
    while((base->I2SR & (1 << IIF)) == 0);

    int i;  //0x1234  reg_len = 2
    for(i = 0;i < reg_len;++i)
    {
        base->I2SR &= ~(1 << IIF);
        base->I2DR = reg_address >> (reg_len - i - 1) * 8;
        while((base->I2SR & (1 << IIF)) == 0);          
    }

    
    base->I2CR |= (1 << RSTA);
    base->I2SR &= ~(1 << IIF);   
    base->I2DR = device_address << 1 | 1;
    while((base->I2SR & (1 << IIF)) == 0); 
    
    base->I2CR &= ~(1 << MTX);
    base->I2SR &= ~(1 << IIF);  
    
    if(1 == len)
    {
        base->I2CR |= (1 << TXAK);
    }

    *data = base->I2DR;

    while(len-- != 0)
    {
        while((base->I2SR & (1 << IIF)) == 0);
        base->I2SR &= ~(1 << IIF);  
        if(len == 0)        
        {
            base->I2CR &= ~((1 << MSTA) | (1 << TXAK));
            while((base->I2SR & (1 << IBB)) != 0)
            {
                delayus(100);
            }
        }
        else if(len == 1)
        {
            base->I2CR |= (1 << TXAK);
        }
        *data++ = base->I2DR;
    }
}

void xfer(I2C_Type *base, struct I2C_MSG *msg)
{
    if(msg->deiection == I2C_Write)
    {
        i2c_write(base, msg->dev_address, msg->reg_address, msg->reg_len, msg->data, msg->len);
    }
    else
    {
        i2c_read(base, msg->dev_address, msg->reg_address, msg->reg_len, msg->data, msg->len);
    }
}

3.i2c.h

cs 复制代码
#ifndef _I2C_H_
#define _I2C_H_

#include "MCIMX6Y2.h"
extern void init_i2c1(void);
extern void i2c_write(I2C_Type *base, unsigned char device_address, unsigned short reg_address, int reg_len, const unsigned char *data, int len);
extern void i2c_read(I2C_Type *base, unsigned char device_address, unsigned short reg_address, int reg_len, unsigned char *data, int len);

enum I2C_Driection
{
    I2C_Write = 0,
    I2C_Read = 1
};


struct I2C_MSG
{
    unsigned char dev_address;
    unsigned short reg_address;
    int reg_len;
    unsigned char *data;
    int len;
    enum I2C_Driection deiection;
};

extern void xfer(I2C_Type *base, struct I2C_MSG *msg);

#endif

4.lm75.c

cs 复制代码
#include "i2c.h"
#include "MCIMX6Y2.h"

float lm75_get_temperature(void)
{
    unsigned char buffer[2] = {0};
    short s;
    struct I2C_MSG msg = 
    {
        .deiection = I2C_Read,
        .dev_address = 0x48,
        .reg_address = 0,
        .reg_len = 1,
        .data = buffer,
        .len = 2
    };
    xfer(I2C1, &msg);

    // i2c_read(I2C1, 0x48, 0, 1,buffer, 2);
    s = buffer[0] << 8;
    s |= buffer[1];
    s >>= 7;
    return s * 0.5;
}

5.lm75.h

cs 复制代码
#ifndef _LM75_H_
#define _LM75_H_

extern float lm75_get_temperature(void);


#endif

6.main.c

cs 复制代码
#include "string.h"
#include "led.h"
#include "beep.h"
#include "MCIMX6Y2.h"
#include "key.h"
#include "interrupt.h"
#include "clock.h"
#include "epit.h"
#include "gpt.h"
#include "delay.h"
#include "uart.h"
#include "stdio.h"
#include "i2c.h"
#include "lm75.h"

int main(void)
{
    init_clock();
    system_interrupt_init();
    init_led();
    init_beep();
    // init_key();
//    init_epit1();
    init_gpt1();
    init_uart1(); 
    init_i2c1();
    
    while(1)
    {
        delayms(500);

        float f;
        f = lm75_get_temperature();
        int k = f * 10;
        int n = k / 10;
        int m = k % 10;
        printf("%d.%d\n", n, m);
    }
    return 0;
}
相关推荐
Funing713 分钟前
BUCK降压电路如何同时兼顾效率和纹波?——12V 转 3.3V 供电的工程解法
嵌入式硬件·电路·开关电源·buck降压
秋深枫叶红20 分钟前
嵌入式第五十一篇——IMX6ULL中断和EPIT定时器
单片机·嵌入式硬件
【赫兹威客】浩哥37 分钟前
【赫兹威客】Arduino安装教程
stm32·单片机·嵌入式硬件
flashier1 小时前
ESP32学习笔记_WiFi(3)——HTTP
网络·笔记·单片机·网络协议·学习·http·esp32
兆龙电子单片机设计1 小时前
【STM32项目开源】STM32单片机智能宠物管家
stm32·单片机·物联网·开源·毕业设计·宠物
阿呀呀呀1 小时前
ESP32复位电路分析
单片机·嵌入式硬件
华清远见IT开放实验室2 小时前
【课程升级】STM32U5体系化课程深度升级!全103集,覆盖裸机开发+TouchGFX图形界面+智能手表项目,从入门到实战!
stm32·单片机·嵌入式硬件·智能手表
一路往蓝-Anbo2 小时前
第 2 篇:单例模式 (Singleton) 与 懒汉式硬件初始化
开发语言·数据结构·stm32·单片机·嵌入式硬件·链表·单例模式
嵌入你的世界2 小时前
cmBacktrace 实现原理解析:从 HardFault 现场到源码回溯
stm32·单片机·嵌入式硬件·cmbacktrace
BackCatK Chen2 小时前
浅聊:STM32 2026 年核心技术及选型建议
stm32·单片机·嵌入式硬件·csdn年度技术趋势预测