⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shtxx_sample_code_ok_01.c

📁 这是单片机驱动温湿度传感器SHT11温湿度传感器的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************************
Project:          SHTxx demo program (V2.1)
Filename:         SHTxx_Sample_Code.c    

Prozessor:        80C51 family
Compiler:         Keil Version 6.14

Autor:            MST
Copyrigth:        (c) Sensirion AG      
***********************************************************************************/

//#include <AT89s53.h> //Microcontroller specific library, e.g. port definitions
#include <SST89x5x4.H>

#include <intrins.h> //Keil library (is used for _nop()_ operation)  
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library

#define uchar unsigned  char
#define uint unsigned int
#define lcd_clr 0x01
#define you_on	0x0f
#define ad_n 12		//ad测试次数
#define  _Nop()  _nop_()        /*定义空指令*/

/*
keyboard	data
0		12
1		8
2		4
3		0
4		1
5		2
6		3
7		5
8		6
9		7
10-ok	9
11		10
12-wrong11
13		13
14		14
15		15
*/	

//全局变量定义
sbit rs = P1^7;
sbit rw  = P1^6;
sbit e = P2^1;
sbit lcd_deng = P2^3;
sbit le = P2^6;
sbit ce = P2^4;


//ad_bits

sbit sta = P3^2;
sbit lben = P3^6;
sbit hben = P3^7;
//sbit ce = P2^4; 




/*端口位定义*/
sbit SDA = P3^3;            /*模拟I2C数据传送位*/
sbit SCL = P1^4;            /*模拟I2C时钟控制位*/
sbit WP = P1^3;	
/*状态标志*/
bit ack = 0 ;	         /*应答标志位*/
uchar s;
//uchar ad_data[2]={0};




//函数申明
void lcd_ini(void);	
void lcd_wrc(uchar com);
void lcd_wrd(uchar dat);
void lcd_checkbusy();
void delay(uchar n);
void ldelay(uchar n);
void lcd_on();
void lcd_off();
uchar lcd_read_ac();
void lcd_dis_num(uint dat);
void lcd_dis_ch(uchar h,uchar l);
void lcd_add(uchar h,uchar l);

//keyboard
uchar key_data(void);


//i2c相关函数
void Start_I2c();		//起动总线函数
void Stop_I2c();		//结束总线函数
void  SendByte(uchar c);		//字节数据传送函数send
uchar  RcvByte();		//字节数据传送函数 receive
void Ack_I2c(bit a);		//主控器进行应答信号
bit ISendStr_8(uchar add,uchar son_add,uchar dat);		//向子地址为8位的器件发送多字节数据函数 
bit ISendStr_16(uchar add,uint son_add,uchar dat);		//向子地址为16位的器件发送多字节数据函数 
uchar IRcvStr_8(uchar add,uchar son_add);		//向子地址为8位的器件读取多字节数据函数
uchar IRcvStr_16(uchar add,uint son_add);		//向子地址为16位的器件读取多字节数据函数



//时钟相关
void lcd_dis_time(void);		//时钟显示函数
void set_time(uchar sec, uchar min, uchar hr, uchar dy, uchar dt,uchar mn,uchar yr);		//时钟设置sec, min, hr, dy, dt, mn, yr

//ad相关
uint ad_ce(void);
uint ad_ce_n(void);




//总线控制--使能和释放
void ad_en(void);
void lcd_en(void);
void three_en(void);

typedef union 
{
	unsigned int i;
	float f;
} value;
//value 代表上面的一个共用体类型。可用来定义变量
//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};

//#define	DATA   	P1_1
//#define	SCK   	P1_0
sbit DATA = P3^5;
sbit SCK = P1^5;

#define noACK 0
#define ACK   1
                            //adr  command  r/w
#define STATUS_REG_W 0x06   //000   0011    0
#define STATUS_REG_R 0x07   //000   0011    1
#define MEASURE_TEMP 0x03   //000   0001    1
#define MEASURE_HUMI 0x05   //000   0010    1
#define RESET        0x1e   //000   1111    0



/*
void service_int0() interrupt 0 using 0		//带数组型全局变量
{
	uint aa = 0;
//	IE0 = 0;	//先清中断标志
	uchar ad_data[2]={0};
	ad_en();
	hben = 1;
	lben = 0;
	delay(2);
	ad_data[0] = P0;
	delay(2);
	hben = 0;
	lben = 1;
	delay(2);
	ad_data[1] = P0;

//	EX0 = 1;
//	IT0 = 1;
//	ad_data[1] = ad_data&0x1f;
//	ad_data[1] = ad_data[1]<<8;
//	return(ad_data[1]<<8+ad_data[0]);
}
*/

