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

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

0x00是温度传感器的温度,只读
0x07是产品ID

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


二、代码
1.start.S
加入cp11的(FPU,计算浮点数)使能代码(进入主函数之前调用)
_enable_fpu:// 1. 设置CPACR寄存器使能FPU访问mrc     p15, 0, r0, c1, c0, 2   // 读取CPACRorr     r0, r0, #(0xF << 20)    // 设置CP10和CP11为完全访问mcr     p15, 0, r0, c1, c0, 2   // 写回CPACR// 2. 使能FPUmov     r0, #0x40000000         // 设置FPEXC的EN位vmsr    fpexc, r0               // 写入FPEXC// 3. 配置FPSCRmov     r0, #0x00000000         // 清除所有标志位vmsr    fpscr, r0               // 写入FPSCRbx      lr                      // 返回2.i2c.c
修改了寄存器地址,因为他不一定是一个字节
#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 = 2for(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
#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
#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
#ifndef _LM75_H_
#define _LM75_H_extern float lm75_get_temperature(void);#endif
6.main.c
#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;
}
