#define uchar unsigned char
#define uint unsigned int
//数码管位定义
sbit dula = P2^6
sbit wela = P2^7
#define OK 1
#define ERROR 0
#define NUMBER 20
#define SIZE 5
sbit dht11 = P2^0
uchar status
//存放五字节数据的数组
uchar value_array[SIZE]
/*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
uchar flag
//数码管编码
uchar code array[]= {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
}
int temp_value, humi_value
void InitTime(void)
//void Delay_1ms(uint ms)
void SMG_Display(uint value)
void Delay_1ms(uint ms)
{
uint x, y
for(x = msx >0x--)
{
for(y = 124y >0y--)
}
}
void Delay_10us(void)
{
unsigned char i
i--
i--
i--
i--
i--
i--
}
/*读一个字节的数据*/
uchar ReadValue(void)
{
uchar count, value = 0, i
status = OK//设定标志为正常状态
for(i = 8i >0i--)
{
//高位在先
value <<= 1
count = 0
/做历宏/每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
while(dht11 == 0 &&count++ <NUMBER)
if(count >= NUMBER)
{
status = ERROR//设定错误标志
return 0//函数执行过程发生错误就退出函数
}
//26-28us 的高电平表示该位是0,为70us 高电平表该位1
Delay_10us()
Delay_10us()
Delay_10us()
//延时30us 后检测数据线是否还是高电平烂如
if(dht11 != 0)
{
//进入这里表示该位是1
value++
//等待剩余(约40us)的高电平结束
while(dht11 != 0 &&count++ <NUMBER)
{
dht11 = 1
}
if(count >= NUMBER)
{
status = ERROR//设定错误标志
return 0
}
}
}
return (value)
}
//读一次的数据,共五字节
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0
EA = 0
dht11 = 0//拉低数据线大于18ms 发送开始信号
Delay_1ms(20)//需大于18 毫纯册秒
dht11 = 1//释放数据线,用于检测低电平的应答信号
//延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
Delay_10us()
Delay_10us()
Delay_10us()
Delay_10us()
if(dht11 != 0) //检测应答信号,应答信号是低电平
{
//没应答信号
EA = 1
return ERROR
}
else
{
//有应答信号
while(dht11 == 0 &&count++ <NUMBER)//等待应答信号结束
if(count >= NUMBER) //检测计数器是否超过了设定的范围
{
dht11 = 1
EA = 1
return ERROR//读数据出错,退出函数
}
count = 0
dht11 = 1//释放数据线
//应答信号后会有一个80us 的高电平,等待高电平结束
while(dht11 != 0 &&count++ <NUMBER)
if(count >= NUMBER)
{
dht11 = 1
EA = 1
return ERROR//退出函数
}
//读出湿.温度值
for(i = 0i <SIZEi++)
{
value_array[i] = ReadValue()
if(status == ERROR)//调用ReadValue()读数据出错会设定status 为ERROR
{
dht11 = 1
EA = 1
return ERROR
}
//读出的最后一个值是校验值不需加上去
if(i != SIZE - 1)
{
//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
check_value += value_array[i]
}
}//end for
//在没用发生函数调用失败时进行校验
if(check_value == value_array[SIZE - 1])
{
//将温湿度扩大10 倍方便分离出每一位
humi_value = value_array[0] * 10
temp_value = value_array[2] * 10
dht11 = 1
EA = 1
return OK//正确的读出dht11 输出的数据
}
else
{
//校验数据出错
EA = 1
return ERROR
}
}
}
void main(void)
{
uchar mark = 0
//先等上电稳定
Delay_1ms(1000)
//因为读一次数据dht11 才会触发一次采集数据.
//即在先使用数据时采集一次数据
ReadTempAndHumi()
//因为在两次采集数据需一定的时间间隔,这里还可减少
Delay_1ms(3000)
//设定定时器
InitTime()
while(1)
{
//三秒读一次温湿度
if(flag == 60)
{
flag = 0
mark++
/*
//读温湿度,可检测函数调用是否失败,
//函数返回OK(1)表示成功,返回ERROR(0)表示失败
//OK和ERROR是在DHT11.H中定义的宏
*/
ReadTempAndHumi()
}
if(mark % 2 == 0)
{
//显示温度
SMG_Display(temp_value)
}
else
{
//显示湿度
SMG_Display(humi_value)
}
}
}
//设定定时器
void InitTime(void)
{
TH0 = (65535 - 50000)/256
TL0 = (65535 - 50000)%256
TMOD = 0X01
TR0 = 1
ET0 = 1
EA = 1
}
//数码管显示函数
void SMG_Display(uint value)
{
uchar ge, bai, shi
ge = value % 10
shi = value % 100 / 10
bai = value % 1000 / 100
wela=1
P0 = 0XFE
wela=0
P0 = 0XFF
dula=1
P0 = array[bai]
dula=0
Delay_1ms(2)
wela=1
P0 = 0XFD
wela=0
P0 = 0XFF
dula=1
P0 = array[shi]
P0 |= 0x80/*显示小数点*/
dula=0
Delay_1ms(2)
wela=1
P0 = 0XFB
wela=0
P0 = 0XFF
dula=1
P0 = array[ge]
dula=0
Delay_1ms(2)
}
//中断函数
void timer(void) interrupt 1
{
TH0 = (65535 - 50000)/256
TL0 = (65535 - 50000)%256
flag++
}
xrow = sht.Range("a1").CurrentRegion.Rows.Count - 1如果某尺灶个工作表里仅有一行数据,或者没有数据,这儿 xrow=0
然后,下面者缺的 .resize(xrow,13) 就首困辩会出错
把上面的-1去掉,应该就可以了。
这是一个温湿度检测的程序,可以参考一下:#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#include <absacc.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
sbit LcdRs=P2^0 //1602液晶端口定义
sbit LcdRw=P2^1
sbit LcdEn=P2^2
sbit led1=P3^0
sbit led2=P3^4 //报警灯端口定义
sbit ACC0=ACC^0
sbit ACC7=ACC^7
sbit k_ud=P2^4//定义上下限选择
sbit k_ws=P2^5//定义温度/湿度 选择
sbit k_add=P2^6//定义按键 +
sbit k_sub=P2^7//定义按键 -
bit flag_ud,flag_ws
bit start
uchar str[7]
//向LCD写命令
#define LCD_COMMAND 0//Command
#define LCD_DATA 1 //Data
#define LCD_CLEAR_SCREEN 0x01 //清屏
#define LCD_HOMING0X02 //光标返回原点
//设置显示模式
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关举念
#define LCD_CURSOR0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
//输入设置
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 //default
#define LCD_MOVE 0x01 //画面可平移
#define LCD_NO_MOVE 0x00 //default
unsigned char TEMP_UP=20 //温度上限
unsigned char TEMP_DOWN=0 //温度下限
unsigned char HUMUP=30//湿度上限
unsigned char HUMDOWN=10//湿度下限
unsigned char dis[4]
unsigned char LCD_Wait(void)
//SHT10设置
sbit SCK =P1^2 //定义通讯时钟端口
sbit DATA=P1^3 //定义通讯数据端口
typedef union
{ uint i//定义了两个共用体
float f
}value
enum {TEMP,HUMI}//TEMP=0,HUMI=1
#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 RESET0xle //运雹000 1111 0
//定义函数
void s_transstart(void) //启动传输函数
void s_connectionreset(void) //连接复位函数
char s_write_byte(unsigned char value)//SHT10写函数正悄困
char s_read_byte(unsigned char ack)//SHT10读函数
char s_measure(unsigned char*p_value,unsigned char*p_checksum,unsigned char mode)//测量温湿度函数
void calc_dht90(float*p_humidity,float*p_temperature)//温湿度补偿
void LCD_Write(bit style, unsigned char input)
//液晶显示子程序
void delay(uint z) //延时函数
{
int x
for(x=zx>0x--)
{
int y
for(y=110y>0y--)
}
}
void dat_char(uchar ff,uchar a)
{
dis[0]=ff
dis[1]='_'
dis[2]=0x30+a/10
dis[3]=0x30+a%10
}
void LCD_Write(bit style,unsigned char input)
{
LcdRs=style
P0=input
delay(5)
LcdEn=1
delay(5)
LcdEn=0
}
void LCD_SetDisplay(unsigned char DisplayMode) //设置输出
{
LCD_Write(LCD_COMMAND,0x08|DisplayMode)
}
void LCD_SetInput(unsigned char InputMode) //设置输入
{
LCD_Write(LCD_COMMAND,0x04|InputMode)
}
void LCD_Initial()//初始化LCD函数
{
LcdEn=0
LCD_Write(LCD_COMMAND,0x38) //8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38)
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR)//开启显示,无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN) //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE) //AC递增,画面不动
}
void GotoXY(uchar x, uchar y) //液晶字符输入的位置
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x)
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40))
}
void Rrint(uchar *str) //将字符输出到液晶显示
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str)
str++
}
}
void zhuanhuan(float a) //浮点数转换成字符串函数
{
memset(str,0,sizeof(str))
sprintf(str,"%f",a)
}
void welcome() //初始界面函数
{
LCD_Initial()
GotoXY(0,0)
Rrint(" Welcome! ")
GotoXY(0,1)
Rrint(" Code of sht10 ")
delay(200)
}
/*
void delay_n10us(uint n) //延时n个10us@12M晶振
{
uint i
for(i=ni>0i--)
{
_nop_()_nop_()_nop_()
_nop_()_nop_()_nop_()
}
} */
void s_transstart(void) //启动函数
{
DATA=1SCK=0
_nop_()
SCK=1
_nop_()
DATA=0
_nop_()
SCK=0
_nop_()_nop_()_nop_()
SCK=1
_nop_()
DATA=1
_nop_()
SCK=0
}
void s_connectionreset(void) //连接复位函数
{
uchar i
DATA=1SCK=0 //Initial state
for(i=0i<9i++) //9 SCK cycles
{
SCK=1
SCK=0
}
s_transstart()
}
char s_write_byte(unsigned char value)//SHT10写字节函数
{
uchar i,error=0
for (i=0x80i>0i/=2) //shift bie for masking
{
if(i&value)DATA=1 //masking value with i,write to SENSI-BUS
else DATA=0
SCK=1
_nop_()_nop_()_nop_() //pulswith approx. 3 us
SCK=0
}
DATA=1 //release DATA-line
SCK=1 //clk#9for ack
error=DATA //check ack(DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。
_nop_()_nop_()_nop_()
SCK=0
DATA=1//release DATA-line
return error //error=1 in case of no acknowledge//返回:0成功 1失败
}
//SHT10读取函数
char s_read_byte(uchar ack)
{
uchar i,val=0
DATA=1 //release DATA-line
for(i=0x80i>0i/=2)//shift bit for masking
{SCK=1
if(DATA)val=(val|i)//read bit
_nop_()_nop_()_nop_()//pulswith approx.3 us
SCK=0
}
if(ack==1)DATA=0//in case of"ack==1"pull down DATA-Line
else DATA=1//如果是校验(ack=0),读取完后结束通讯
_nop_()_nop_()_nop_() //pulswith approx. 3 us
SCK=1//clk#9 for ack
_nop_()_nop_()_nop_() //pulswith approx. 3 us
SCK=0
_nop_()_nop_()_nop_() //pulswith approx. 3 us
DATA=1 //release DATA-line
return val
}
//测量温湿度函数
char s_measure(uchar *p_value,uchar *p_checksum,uchar mode)
{
unsigned error=0
uint i
s_transstart() //transstart atart
switch(mode) //send command to sensor
{
case TEMP :error+=s_write_byte(MEASURE_TEMP)break
case HUMI :error+=s_write_byte(MEASURE_HUMI)break
default :break
}
for(i=0i<65535i++)if(DATA==0)break //wait until sensor has finishede the measurement
if(DATA)error+=1 //or timeout(~2 sec.)is reached
*(p_value) =s_read_byte(ACK) //read the first byte(MSB)
*(p_value+1)=s_read_byte(ACK) //read the second byte(LSB)
*p_checksum=s_read_byte(noACK) //read checksum
return error
}
void calc_sht90(float*p_humidity,float*p_temperature) //温湿度补偿函数
{
const float C1=-4.0//for 12 Bit
const float C2=+0.0405 //for 12 Bit
const float C3=-0.0000028 //for 12 Bit
const float T1=+0.01 //for 14 Bit@5V
const float T2=+0.00008 //for 14 Bit@5V
float rh=*p_humidity //rh: Humidity[Ticks]12 Bit
float t=*p_temperature//t: Temperature[Ticks]14 Bit
float rh_lin //rh_lin: Humidity linear
float rh_true //rh_true:Temperature compensated humidity
float t_C //t_C : Temperature[C]
t_C=t*0.01-40 //calc.temperature from ticks to [C]
rh_lin=C3*rh*rh+C2*rh+C1 //calc.humidity from ticks to[%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin //calc.temperature compensated humidity[%RH]
if(rh_true>100)rh_true=100 //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1 //the physical possible range
*p_temperature=t_C //return temperature[C]
*p_humidity=rh_true //return humidity[%RH]
}
void keyscan()
{
if(k_ud==0)
{
delay(10)//去抖动 100ms
if(k_ud==0)
{
while(!k_ud)
flag_ud = ~flag_ud
}
}
if(k_ws==0)
{
delay(10)//去抖动 100ms
if(k_ws==0)
{
while(!k_ws)
flag_ws = ~flag_ws
}
}
if(k_add==0)
{
delay(10)//去抖动 100ms
if(k_add==0)
{
while(!k_add)
GotoXY(12,0)
if(!flag_ws)
{
if(flag_ud){TEMP_UP++dat_char('T',TEMP_UP)}
else {TEMP_DOWN++dat_char('T',TEMP_DOWN)}
Rrint(&dis)
}
else
{
if(flag_ud){HUMUP++dat_char('H',HUMUP)}
else {HUMDOWN++dat_char('H',HUMDOWN)}
Rrint(&dis)
}
}
}
if(k_sub==0)
{
delay(10)//去抖动 100ms
if(k_sub==0)
{
while(!k_sub)
GotoXY(12,1)
if(!flag_ws)
{
if(flag_ud){TEMP_UP--dat_char('T',TEMP_UP)}
else {TEMP_DOWN--dat_char('T',TEMP_DOWN)}
Rrint(&dis)
}
else
{
if(flag_ud){HUMUP--dat_char('H',HUMUP)}
else {HUMDOWN--dat_char('H',HUMDOWN)}
Rrint(&dis)}
}
}
}
//主函数
void main()
{
value humi_val,temp_val
unsigned char error,checksum
bit status_th=0,status_ch=0
unsigned char cnt=0
LCD_Initial()
LcdRw=0
led1=0
led2=0
start=0
s_connectionreset()
welcome()//显示欢迎画面
delay(20000)
while(1)
{
cnt++
if(!(cnt%10))
{
cnt=0
error=0
error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI)
error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP)
if(error!=0)
{
s_connectionreset() //in case of an erroe:connection reset
}else
{
humi_val.f=(float)humi_val.i //converts integer to float
temp_val.f=(float)temp_val.i //converts integer to float
calc_sht90(&humi_val.f,&temp_val.f)//计算温度与湿?
LCD_Initial()
GotoXY(0,0)
Rrint("Tep:")
GotoXY(0,1)
Rrint("Hum:")
zhuanhuan(temp_val.f) //转换温度为uchar方便液晶显示
GotoXY(4,0)
str[5]=0xDF //℃的符号
str[6]=0x43
str[7]='\0'
Rrint(str)
if(temp_val.f>TEMP_UP-1||temp_val.f<TEMP_DOWN)
led1=1
else
led1=0
zhuanhuan(humi_val.f) //转换湿度为uchar方便液晶显示
GotoXY(4,1)
str[5]='%' //%的符号
str[6]='\0' //字符串结束标志
Rrint(str)
if((humi_val.f>HUMUP-1)||(humi_val.f<HUMDOWN))
led2=1
else
led2=0
}
}
if(!flag_ws) {GotoXY(12,0)dat_char('T',TEMP_UP)Rrint(&dis)GotoXY(12,1)dat_char('T',TEMP_DOWN)Rrint(&dis)}
else {GotoXY(12,0)dat_char('H',HUMUP)Rrint(&dis)dat_char('H',HUMDOWN)GotoXY(12,1)Rrint(&dis)}
keyscan()
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)