uint ad_ce(void)
{
//ad读
	uchar i=0;
	uchar v=0;
	uint dat_ad=0;
//		if(sta == 0)
		while(sta == 0)
		{
			P0 = 0XFF;
			delay(10);

//			if(sta == 0)
//			{
//				P0 = 0XFF;
				lben = 0;
				hben = 1;
				ad_en();
				_nop_();
				i = P0;
				ce = 1;
				_nop_();

				hben = 0;
				lben = 1;
				ad_en();
				_nop_();
				v = P0&0x0f;
				dat_ad = v*256+i;

//				lcd_en();
//				lcd_add(2,1);
//				lcd_dis_num(v);
//				lcd_dis_num(i);
//				lcd_dis_num(dat_ad);
//				dat_ad_xian = (float)(dat_ad*1.28/2.048);
// 				dat_ad_xian = (float)(dat_ad/2.048);
//				lcd_dis_num((uint)dat_ad_xian);
//				v = P0&0X30;
//				v = v>>4;
//				lcd_dis_num(v);
//				ldelay(80);
//			}
		
		}
		return(dat_ad);
//ad读结束
}

uint ad_ce_n(void)		//ad测试n(ad_n)次取平均
{
	uchar i=0;
	uchar m=0;
	uchar n=0;
	uint a[ad_n]={0};

	for(i=0;i<ad_n;i++)
	{
		a[i]=ad_ce();
		delay(10);
	}
/*
	a[0] = ad_ce();
	a[1] = ad_ce();
	lcd_add(3,1);
	lcd_dis_num(a[0]);
	lcd_dis_num(a[1]);
*/	
	lcd_add(3,1);
	for(i=0;i<ad_n;i++)
	{
		lcd_dis_num(a[i]);
	}

	return(0);

}

void lcd_dis_time(void)		//时钟显示函数
{
	uchar i=0;
	i = IRcvStr_8(0xd0,0x00);
	i = ((i&0x70)>>4)*10+(i&0x0f);
	lcd_add(3,7);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x01);
	i = ((i&0x70)>>4)*10+(i&0x0f);
	lcd_add(3,4);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x02);
	i = ((i&0x30)>>4)*10+(i&0x0f);
	lcd_add(3,1);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x03);
	i = i&0x07;
	lcd_add(4,1);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x04);
	i = ((i&0x30)>>4)*10+(i&0x0f);
	lcd_add(2,7);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x05);
	i = ((i&0x10)>>4)*10+(i&0x0f);
	lcd_add(2,4);
	lcd_dis_num(i);
	i = IRcvStr_8(0xd0,0x06);
	i = ((i&0xf0)>>4)*10+(i&0x0f);
	lcd_add(2,1);
	lcd_dis_num(i);
}

void set_time(uchar sec, uchar min, uchar hr, uchar dy, uchar dt,uchar mn,uchar yr)		//时钟设置sec, min, hr, dy, dt, mn, yr
{
	uchar i;
	lcd_add(4,1);
	i = ISendStr_8(0xd0,0x00,0);
	lcd_wrd(0x30+(uchar)i);
	sec = ((sec/10)<<4)+(sec%10);
	i = ISendStr_8(0xd0,0x00,sec);
	lcd_wrd(0x30+(uchar)i);
	min = ((min/10)<<4)+(min%10);
	i = ISendStr_8(0xd0,0x01,min);
	lcd_wrd(0x30+(uchar)i);
	hr = ((hr/10)<<4)+(hr%10);
	i = ISendStr_8(0xd0,0x02,hr);
	lcd_wrd(0x30+(uchar)i);

	i = ISendStr_8(0xd0,0x03,dy);
	lcd_wrd(0x30+(uchar)i);
	dt = ((dt/10)<<4)+(dt%10);
	i = ISendStr_8(0xd0,0x04,dt);
	lcd_wrd(0x30+(uchar)i);
	mn = ((mn/10)<<4)+(mn%10);
	i = ISendStr_8(0xd0,0x05,mn);
	lcd_wrd(0x30+(uchar)i);
	yr = ((yr/10)<<4)+(yr%10);
	i = ISendStr_8(0xd0,0x06,yr);
	lcd_wrd(0x30+(uchar)i);
}


void ad_en(void)
{

	e = 0;	//lcd not enable
	le = 0;	//three-states latched
	ce = 0;	//ad enable

}
void lcd_en(void)
{
	ce = 1;	//ad not enable
	le = 0;	//three-states latched
	e = 1;	//lcd enable
}

void three_en(void)
{
	ce = 1;	//ad not enable
	e = 0;	//lcd not enable
	le = 1;	//tree-states open
}


void lcd_ini()
{
	delay(100);
	lcd_wrc(0x34);
	delay(10);
	lcd_wrc(0x30);
	delay(10);
	lcd_wrc(0x01);
	delay(10);
	lcd_wrc(0x06);
	delay(10);
	lcd_wrc(0x0c);
	delay(200);
}	
void lcd_wrc(uchar com)
{
	lcd_en();
	lcd_checkbusy();
	rs = 0;
	rw = 0;
	P0 = com;
	e = 1;
	delay(10);
	e = 0;
}

