同样的程序在ATMEGA169上可以读取,转到ATMEGA48上就不行了,到发送0XF5命令就无反馈了,谢谢
#include "TIME.h"
#include "UART.h"
#include "SHT20.H" //sht20 head file
unsigned char g_ucSegnumber1;
unsigned char g_ucSegnumber2;
unsigned char g_ucSegnumber3;
unsigned char g_ucSegnumber4;
unsigned char g_ucSegnumber5;
unsigned char g_ucSegnumber6;
//
unsigned char g_ucTH_H , g_ucTH_L,g_ucTC_H , g_ucTC_L ,aa,bb;
/*================================================================
【 Name 】Pin Description
【Function】模拟IIC使用的引脚定义,注意要上拉电阻,SDA和SCL均上拉10KΩ电阻
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
/*************Pin Description*************
P2.6------SCK (SHT20)
P2.7------DATA (SHT20)
*****************************************/
// sbit SDA=P2^7; // define data pin
// sbit SCL=P2^6; // define clock pin
/*================================================================
【 Name 】
【Function】SHT20的I2C地址
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
#define SHT20ADDR 0x80
/*================================================================
【 Name 】
【Function】应答位电平定义
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
#define ACK 0 //应答信号
#define NACK 1 //非应答信号
/*================================================================
【 Name 】void Delay(uint t)
【Function】delay Nms
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
// void Delay(uint t)
// {
//_delay_ms(t) ;
// }
/*------------------------------------------------------------*/
/**********************Simulation I2C Function*****************/
/*------------------------------------------------------------*/
/*================================================================
【 Name 】void I2CDelay (uchar t)
【Function】模拟IIC用的短延时 us
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
// void I2CDelay (uchar t)
// {
//_delay_us(t);
// }
/*================================================================
【 Name 】void I2CInit(void)
【Function】I2C初始化,空闲状态
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
void I2CInit(void)
{
SDADDROUT;//
SCLDDROUT;
_delay_us(20);//I2CDelay(1);
SDASET;//SDA = 1;
// _delay_us(20);//I2CDelay(10);
SCLSET;//SCL = 1;
_delay_ms(20);//I2CDelay(10);
}
/*================================================================
【 Name 】void I2CStart(void)
【Function】I2C起始信号
【 Notes 】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
void I2CStart(void)
{
SDADDROUT;//
SCLDDROUT;
_delay_us(20);//I2CDelay(1);
SDASET;//SDA = 1; //发送起始条件的数据信号--ZLG
SCLSET;//SCL = 1;
_delay_us(20);//I2CDelay(1); //起始条件建立时间大于4.7us,延时--ZLG
SDACLR;//SDA = 0; //发送起始信号-ZLG
_delay_us(20);//I2CDelay(1); //起始条件锁定时间大于4μs--ZLG
SCLCLR;//SCL = 0; //钳住I2C总线,准备发送或接收数据--ZLG
_delay_us(20);//I2CDelay(1);
}
/*================================================================
【 Name 】void I2CStop(void)
【Function】I2C停止信号
【 Notes 】SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
void I2CStop(void)
{
SDADDROUT;//
SCLDDROUT;
_delay_us(20);//I2CDelay(1);
SDACLR;//SDA = 0; //发送结束条件的数据信号--ZLG
SCLCLR;//SCL = 0;
_delay_us(20);//I2CDelay(1);
SCLSET;//SCL = 1; //发送结束条件的时钟信号--ZLG
_delay_us(20);//I2CDelay(1); //结束条件建立时间大于4μs--ZLG
SDASET;//SDA = 1; //发送I2C总线结束信号--ZLG
_delay_us(20);//I2CDelay(1);
}
/*================================================================
【 Name 】uchar I2C_Write_Byte(uchar WRByte)
【Function】I2C写一个字节数据,返回ACK或者NACK
【 Notes 】从高到低,依次发送
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
uchar I2C_Write_Byte(uchar Write_Byte) //Sendbyte
{
uchar i;
SDADDROUT;
SCLDDROUT;
_delay_us(20);//I2CDelay(1);
for(i=0;i<8;i++) //要传送的数据长度为8位--ZLG
{
if(Write_Byte&0x80) //判断发送位--ZLG
{
SDASET;//SDA = 1;
}
else
{
SDACLR;//SDA = 0;
}
_delay_us(10);//I2CDelay(1);
SCLSET;//SCL=1; //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
_delay_us(10);//I2CDelay(5); //保证时钟高电平周期大于4μs--ZLG
SCLCLR;//SCL=0;
_delay_us(10);//I2CDelay(1);
Write_Byte <<= 1;
}
_delay_us(40);//I2CDelay(4);
SDASET;//SDA = 1; //8位发送完后释放数据线,准备接收应答位-ZLG
SCLSET;//SCL = 1; //MCU告知SHT2X数据发送完毕,等待从机的应答信号
SDADDRIN; //SDA口转为输入
_delay_us(50);//I2CDelay(5);
/*以下是判断I2C总线接收应到应答信号是ACK还是NACK*/
asm("nop");
// while(1)
// {
//if((SDAIN)!=0x10)//(SDA==1) //SDA为高,收到NACK
//{
//SCLCLR;//SCL=0;
//_delay_us(150);//I2CDelay(15);
//return ACK;
//}
if((SDAIN)==0x10)//(SDA==1) //SDA为高,收到NACK
{
SCLCLR;//SCL=0;
_delay_us(50);//I2CDelay(15);
return NACK;
}
else //SDA为低,收到ACK
{
SCLCLR;//SCL=0;
_delay_us(50);//I2CDelay(15);
return ACK;
}
// }
}
/*================================================================
【 Name 】uchar I2C_Read_Byte(uchar AckValue)
【Function】I2C读一个字节数据,入口参数用于控制应答状态,ACK或者NACK
【 Notes 】从高到低,依次接收
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
uchar I2C_Read_Byte(uchar AckValue)//receivebyte
{
uchar i,RDByte=0;
//管脚输出
SCLDDROUT;
SDADDROUT;
SCLCLR;//SCL=0; //置时钟线为低,准备接收数据位--ZLG
SDASET;//SDA = 1; //释放总线,置数据线为输入方式--ZLG
//管脚输入
SDADDRIN;
for (i=0;i<8;i++)
{
SCLSET;//SCL = 1; //SCL高电平期间,采集SDA信号,并作为有效数据 //置时钟线为高使数据线上数据有效--ZLG
_delay_us(20);//I2CDelay(2);
RDByte <<= 1; //移位
asm("nop");
if((SDAIN)==0x10)//(SDA==1) //采样获取数据
{
RDByte |= 0x01;
}
else
{
RDByte &= 0xfe;
}
_delay_us(10);//I2CDelay(1);
SCLCLR;//SCL = 0; //下降沿,从机给出下一位值
_delay_us(60);//I2CDelay(6);
}
/*以下是I2C总线发送应答信号ACK或者NACK*/
SDADDROUT;
if(AckValue==1)//SDA = AckValue; //应答状态
{
SDASET;
}
else
{
SDACLR;
}
_delay_us(30);//I2CDelay(3);
SCLSET;//SCL = 1;
_delay_us(50);//I2CDelay(5); //时钟低电平周期大于4μs--ZLG
SCLCLR;//SCL = 0; //清时钟线,钳住I2C总线以便继续接收--ZLG
_delay_us(150);//I2CDelay(15);
//SDA = 1;
return RDByte;
}
/*================================================================
【 Name 】void SoftReset(void)
【Function】SHT20软件复位,主函数中调用
【 Notes 】从高到低,依次接收
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
void SoftReset(void)
{
I2CInit(); //I2C initialize
I2CStart(); //start I2C
I2C_Write_Byte(SHT20ADDR&0xfe); //I2C address + write
I2C_Write_Byte(0xfe); //soft reset
I2CStop(); //stop I2C
}
/*================================================================
【 Name 】void SET_Resolution(void)
【Function】写寄存器,设置分辨率
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
void SET_Resolution(void)
{
I2CStart(); //Start I2C
if(I2C_Write_Byte(SHT20ADDR&0xfe)==ACK) //I2C address + write + ACK
{
if(I2C_Write_Byte(0xe6)==ACK) //写用户寄存器
{
//if(I2C_Write_Byte(0x83)==ACK); //设置分辨率 11bit RH% 测量时间:12ms(typ.) & 11bit T℃ 测量时间:9ms(typ.)
if(I2C_Write_Byte(0x02)==ACK);
//if(I2C_Write_Byte(0x06)==ACK); //自加热
_delay_ms(30);//Delay(6);
}
}
I2CStop(); //Stop I2C
}
/*================================================================
【 Name 】float ReadSht20(char whatdo)
【Function】非主机模式,读取函数函数
【 Notes 】
【 Author 】dingshidong
【 Data 】2012.08.07
================================================================*/
float ReadSht20(uchar whatdo)
{
// float temp,tttt,ttt,X;
unsigned long ttemp=0,X;
unsigned char MSB,LSB ,ZZ;// ,tt1,tt2,tt3,tt4;
float Temperature,Humidity;
unsigned int tt;
SET_Resolution();
I2CStart();
if(I2C_Write_Byte(SHT20ADDR&0xfe)==ACK) //I2C address + write + ACK
{
//_delay_ms(6);//Delay(6);
ZZ=I2C_Write_Byte(whatdo);
if(ZZ==ACK)
// if(I2C_Write_Byte(0XF5)==ACK) //Command
{
do
{
_delay_ms(30);//Delay(6);
I2CStart();
}while(I2C_Write_Byte(SHT20ADDR|0x01)==NACK); //I2C address + read + NACK
MSB = I2C_Read_Byte(ACK); //Data(MSB)
LSB = I2C_Read_Byte(ACK); //Data(LSB)
I2C_Read_Byte(NACK); //Checksum + NACK
I2CStop(); //Stop I2C
LSB &= 0xfc; //Data (LSB) 的后两位在进行物理计算前前须置‘0’
//十六进制转成十进制
if (whatdo==0xf5) //No Hold Master Mode,read humidity
{
/*-- calculate relative humidity [%RH] --*/
ttemp= MSB*256 + LSB;
ttemp =ttemp&0x0000ffff;
//计算出发送的湿度值 001~~~999
//ttemp=(((ttemp*125)&0x007dffff)*100)/65536-600;
//
ttemp=((((ttemp))*12500)/65536-600);
ttemp=ttemp+1000;//1000比SHT10低10%
//
g_ucTH_H = ttemp/100;
X=ttemp-g_ucTH_H*100;
g_ucTH_L=X;
//g_ucTH_L=LSB;//X;
//ttemp=1000;
//aa=MSB;
//bb=LSB;
// g_ucTC_H =(unsigned char)(ttemp>>24);;//ttt/100;
//g_ucTC_L=(unsigned char)(ttemp>>16);;
//g_ucTH_H =(unsigned char)(ttemp>>8);//MSB;//ttt/100;
//g_ucTH_L=(unsigned char)(ttemp);
//
tt=((unsigned int)(ttemp/10 ));
/*if(tt>1000)
{
tt=999;
}
if(tt<=1)
{
tt=1;
}
*/
//
tt=tt%1000;
g_ucSegnumber1=tt/100;
tt=tt%100;
g_ucSegnumber2=tt/10;
tt=tt%10;
g_ucSegnumber3=tt;
return Humidity; //返回值:humidity
}
else //No Hold Master Mode,read temperature
{
/*-- calculate temperature [°C] --*/
//ttemp =0;
ttemp = MSB*256 + LSB;
ttemp =ttemp&0x0000ffff;
//公式:T= -46.85 + 175.72 * ST/2^16
ttemp = ((ttemp*17572))/65536-4685;
//
g_ucTC_H = ttemp/100;
X=ttemp-g_ucTC_H*100;
g_ucTC_L=X;
//aa=MSB;
//bb=LSB;
//g_ucTC_H =(unsigned char)(ttemp>>8);;//ttt/100;
//g_ucTC_L=(unsigned char)(ttemp);;
//g_ucTH_H =(unsigned char)(ttemp>>8);//MSB;//ttt/100;
//g_ucTH_L=(unsigned char)(ttemp);
//g_ucTC_H =(unsigned char)(ttemp>>24);;//ttt/100;
//g_ucTC_L=(unsigned char)(ttemp>>16);;
//g_ucTH_H =(unsigned char)(ttemp>>8);//MSB;//ttt/100;
//g_ucTH_L=(unsigned char)(ttemp);
/*Temperature =Temperature *10;
if(Temperature>1000)
{
Temperature=1000;
}
if(Temperature<1)
{
Temperature=1;
}*/
tt=(unsigned int)(ttemp/10 );
tt=tt%1000;
g_ucSegnumber4=tt/100;
tt=tt%100;
g_ucSegnumber5=tt/10;
tt=tt%10;
g_ucSegnumber6=tt;
return Temperature; //返回值:temperature
}
}
}
return 0;
}
//------------------------------------------------------------------------
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
逻辑分析仪看过就是发0xF5没返回ACK
一周热门 更多>