|
发表于 2015-5-8 19:57:45
|
显示全部楼层
本帖最后由 chun_hua82 于 2015-5-8 22:55 编辑
各位师傅帮我看看 这代码哪里有问题,完全用的楼主的代码,就是读不出SHT20温度湿度,if(I2C_Write_Byte(SHT20ADDR&0xfe)==ACK)把这段屏蔽掉就能读出数据但是数据不对实际温度是20几度读出的温度有50多度了,不知道哪里出了问题- #include<STC89C5.h> //12M
- #include <intrins.h>
- typedef unsigned char uint8;
- typedef signed char fuint8;
- typedef unsigned int uint16;
- typedef signed int fuint16;
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #define TC 0xF3 //温度测量
- #define SH 0xF5 //湿度测量
- #define WR 0xE6 //写寄存器
- #define RD 0xE7 //读寄存器
- #define RST 0xFe //软复位
- /*================================================================
- 【 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 //非应答信号
-
- #define led_duan P0 //数码管段选//
- #define led_wei P2 //数码管位选//
- fuint16 value;
- fuint16 ys;
- bit dian = 0;
- bit ad_ok = 0;
- sbit wei_1 = P2^0;
- sbit wei_2 = P2^1;
- sbit wei_3 = P2^2;
- sbit wei_4 = P2^3;
- sbit wei_5 = P2^4;
- sbit wei_6 = P2^5;
- sbit wei_7 = P2^6;
- sbit led_dian = P0^5;
- sbit SDA = P3^4;
- sbit SCL = P3^3;
- uint8 xsjs = 0;
- uint16 pca_s=0;
- uint16 wendu,shidu;
- uint8 xszc[7]; //显示缓冲区
- uint8 code duan_ma[] = {
- 0x28,/*0*/
- 0x7E,/*1*/
- 0xA2,/*2*/
- 0x62,/*3*/
- 0x74,/*4*/
- 0x61,/*5*/
- 0x21,/*6*/
- 0x7A,/*7*/
- 0x20,/*8*/
- 0x60,/*9*/
- };
- uint8 code wei_ma [] = {0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD};
- /*================================================================
- 【 Name 】void Delay(uint t)
- 【Function】delay Nms
- 【 Notes 】
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- void Delay(uint t)
- {
- uchar i;
- while(t--)
- {
- for(i=0;i<200;i++);
- }
- }
- /*------------------------------------------------------------*/
- /**********************Simulation I2C Function*****************/
- /*------------------------------------------------------------*/
- /*================================================================
- 【 Name 】void I2CDelay (uchar t)
- 【Function】模拟IIC用的短延时 us
- 【 Notes 】
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- void I2CDelay (uchar t)
- {
- while(t--);
- }
- /*================================================================
- 【 Name 】void I2CInit(void)
- 【Function】I2C初始化,空闲状态
- 【 Notes 】
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- void I2CInit(void)
- {
- SDA = 1;
- I2CDelay(1);
- SCL = 1;
- I2CDelay(1);
- }
- /*================================================================
- 【 Name 】void I2CStart(void)
- 【Function】I2C起始信号
- 【 Notes 】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- void I2CStart(void)
- {
- SDA = 1; //发送起始条件的数据信号--ZLG
- SCL = 1;
- I2CDelay(5); //起始条件建立时间大于4.7us,延时--ZLG
- SDA = 0; //发送起始信号-ZLG
- I2CDelay(5); //起始条件锁定时间大于4μs--ZLG
- SCL = 0; //钳住I2C总线,准备发送或接收数据--ZLG
- I2CDelay(5);
- }
- /*================================================================
- 【 Name 】void I2CStop(void)
- 【Function】I2C停止信号
- 【 Notes 】SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- void I2CStop(void)
- {
- SDA = 0; //发送结束条件的数据信号--ZLG
- SCL = 0;
- I2CDelay(5);
- SCL = 1; //发送结束条件的时钟信号--ZLG
- I2CDelay(5); //结束条件建立时间大于4μs--ZLG
- SDA = 1; //发送I2C总线结束信号--ZLG
- I2CDelay(5);
- }
- /*================================================================
- 【 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;
- for(i=0;i<8;i++) //要传送的数据长度为8位--ZLG
- {
- if(Write_Byte&0x80) //判断发送位--ZLG
- {
- SDA = 1;
- }
- else
- {
- SDA = 0;
- }
- I2CDelay(1);
- SCL=1; //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
- I2CDelay(5); //保证时钟高电平周期大于4μs--ZLG
- SCL=0;
- I2CDelay(1);
- Write_Byte <<= 1;
- }
- I2CDelay(4);
- SDA = 1; //8位发送完后释放数据线,准备接收应答位-ZLG
- SCL = 1; //MCU告知SHT2X数据发送完毕,等待从机的应答信号
- I2CDelay(5);
- /*以下是判断I2C总线接收应到应答信号是ACK还是NACK*/
- if(SDA==1) //SDA为高,收到NACK
- return NACK;
- else //SDA为低,收到ACK
- return ACK;
- SCL=0;
- I2CDelay(15);
- }
- /*================================================================
- 【 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;
- SCL=0; //置时钟线为低,准备接收数据位--ZLG
- SDA = 1; //释放总线,置数据线为输入方式--ZLG
- for (i=0;i<8;i++)
- {
- SCL = 1; //SCL高电平期间,采集SDA信号,并作为有效数据 //置时钟线为高使数据线上数据有效--ZLG
- I2CDelay(2);
- RDByte <<= 1; //移位
- if(SDA==1) //采样获取数据
- {
- RDByte |= 0x01;
- }
- else
- {
- RDByte &= 0xfe;
- }
- I2CDelay(1);
- SCL = 0; //下降沿,从机给出下一位值
- I2CDelay(6);
- }
- /*以下是I2C总线发送应答信号ACK或者NACK*/
- SDA = AckValue; //应答状态
- I2CDelay(3);
- SCL = 1;
- I2CDelay(5); //时钟低电平周期大于4μs--ZLG
- SCL = 0; //清时钟线,钳住I2C总线以便继续接收--ZLG
- 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.)
- }
- }
- I2CStop(); //Stop I2C
- }
- /*================================================================
- 【 Name 】float ReadSht20(char whatdo)
- 【Function】非主机模式,读取函数函数
- 【 Notes 】
- 【 Author 】dingshidong
- 【 Data 】2012.08.07
- ================================================================*/
- float ReadSht20(char whatdo)
- {
- float temp;
- uchar MSB,LSB;
- float Humidity,Temperature;
- SET_Resolution();
- I2CStart();
- // if(I2C_Write_Byte(SHT20ADDR&0xfe)==ACK) //I2C address + write + ACK 这个函数屏蔽掉才读出数据但是数据好像不对,读出的温度50多度环境温度只有20几度
- {
- if(I2C_Write_Byte(whatdo)==ACK) //Command
- {
- do
- {
- 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’
- temp = MSB*256 + LSB; //十六进制转成十进制
- if (whatdo==((char)0xf5)) //No Hold Master Mode,read humidity
- {
- /*-- calculate relative humidity [%RH] --*/
- Humidity =(temp*125)/65536-6; //公式: RH%= -6 + 125 * SRH/2^16
- return Humidity; //返回值:humidity
- }
- else //No Hold Master Mode,read temperature
- {
- /*-- calculate temperature [°C] --*/
- Temperature = (temp*175.72)/65536-46.85; //公式:T= -46.85 + 175.72 * ST/2^16
- return Temperature; //返回值:temperature
- }
- }
- }
- return 0;
- }
- //=========================================显示数据分解===========================================
- void pv3_3_DATA(uint16 x)
- {
- uint8 a,b,c,d,e;
- a = x/10000;
- b = x%10000/1000;
- c = x%1000/100;
- d = x%100/10;
- e = x%10;
- xszc[2]=a;
- xszc[3]=b;
- xszc[4]=c;
- xszc[5]=d;
- xszc[6]=e;
- }
- //=====================================================================================
- void main(void)
- {
- TMOD = 0x01;
- TH0 = 0xF6;
- TL0 = 0x3C;
-
- TR0 = 1;
- ET0 = 1;
- EA = 1;
- while(1)
- {
- if(ad_ok == 1)
- {
- // EA = 0;
- shidu=(ReadSht20(TC)*100);//湿度
- // EA = 1;
- ad_ok = 0;
- }
- pv3_3_DATA(shidu);
-
- }
- }
- //================================================================================================
- void timer0(void) interrupt 1 using 2//
- {
- TH0 = 0xF6;
- TL0 = 0x3C;
- pca_s++;
- if(pca_s == 200)
- {
- ad_ok = 1;
- pca_s = 0;
- }
-
- led_wei = 0xFF;;
- switch(xsjs)
- {
- case 0: led_duan = duan_ma[xszc[xsjs]];wei_1=0;break;
- case 1: led_duan = duan_ma[xszc[xsjs]];wei_2=0;break;
- case 2: led_duan = duan_ma[xszc[xsjs]];wei_3=0;break;
- case 3: led_duan = duan_ma[xszc[xsjs]];wei_4=0;break;
- case 4: led_duan = duan_ma[xszc[xsjs]];led_dian=dian;wei_5=0;break;
- case 5: led_duan = duan_ma[xszc[xsjs]];wei_6=0;break;
- case 6: led_duan = duan_ma[xszc[xsjs]];wei_7=0;
- }
- xsjs++;
- if(xsjs == 7)xsjs = 0;
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|