void lcd_wrd(uchar dat)
{
//	checkbusy();
	lcd_en();
	lcd_checkbusy();
	rs = 1;
	rw = 0;
	P0 = dat;
	e = 1;
	delay(5);
	e = 0;
}
void lcd_checkbusy()
{
	
	uchar busy = 0;
	lcd_en();
	P0 = 0XFF;
	busy = P0;
	if(busy>0x7f)
	{
		rs = 0;
		rw = 1;
		e = 1;
		busy = P0;
		e = 0;
		delay(10);
	}
}
uchar lcd_rdd();
void delay(uchar n)
{
	while(n--);
}

void ldelay(uchar n)
{
	uchar a=250;
	while(a--)
	{
    	while(n--);
	}
}


void lcd_on()
{
	lcd_deng = 0;
}
void lcd_off()
{
	lcd_deng = 1;
}
uchar lcd_read_ac()
{
	uchar dat = 0;
	lcd_en();
//	P0 = 0X00;
	e = 1;
	rs = 0;
	rw = 1;
//	e = 1;
	delay(10);
	dat = P0;
//	delay(10);
//	e = 0;
	return(dat&0x7f);
}
void lcd_dis_num(uint dat)
{
    uint a=0;
    dat =dat%10000;
    a =dat/1000;
    lcd_wrd(0x30+a);
    dat =dat%1000;
    a =dat/100;
    lcd_wrd(0x30+a);
    dat =dat%100;
    a=dat/10;
    lcd_wrd(0x30+a);
    dat =dat%10;
    lcd_wrd(0x30+dat);
}
void lcd_dis_ch(uchar h,uchar l)
{
    lcd_wrd(h);
    lcd_wrd(l);
}

void lcd_add(uchar h,uchar l)       //定位地址
{
  l--;
  switch(h)
  {
    case 1:
    {
      lcd_wrc(0x80+l);
      break;
    }
    case 2:
    {
      lcd_wrc(0x90+l);
      break;
    }
    case 3:
    {
      lcd_wrc(0x88+l);
      break;
    }
    case 4:
    {
      lcd_wrc(0x98+l);
      break;
    }
  }
}



unsigned char key_data()      //判断键值
{
	uchar a=0,b=0,c=0,d=0,i=0;
  	a = 0xef;
  	for(i = 0;i<4;i++)      //读行
	{
	    P1 = a;
		delay(10);
	    b = P1;
		b = b&0x0f;
//    	b = b>>4;
	    if(b!=0x0F)   //表示有键按下
    	{
			delay(200);   //软件延时   确认有键按下
			b = P1&0X0F;
//	    	b = b>>4;
      		if(b != 0x0F)
      		{  
//	        	return b;

				c=b;
		        if(c==0X07)
		        {
	          		d=i*4+3;
		        }
		        else if(c==0X0B)
		        {
		          	d=i*4+2;
		        }
		        else if(c==0X0D)
		        {
		          	d=i*4+1;
		        }
		        else if(c==0X0E)
		        {
		          	d=i*4;
		        }
			    break;
			}
		}
    	else
	    {
	      	a = a<<1;
			a = a+0x01;
	      	if(a==0xFF)
	      	{
//	        	return 0x0f;
				d = 0x0f+1;
				break;
	      	}
    	}
	}
	return d;
}



void Start_I2c()		//起动总线函数
{
	SDA=1;   //发送起始条件的数据信号
	_Nop();
	SCL=1;
	_Nop();    //起始条件建立时间大于4.7us,延时
	_Nop();
	_Nop();
	_Nop();
	_Nop();    
	SDA=0;   //发送起始信号
	_Nop();    // 起始条件锁定时间大于4
	_Nop();
	_Nop();
	_Nop();
	_Nop();       
	SCL=0;   //钳住I2C总线,准备发送或接收数据 
	_Nop();
	_Nop();
}

void Stop_I2c()		//结束总线函数
{
	SDA=0;  /*发送结束条件的数据信号*/
	_Nop();   /*发送结束条件的时钟信号*/
	SCL=1;  /*结束条件建立时间大于4*/
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	_Nop();
	SDA=1;  /*发送I2C总线结束信号*/
	_Nop();
	_Nop();
	_Nop();
	_Nop();
}



void  SendByte(uchar c)		//字节数据传送函数send
{
 	uchar BitCnt;
 	for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
    {
     	if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
       	else  SDA=0;                
     	_Nop();
     	SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
      	_Nop(); 
      	_Nop();               /*保证时钟高电平周期大于4*/
      	_Nop();
      	_Nop();
      	_Nop();  
     	SCL=0; 
    }
    _Nop();
    _Nop();
    SDA=1;               /*8位发送完后释放数据线,准备接收应答位*/
    _Nop();
    _Nop();   
    SCL=1;
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1)ack=0;     
    else ack=1;        /*判断是否接收到应答信号*/
    SCL=0;
    _Nop();
    _Nop();
}


uchar  RcvByte()		//字节数据传送函数 receive
{
  	uchar retc;
  	uchar BitCnt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -