金牌会员
- 积分
- 1113
- 金钱
- 1113
- 注册时间
- 2016-8-26
- 在线时间
- 256 小时
|
楼主 |
发表于 2020-3-16 11:09:11
|
显示全部楼层
这是在我msp430f5438上通过的代码,看有木有帮助
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __SHT3X_H__
#define __SHT3X_H__
#include <msp430x54x.h>
// CRC
#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
#define SHT30W 0x88
#define SHT30R 0x89
#define SDA_OUT (P4DIR |= BIT1) //p4.1=out/in
#define SDA_IN (P4DIR &=~BIT1)
#define SDA_1 (P4OUT |= BIT1)
#define SDA_0 (P4OUT &=~BIT1)
#define SDA_INPUT P4IN
#define SDA BIT1
#define SCL_1 (P4OUT |= BIT2) //p4.2=out
#define SCL_0 (P4OUT &=~BIT2)
#define SCL_IN (P4DIR &=~BIT2)
#define SCL_OUT (P4DIR |= BIT2)
void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(void);
void IIC_NAck(void);
u8 IIC_Wait_Ack(void );
void IIC_Send_Byte(u8 data);
u8 Read_I2c(void);
u8 SHT3X_GetTempAndHumi(void); //读取温湿度
u8 SHT3X_WriteCmd(u8 msb,u8 lsb); //发送命令
u8 SHT3X_CheckCrc(u8 data[], u8 BytesNum, u8 rx_crc);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/******************************模拟IIC总线*************************************
//端口初始化
void IIC_Init(void)
{
SCL_OUT; //SCL管脚为输出
SDA_OUT; //SDA管脚为输出
SCL_1;
SDA_1;
}
//开始条件
void IIC_Start(void) //scl为高电平期间,sda产生一个下降沿
{
SDA_OUT; //sda线输出
SDA_1;
SCL_1;
delay_us(20);
SDA_0; //START:when CLK is high,DATA change form high to low
delay_us(20);
SCL_0; //钳住I2C总线,准备发送或接收数据
delay_us(20);
}
//停止条件
void IIC_Stop(void) //scl高电平期间,sda产生一上升沿
{
SDA_OUT;//sda线输出
SCL_0;
SDA_0;//STOP:when CLK is high DATA change form low to high
delay_us(20);
SCL_1;
delay_us(20);
SDA_1;//发送I2C总线结束信号
delay_us(20);
}
//单片机给传感器应答
void IIC_Ack(void)
{
SDA_OUT;
SCL_OUT;
SDA_0;
//delay_us(20);
SCL_0;
delay_us(20);
SCL_1;
delay_us(20);
SCL_0;
delay_us(20);
}
//单片机不给传感器应答
void IIC_NAck(void)
{
SDA_OUT;
SDA_1;
delay_us(20);
SCL_1;
delay_us(20);
SCL_0;
delay_us(20);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN; //SDA设置为输入
SCL_1;delay_us(20);
while((SDA_INPUT&SDA) == SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
SCL_0;//时钟输出0
delay_us(20);
//SDA_0;delay_us(20);
return 0;
}
/*******************************************************************************
函数名称:IIC_Send_Byte
函数功能:向I2C总线写入一个字节数据
入口参数:待写入的数据data
出口参数:无
备 注:一个字节为8位,单片机分8次写入I2C总线
*******************************************************************************/
void IIC_Send_Byte(u8 data)
{
u8 t,temp;
SDA_OUT;
SCL_0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
temp = data&0x80;
if(temp == 0x80)
SDA_1; //判断发送位,送数据到数据线上
else
SDA_0;
delay_us(20); //
SCL_1;
delay_us(20);
SCL_0;
delay_us(20);
data<<=1;
}
delay_us(20);
}
//读取1字节数据
u8 Read_I2c(void)
{
SDA_IN; //置数据线为输入方向
u8 i,q0;
u8 byte=0;
for(i=0;i<8;i++)
{
SCL_1; //置时钟为高电平,使数据线数据有效
delay_us(20);
byte=byte<<1;
q0=(SDA_INPUT & SDA);
if(q0==SDA)
byte=(byte|0x01); //将数据存入byte
delay_us(20);
SCL_0;
delay_us(20);
}
SDA_0;
delay_us(20);
SCL_1; // clk #9 for IIC_Ack
delay_us(20); // SCL high time (t_HIGH)
SCL_0;
delay_us(20);
SDA_1; // release SDA-line
delay_us(20);
return(byte);
}
//IIC读取一个字节
u8 IIC_Read_Byte(u8 ack)
{
u8 i,receive=0;
SDA_IN;//SDA设置为输入
SCL_0;
for(i=0;i<8;i++ )
{
SCL_1;
delay_us(20);
receive<<=1;
if((SDA_INPUT & SDA) == SDA)
receive |= 0x01;
else
receive &= 0xfe;
SCL_0;
delay_us(20);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
//sht30获取温湿度
u8 SHT3X_GetTempAndHumi(void)
{
int temp=0,humi=0;
u8 BUFt[6]={0};
u8 bytes[2];//收到的数据
u8 checksum;//收到的crc
u8 error = 0;
IIC_Init();
IIC_Start();
IIC_Send_Byte(SHT30W); //地址+写
//while(IIC_Wait_Ack()); //从机应答
if(IIC_Wait_Ack()) //从机应答
{
//进入这里表示sht30不存在或者通信故障,此时温湿度数据默认为0xFFFF
return error = 1;
}
else
{
IIC_Send_Byte(0x22); //发送0x2220,启动周期测量
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
IIC_Send_Byte(0x20);
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
//IIC_Stop(); //周期读取sht30数据,按照时序图,不需要发送停止信号
delay_ms(2); //此处延时必须要有,等待数据读取完成
IIC_Start();
IIC_Send_Byte(SHT30W); //地址+写
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
IIC_Send_Byte(0xe0); //0xE000,读取周期测量模式结果
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
IIC_Send_Byte(0x00);
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
//IIC_Stop(); //周期读取sht30数据,按照时序图,不需要发送停止信号
IIC_Start();
IIC_Send_Byte(SHT30R); //地址+读
//while(IIC_Wait_Ack());
//IIC_Wait_Ack();
if(IIC_Wait_Ack())
{
return error =1;
}
BUFt[0] = IIC_Read_Byte(1); //温度高
BUFt[1] = IIC_Read_Byte(1); //温度低
BUFt[2] = IIC_Read_Byte(1); //crc
BUFt[3] = IIC_Read_Byte(1); //湿度高
BUFt[4] = IIC_Read_Byte(1); //湿度低
BUFt[5] = IIC_Read_Byte(0); //crc
IIC_Stop();
bytes[0] = BUFt[0];
bytes[1] = BUFt[1];
checksum = BUFt[2];
temp = (BUFt[0]<<8) | BUFt[1];
humi = (BUFt[3]<<8) | BUFt[4];
if(!SHT3X_CheckCrc(bytes,2,checksum)) //校验通多,计算温度
{
temp = (int)(175*(float)temp / 65535 - 45);
if(temp < -40) temp = -40;
if(temp > 125) temp = 125;
}
bytes[0] = BUFt[3];
bytes[1] = BUFt[4];
checksum = BUFt[5];
if(!SHT3X_CheckCrc(bytes,2,checksum)) //校验通多,计算湿度
{
humi = (u16)(100*(float)humi / 65535);
}
}
return error;
}
|
|