《嵌入式硬件(十七):基于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;
}
相关推荐
jmlinux8 小时前
stm32与串口屏双向通讯官方例程
c语言·stm32·单片机·嵌入式硬件·物联网
GilgameshJSS12 小时前
STM32H742-ARM例程32-LCD
c语言·arm开发·stm32·单片机·嵌入式硬件·计算机外设
heisd_115 小时前
什么是状态机编程和模块化编程
单片机·嵌入式硬件
liujing1023292916 小时前
stm32_关于乐鑫ESP8266-07S WIFI模组烧录安信可科技的MQTT固件流程
科技·stm32·嵌入式硬件
zzz海羊17 小时前
江科大stm32 | OLED显示汉字
stm32·单片机·嵌入式硬件
Jack1530276827918 小时前
误接电容正负极的风险与注意事项
单片机·嵌入式硬件·逆变器·摇头机·电动工具·dc/dc变换器
国科安芯20 小时前
国产MCU芯片在船舶压力传感器中的应用探索与实践
网络·单片机·嵌入式硬件·fpga开发·车载系统
学工科的皮皮志^_^20 小时前
PCIE学习
经验分享·嵌入式硬件·学习·fpga开发·pcie
La Pulga21 小时前
【STM32】WDG看门狗
c语言·stm32·单片机·嵌入式硬件·mcu