时序图
- 写地址
- 写寄存器指针
- 重新开始
- 写地址
- 读数据
程序
#define LM75A_ADDRESS_READ 0b10010001
#define LM75A_ADDRESS_WRITE 0b10010000
#define LM75A_REGISTER_TEMPERATURE 0
/* starts i2c */
void initLM75A();
/* gets the full temperature register info and returns it to master */
uint16_t getTemperature();
/*
allows the lm75a temperature register to be read
Returns: unsigned 16bit int containing the temperature. The top 8 bits represent the whole number part of the temperature, bits 9, 10 and 11 represent the fractional part of the temperature (0.5, 0.25 and 0.125 degrees) and the remaining bits are always 0
*/
uint16_t getTemperature()
{
i2cStart();
i2cSend(LM75A_ADDRESS_WRITE);
i2cSend(LM75A_REGISTER_TEMPERATURE); // set register pointer to temperature register
i2cStart(); // restart, now reading
i2cSend(LM75A_ADDRESS_READ);
uint8_t upperByte = i2cRead(ACK);
uint8_t lowerByte = i2cRead(NACK);
i2cStop();
return (upperByte << 8) | lowerByte;
}
寄存器
完整程序
#ifndef _LM75AD_H_
#define _LM75AD_H_
#include "config.h"
#include "STC8A_GPIO.h"
#include "STC8A_Delay.h"
#define LM75A_ADDR 0X48 //i2c slave address
#define REG_TEMP 0X00 //温度,只读
#define REG_CONF 0X01 //配置
#define REG_THYST 0X02 //滞后控制
#define REG_TOS 0X03 //超温关闭寄存器
#define IIC_WRITE 0 //数据方向,写入
#define IIC_READ 1 //数据方向,接收
#define LM75AD_SDA_IN() P5_MODE_IO_PU(GPIO_Pin_2);
#define LM75AD_SDA_OUT() P5_MODE_OUT_PP(GPIO_Pin_2);
//IO操作函数
sbit LM75AD_IIC_SCL =P5^3; //SCL
sbit LM75AD_IIC_SDA = P5^2; //SDA
sbit LM75AD_READ_SDA = P5^2; //输入SDA
sbit LM75AD_A0 = P3^5;
sbit LM75AD_A1 = P3^4;
sbit LM75AD_A2 = P3^5;
//IIC所有操作函数
void LM75AD_Init(void); //初始化IIC的IO口
void LM75AD_IIC_Start(void); //发送IIC开始信号
void LM75AD_IIC_Stop(void); //发送IIC停止信号
void LM75AD_IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 LM75AD_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 LM75AD_IIC_Wait_Ack(void); //IIC等待ACK信号
void LM75AD_IIC_Ack(void); //IIC发送ACK信号
void LM75AD_IIC_NAck(void); //IIC不发送ACK信号
u16 I2C_LM75read(void);
float LM75A_readTemperature(void);
void LM75A_GetTemp(u8 *Tempbuffer);
float getTemperature();
#endif
#include "LM75AD.h"
//初始化IIC
void LM75AD_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_2|GPIO_Pin_3; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P5,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化
LM75AD_IIC_SCL = 1;
LM75AD_IIC_SDA = 1;
LM75AD_A0 =1;
LM75AD_A1 =1;
LM75AD_A2 =1;
delay_ms(10);
}
//产生IIC起始信号
void LM75AD_IIC_Start(void)
{
LM75AD_SDA_OUT(); //sda线输出
LM75AD_IIC_SDA=1;
LM75AD_IIC_SCL=1;
delay_us(4);
LM75AD_IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
LM75AD_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void LM75AD_IIC_Stop(void)
{
LM75AD_SDA_OUT();//sda线输出
LM75AD_IIC_SCL=0;
LM75AD_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
LM75AD_IIC_SCL=1;
LM75AD_IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 LM75AD_IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
LM75AD_SDA_IN(); //SDA设置为输入
LM75AD_IIC_SDA=1;
delay_us(1);
LM75AD_IIC_SCL=1;
delay_us(1);
while(LM75AD_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
LM75AD_IIC_Stop();
return 1;
}
}
LM75AD_IIC_SCL=0;//时钟输出0
// LM75AD_SDA_OUT();//sda线输出
return 0;
}
//产生ACK应答
void LM75AD_IIC_Ack(void)
{
LM75AD_IIC_SCL=0;
LM75AD_SDA_OUT();
LM75AD_IIC_SDA=0;
delay_us(2);
LM75AD_IIC_SCL=1;
delay_us(2);
LM75AD_IIC_SCL=0;
}
//不产生ACK应答
void LM75AD_IIC_NAck(void)
{
LM75AD_IIC_SCL=0;
LM75AD_SDA_OUT();
LM75AD_IIC_SDA=1;
delay_us(2);
LM75AD_IIC_SCL=1;
delay_us(2);
LM75AD_IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void LM75AD_IIC_Send_Byte(u8 txd)
{
u8 t;
LM75AD_SDA_OUT();
LM75AD_IIC_SCL=0;//拉低时钟开始数据传输
for(t=0; t<8; t++)
{
//LM75AD_IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
LM75AD_IIC_SDA=1;
else
LM75AD_IIC_SDA=0;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
LM75AD_IIC_SCL=1;
delay_us(2);
LM75AD_IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 LM75AD_IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
LM75AD_SDA_IN();//SDA设置为输入
for(i=0; i<8; i++ )
{
LM75AD_IIC_SCL=0;
delay_us(2);
LM75AD_IIC_SCL=1;
receive<<=1;
if(LM75AD_READ_SDA)receive++;
delay_us(1);
}
if (!ack)
LM75AD_IIC_NAck();//发送nACK
else
LM75AD_IIC_Ack(); //发送ACK
// LM75AD_SDA_OUT();//sda线输出
return receive;
}
u16 I2C_LM75read(void)
{
u16 readDATA=0x0000;
u8 tempH=0x00;
u8 tempL=0x00;
LM75AD_IIC_Start();
LM75AD_IIC_Send_Byte(0x9E); //A0A1A2 111
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
LM75AD_IIC_Send_Byte(0x00);
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
LM75AD_IIC_Start();
LM75AD_IIC_Send_Byte(0x9F);
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
tempH=LM75AD_IIC_Read_Byte(1);
//LM75AD_IIC_Ack();
tempL=LM75AD_IIC_Read_Byte(0);
//LM75AD_IIC_NAck();
LM75AD_IIC_Stop();
readDATA=(((u16)tempH<<8 )| tempL)>>5;
return readDATA;
}
float LM75A_readTemperature(void) {
u8 temp_buff[2];
short temp_data;
float temp_out;
float temp_value=0.0;
unsigned int temp_high=0;
unsigned int temp_low=0;
unsigned int low=0;
unsigned int tempforh=0;
unsigned int judge_posneg=0;
LM75AD_IIC_Start();
LM75AD_IIC_Send_Byte(0x9E); //A0A1A2 111
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
LM75AD_IIC_Send_Byte(0x00);
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
LM75AD_IIC_Start();
LM75AD_IIC_Send_Byte(0x9F);
LM75AD_IIC_Wait_Ack();//等待地址确认,从机应答
temp_buff[0]=LM75AD_IIC_Read_Byte(1);
temp_buff[1]=LM75AD_IIC_Read_Byte(0);
LM75AD_IIC_Stop();
temp_high=temp_buff[0];
temp_low=temp_buff[1];
low=temp_low>>5;
tempforh=temp_high*8+low;
judge_posneg=(temp_high & 0x80)>>7;
if(judge_posneg==0){
temp_value=tempforh*0.125;
return temp_value;
}else {
tempforh=(tempforh^0x7FF)+1;
temp_value=tempforh*(-0.125);
return temp_value;
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于