一、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;
}
