📄 shtxx_sample_code_ok_01.c
字号:
/***********************************************************************************
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 + -