标题:
单片机12864显示光照强度和温湿度 程序问题
[打印本页]
作者:
hyg1997
时间:
2019-10-14 10:29
标题:
单片机12864显示光照强度和温湿度 程序问题
基于51单片机的用12864显示光照强度和温湿度,想多加两个温度过高或过低的指示灯,不知道为什么只能一个灯亮,温度变化灯也不会改变
单片机源程序如下:
#include <REG51.H>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define DataPort P0 //LCD1602数据端口
sbit SCL=P2^1; //IIC时钟引脚定义
sbit SDA=P2^2; //IIC数据引脚定义
sbit CS=P2^5; //片选信号
sbit SID=P2^6; //数据信号
sbit SCLK=P2^7; //时钟信号
sbit RST=P2^3; //复位信号
sbit CH = P2^4; //并行、串行选择信号
sbit dht_dat=P2^0; //用哪个I/O口自选,注意不要用P3口
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit FAN=P1^2;
sbit key1=P1^3;
sbit key2=P1^4;
sbit buzzer=P1^5;
uchar dht_num=0; //用于while循环中计数,超时则跳出循环
uchar code table[]={"温度:"};
uchar code table1[]={"湿度:"};
uchar code table2[]={"℃"};
uchar dht_d1=0,dht_d2=0,shidu=0 ; //依次为湿度整数部分和湿度小数部
uchar dht_t1=0,dht_t2=0 ,wendu=0 ; //依次为温度整数部分和温度小数部分
uchar dht_j=0; //和校验,可选择是否使用,具体参照数据手
uchar i,t11,t12,d11,d12;
uchar t21,t22,d21,d22;
#define SlaveAddress 0x46 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
//ALT ADDRESS引脚接地时地址为0x46,接电源时地址为0xB8
typedef unsigned char BYTE;
typedef unsigned short WORD;[/font]
[font=黑体]BYTE BUF[8]; //接收数据缓存区
uchar ge,shi,bai,qian,wan; //显示变量
int dis_data; //变量[/font]
[font=黑体]void delay_nms(unsigned int k);
void InitLcd();
void Init_BH1750(void);[/font]
[font=黑体]void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar DData);
void conversion(uint temp_data);[/font]
[font=黑体]void Single_Write_BH1750(uchar REG_Address); //单个写入数据
uchar Single_Read_BH1750(uchar REG_Address); //单个读取内部寄存器数据
void Multiple_Read_BH1750(); //连续的读取内部寄存器数据
//------------------------------------
void Delay5us();
void Delay5ms();
void BH1750_Start(); //起始信号
void BH1750_Stop(); //停止信号
void BH1750_SendACK(bit ack); //应答ACK
bit BH1750_RecvACK(); //读ack
void BH1750_SendByte(BYTE dat); //IIC单个字节写
BYTE BH1750_RecvByte(); //IIC单个字节读[/font]
[font=黑体]//-----------------------------------[/font]
[font=黑体]//*********************************************************
void conversion(uint temp_data) // 数据转换出 个,十,百,千,万
{
wan=temp_data/10000+0x30 ;
temp_data=temp_data%10000; //取余运算
qian=temp_data/1000+0x30 ;
temp_data=temp_data%1000; //取余运算
bai=temp_data/100+0x30 ;
temp_data=temp_data%100; //取余运算
shi=temp_data/10+0x30 ;
temp_data=temp_data%10; //取余运算
ge=temp_data+0x30;
}[/font]
[font=黑体]//毫秒延时**************************
void delay_nms(unsigned int k)
{
unsigned int i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}}
}
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0; i<t; i++)
for(j=0; j<10; j++);
}
void sendbyte(unsigned char zdata)
{
unsigned int i;
for(i=0; i<8; i++)
{
if((zdata << i) & 0x80)
{
SID = 1;
}
else
{
SID = 0;
}
SCLK = 0;
SCLK = 1;
}
}[/font]
[font=黑体]/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)
{
CS = 1;
sendbyte(0xf8);
sendbyte(cmdcode & 0xf0);
sendbyte((cmdcode << 4) & 0xf0);
delay(2);
}[/font]
[font=黑体]/********************************************************************
* 名称 : write_data()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_data(unsigned char Dispdata)
{
CS = 1;
sendbyte(0xfa);
sendbyte(Dispdata & 0xf0);
sendbyte((Dispdata << 4) & 0xf0);
delay(2);
}[/font]
[font=黑体]/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit()
{
RST = 0;
delay(100);
RST = 1;
delay(20000);
write_com(0x30);
delay(50);
write_com(0x0c);
delay(50);
}[/font]
[font=黑体]/********************************************************************
* 名称 : hzkdis()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void hzkdis(unsigned char code *s)
{
while(*s > 0)
{
write_data(*s);
s++;
delay(50);
}
}[/font]
[font=黑体]/********************************************************************
* 名称 : Test()
* 功能 : 显示子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/[/font]
[font=黑体]void DisplayOneChar(uchar DData)
{
//Y&=4;
//X&=15;
//if(Y)X|=0x40;
//X|=0x80;
//WriteCommandLCM(X,0);
write_data(DData);
} [/font]
[font=黑体]/**************************************
延时5微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数,注意时钟过快时需要修改
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}[/font]
[font=黑体]/**************************************
延时5毫秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5ms()
{
WORD n = 560;[/font]
[font=黑体] while (n--);
}[/font]
[font=黑体]/**************************************
起始信号
**************************************/
void BH1750_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 0; //产生下降沿
Delay5us(); //延时
SCL = 0; //拉低时钟线
}[/font]
[font=黑体]/**************************************
停止信号
**************************************/
void BH1750_Stop()
{
SDA = 0; //拉低数据线
SCL = 1; //拉高时钟线
Delay5us(); //延时
SDA = 1; //产生上升沿
Delay5us(); //延时
}[/font]
[font=黑体]/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(bit ack)
{
SDA = ack; //写应答信号
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
}[/font]
[font=黑体]/**************************************
接收应答信号
**************************************/
bit BH1750_RecvACK()
{
SCL = 1; //拉高时钟线
Delay5us(); //延时
CY = SDA; //读应答信号
SCL = 0; //拉低时钟线
Delay5us(); //延时[/font]
[font=黑体] return CY;
}[/font]
[font=黑体]/**************************************
向IIC总线发送一个字节数据
**************************************/
void BH1750_SendByte(BYTE dat)
{
BYTE i;[/font]
[font=黑体] for (i=0; i<8; i++) //8位计数器
{
dat <<= 1; //移出数据的最高位
SDA = CY; //送数据口
SCL = 1; //拉高时钟线
Delay5us(); //延时
SCL = 0; //拉低时钟线
Delay5us(); //延时
}
BH1750_RecvACK();
}[/font]
[font=黑体]/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE BH1750_RecvByte()
{
BYTE i;
BYTE dat = 0;[/font]
[font=黑体] SDA = 1; //使能内部上拉,准备读取数据,
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
SCL = 1; //拉高时钟线
Delay5us(); //延时
dat |= SDA; //读数据
SCL = 0; //拉低时钟线
Delay5us(); //延时
}
return dat;
}[/font]
[font=黑体]//*********************************[/font]
[font=黑体]void Single_Write_BH1750(uchar REG_Address)
{
BH1750_Start(); //起始信号
BH1750_SendByte(SlaveAddress); //发送设备地址+写信号
BH1750_SendByte(REG_Address); //内部寄存器地址,
// BH1750_SendByte(REG_data); //内部寄存器数据,
BH1750_Stop(); //发送停止信号
}[/font]
[font=黑体]//********单字节读取*****************************************
/*
uchar Single_Read_BH1750(uchar REG_Address)
{ uchar REG_data;
BH1750_Start(); //起始信号
BH1750_SendByte(SlaveAddress); //发送设备地址+写信号
BH1750_SendByte(REG_Address); //发送存储单元地址,从0开始
BH1750_Start(); //起始信号
BH1750_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=BH1750_RecvByte(); //读出寄存器数据
BH1750_SendACK(1);
BH1750_Stop(); //停止信号
return REG_data;
}
*/
//*********************************************************
//
//连续读出BH1750内部数据
//
//*********************************************************
void Multiple_read_BH1750(void)
{ uchar i;
BH1750_Start(); //起始信号
BH1750_SendByte(SlaveAddress+1); //发送设备地址+读信号
for (i=0; i<3; i++) //连续读取2个地址数据,存储中BUF
{
BUF[i] = BH1750_RecvByte(); //BUF[0]存储0x32地址中的数据
if (i == 3)
{[/i][/font][i]
[font=黑体] BH1750_SendACK(1); //最后一个数据需要回NOACK
}
else
{
BH1750_SendACK(0); //回应ACK
}
}[/font]
[font=黑体] BH1750_Stop(); //停止信号
Delay5ms();
}[/font]
[font=黑体]
//初始化BH1750,根据需要请参考pdf进行修改****
void Init_BH1750()
{
Single_Write_BH1750(0x01);
}
void delay1(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
/*****************us延时函数*****************************/
void delay_10us()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/*写指令函数*/
/*rs=l,rw=l,en=高脉冲,D0-D7=指令码。*/
void write_cmd(uchar cmd)
{
CS=0;
SID=0;
SCLK=0;
P0=cmd;
delay1(5);
SCLK=1;
delay1(5);
SCLK=0;
}
/***************************写显示数据************************/
/*rs=h,rw=l,*/
void write_dat(uchar date)
{
CS=1;
SID=0;
SCLK=0;
P0=date;
delay1(5);
SCLK=1;
delay1(5);
SCLK=0;
}
/*****************初始化************************/
void init()
{
SCLK=0;
SID=0;
CH=1; //并口方式
write_cmd(0x30); //基本指令操作
delay1(5);
write_cmd(0x0c); //显示开,关光标
delay1(5);
write_cmd(0x06);
delay1(2);
write_cmd(0x01); //清除显示内容
delay1(5);
}
void dht_init()
{
delay1(1000); //DHT11上电前准备时间,大概1s
dht_dat=1; // //总线准备
}
uchar read_date() //接收一个8位数据,先高位后低位
{
uchar i,dat;
for(i=0;i<8;i++) //也就是说程序是循环八次,把判断有“1”输出到dat中,然后输出一个八位的数据。
{
dht_num=2;
while((dht_dat==0)&&(dht_num++)); //dht_dat 数据线由DH11拉低准备发送数据
delay_10us();
delay_10us();
delay_10us();
delay_10us();
dat=dat<<1;
if(dht_dat==1)
{
dht_num=2;
dat=dat|0x01; //如果来自DQ的数据是高电平1,则把1放到dat的最低位
while((dht_dat==1)&&(dht_num++));
}
}
return dat;
}
void get_temp() //给DHT11一个开始信号,然后读取一次数据,共五个8位字节
{
dht_dat=0;
delay1(25);
dht_dat=1; //单片机给起始脉冲信号
delay_10us();
delay_10us();
delay_10us();
delay_10us();
dht_dat=1; //稍作延时,等待DHT11返回响应(响应为低电 平)
if(dht_dat==0) //有响应才接收数据,否则不作处理
{
dht_num=2;
while((dht_dat==0)&&(dht_num++));
dht_num=2;
while((dht_dat==1)&&(dht_num++));
dht_d1=read_date();
dht_d2=read_date();
dht_t1=read_date();
dht_t2=read_date();
dht_j=read_date(); //一次读出五个数据
}
dht_dat=1; //释放总线
delay1(10);
d11=dht_d1/10;
d12=dht_d1%10;
t11=dht_t1/10;
t12=dht_t1%10;
d21=dht_d2/10;
d22=dht_d2%10;
t21=dht_t2/10;
t22=dht_t2%10;
}
void guangzhaochushi()
{
CH = 0;
delay(1);
lcdinit();
delay(10);
Init_BH1750(); //初始化BH1750
}
//void gz()
//*********************************************************
//主程序********
//*********************************************************
void wenshi()
{
get_temp();
write_cmd(0x80);
for(i=0;i<6;i++)
{
write_dat(table[i]);
}
write_cmd(0x83);
write_dat(0x30+t11);
write_dat(0x30+t12);
write_cmd(0x80+4);
write_dat('.');
write_dat(0x30+t21);
write_cmd(0x85);
write_dat(0x30+t22);
write_cmd(0x86);
for(i=0;i<4;i++)
{
write_dat(table2[i]);
}
write_cmd(0x90);
for(i=0;i<6;i++)
{
write_dat(table1[i]);
}
write_cmd(0x93);
write_dat(0x30+d11);
write_dat(0x30+d12);
write_cmd(0x94);
write_dat('.');
write_dat(0x30+d21);
write_cmd(0x95);
write_dat(0x30+d22);
write_cmd(0x96);
write_dat('%');
}
void kongzhi()
{
if(wendu<35)
{
LED1=0;
delay_nms(10);
// buzzer=0;delay_nms(10);
LED2=1;delay_nms(10);
// FAN=1;delay_nms(10);
}
if(wendu>35)
{
// buzzer=1;delay_nms(10);
LED1=1;delay_nms(10);
LED2=0; delay_nms(10);
// FAN=0;delay_nms(10);
}
// if(key1==0)
// { delay_nms(10);
// if(key1==0)
// {
// gz();
// key2=1;
// }
// }
// if(key2==0)
// { delay_nms(10);
// if(key2==0)
// {
// gz();
// wenshi();
// }
// }
}
void main()
{float temp;
buzzer=0;
{ delay_nms(100); //延时100ms
guangzhaochushi();
{ Single_Write_BH1750(0x01); // power on
Single_Write_BH1750(0x10); // H- resolution mode
delay_nms(180); //延时180ms
Multiple_Read_BH1750(); //连续读出数据,存储在BUF中
dis_data=BUF[0];
dis_data=(dis_data<<8)+BUF[1];//合成数据,即光照数据
temp=(float)dis_data/1.2;
conversion(temp); //计算数据和显示
write_com(0x03);
delay(50);
write_com(0x81);
hzkdis("植物精准监控");
write_com(0x91);
hzkdis("17电子二班");
write_com(0x89);
hzkdis("光照强度:");
write_com(0x98);
hzkdis(" ");
DisplayOneChar(wan);
hzkdis(" ");
DisplayOneChar(qian);
hzkdis(" ");
DisplayOneChar(bai);
hzkdis(" ");
DisplayOneChar(shi);
hzkdis(" ");
DisplayOneChar(ge);
hzkdis(" ");
hzkdis(" lx ");
}
}
delay_nms(5000);
dht_init();
init();
while(1) //循环
{
wenshi();
delay_nms(5);
wendu=dht_d1+ (dht_d2)*10;
shidu=dht_t1+ (dht_t2)*10;
delay_nms(5);
kongzhi();
delay_nms(5);
}
}
复制代码
STC_BH1750.zip
2019-10-14 10:29 上传
点击文件名下载附件
59.3 KB, 下载次数: 24
51单片机控制12864显示光照和温湿
作者:
afeiwusi
时间:
2019-10-15 10:47
#在这里快速回复#51单片机控制12864显示光照和温湿
作者:
yyzf998
时间:
2020-4-24 23:28
谢谢楼主的分享!好好学习天天向上!
作者:
15963163728
时间:
2020-5-3 11:21
楼上迷惑行为
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1