上传一个自己调的HIH6xxx系列的温湿度传感器给需要的朋友。 为i2c协议。 有疑问的联系我。qq:244928599 .本人水平有限。
i2c 为IO口模拟。
#include<reg52.h> //#include<intrins.h> #define uchar unsigned char #define uint unsigned int uchar temp,aa,numdu,numwe; sbit dula=P2^6; sbit wela=P2^7; uchar data1[]={0,0,0,0}; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar code tablewe[]={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //void delay(uint z); void show_num(unsigned int num); sbit scl=P2^0; //6pin sbit sda=P2^1; //5pin void i2c_delay() //I2C专用延时,大概6.5us { volatileuchar k; //避免被软件优化去掉。 k++; k--; } void i2c_start() //I2C 启动信号产生 { sda=1; scl=1; i2c_delay();//6.5us sda=0; i2c_delay();//6.5us scl=0; } void i2c_send(uchar dat) //按照I2c协议发送8 bit { uchari; for(i=0;i<8;i++) { scl=0; if(dat&0x80) //高位先发。判断最高位是否为1. sda=1; else sda=0; scl=1; dat<<=1; } } uchar wait_ack() //等待应答。返回0:应答。返回1:表示没有应答。 { ucharst; scl=0; sda=1; scl=1; //创造应答条件(追发一个1) st=0; while(sda==1) //等待从机拉低,以示应答。 { st++; if(st>=250) //给250次机会时间等待。 { scl=0; return1;//应答失败。 } } scl=0; return0; //应答成功 } uchar i2c_receice() //按照I2C协议接收8 bit数据 { uchard,i; for(i=0;i<8;i++) { scl=1; d<<=1; if(sda==1) d++; //d|=0x01; scl=0; } returnd; } void i2c_stop() //I2C停止信号。 { scl=0; sda=0; i2c_delay();//6.5us scl=1; sda=1; i2c_delay();//6.5us } void ack() { sda=0; i2c_delay();//6.5us scl=1; i2c_delay();//6.5us scl=0; i2c_delay();//6.5us sda=1; i2c_delay();//6.5us } void nack() { sda=1; i2c_delay();//6.5us scl=1; i2c_delay();//6.5us scl=0; i2c_delay();//6.5us sda=1; i2c_delay();//6.5us } float value = 0; uchar bit1=0; unsigned long int ret = 0; void hih6131ValueGet(uchar type) { staticuint k=0; /* * 启动传感器转换 */ if(bit1==0) { bit1=1; i2c_start(); i2c_send(0x4e); // 寄存器地址0x27 wait_ack(); i2c_stop(); } k++; /* * 读取传感器值 */ if(k>=200) { k=0; bit1=0; i2c_start(); i2c_send(0x4F); wait_ack(); i2c_delay();//6.5us data1[0]=i2c_receice(); ack(); data1[1]=i2c_receice(); ack(); data1[2]=i2c_receice(); ack(); data1[3]=i2c_receice(); i2c_delay();//6.5us nack(); i2c_delay();//6.5us i2c_stop(); if ((data1[0] & 0xc0) != 0) { ret=4444; // 返回错误 } else { if(type) { value = ((data1[2] <<8) +data1[3]) >> 2; // 温度,保存小数点后3位 value = value * 165 / 16382-40; } else { value = (data1[0] & 0x3F) * 256 + data1[1]; value = (value * 100) / 16382; // 湿度,保存小数点后3位 } ret = value * 100; } } } sbit KEY=P3^4; //定义按键的输入端S2键 bit keybit=0; void Key_Scan(void) { staticunsigned char i; staticunsigned char j; if(KEY==0) { if(i==0) { j++; if(j<5) { i=1; keybit=!keybit; } } } else { i=j=0; } } void main() { while(1) { Key_Scan(); //按键扫描函数 切换由按键完成 if(keybit==0) //不按下的时候显示温度 { hih6131ValueGet(1); } else //按下的时候显示湿度 { hih6131ValueGet(0); } show_num(ret); //显示数值。 } } void delay(uint z) { uintx,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void show_num(unsigned int num) { /* dula=1; P0=table[num/10000]; dula=0; P0=0xff; wela=1; P0=tablewe[1]; wela=0; delay(3); */ dula=1; P0=table[num%10000/1000]; dula=0; P0=0xff; wela=1; P0=tablewe[2]; wela=0; delay(5); dula=1; P0=table[num%1000/100]; dula=0; P0=0xff; wela=1; P0=tablewe[3]; wela=0; delay(5); dula=1; P0=table[num%100/10]; dula=0; P0=0xff; wela=1; P0=tablewe[4]; wela=0; delay(5); dula=1; P0=table[num%10]; dula=0; P0=0xff; wela=1; P0=tablewe[5]; wela=0; delay(5); }
|