切换到宽版
  • 2119阅读
  • 8回复

[C51]AT89C2051 + BH1750FVI =照度计 [复制链接]

上一主题 下一主题
离线小陈兔
 

发帖
4834
M币
1105
专家
26
粉丝
277
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2018-08-27
【麦兜】一来无聊,二来手巧,还真被它摆弄出几样“吃饱了撑的”的东西来。


无光照


白天室内,开灯


手电筒
----------------------------------------------------------------
Po上代码:

/****************************
MCU = AT89C2051
Clock = 11.0592MHz
Sensor = BH1750FVI
Displayer = LCM-1601
*****************************/
#include  <reg51.h>
#include  <math.h>//数学计算
#include  <intrins.h>//位操作
#include  <stdio.h>//标准输入输出

#define   uchar unsigned char
#define   uint unsigned int    
#define   DataPort P1//LCD1602数据

sbit    SCL=P3^0;//IIC时钟
sbit       SDA=P3^1;//IIC数据
sbit    LCM_RS=P3^5;//液晶屏寄存器选择:高电平-命令/低电平-数据
sbit    LCM_RW=P3^4;//液晶屏读/写模式
sbit    LCM_EN=P3^7;   //液晶屏使能

#define    SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                                                 //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A

typedef   unsigned char BYTE;
typedef   unsigned short WORD;

BYTE    BUF[8];//接收数据缓存区          
uchar   ge,shi,bai,qian,wan;//显示变量
int     dis_data; //变量

void delay_nms(unsigned int k);
void InitLcd();
void Init_BH1750(void);

void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
void conversion(uint temp_data);

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单个字节读
/****************************************************/
//  数据转换出 个,十,百,千,万
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;    
}

//延时k ms
void delay_nms(unsigned int k)    
{                        
unsigned int i,j;                
for(i=0;i<k;i++)
{            
for(j=0;j<121;j++)            
{;}}                        
}

//等待使能
void WaitForEnable(void)    
{                    
DataPort=0xff;        
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);    
LCM_EN=0;                
}

//对液晶屏写命令
void WriteCommandLCM(uchar CMD,uchar Attribc)
{                    
if(Attribc)WaitForEnable();    
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();    
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}

//对液晶屏写数据
void WriteDataLCM(uchar dataW)
{                    
WaitForEnable();        
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();    
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}        

//初始化液晶屏
void InitLcd()                
{            
WriteCommandLCM(0x38,1);    
WriteCommandLCM(0x08,1);    
WriteCommandLCM(0x01,1);    
WriteCommandLCM(0x06,1);    
WriteCommandLCM(0x0c,1);
}            

//显示一个字符
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{                        
Y&=1;                        
X&=15;                        
if(!Y) {X|=0x80;}
else {X|=0xC0;}
WriteCommandLCM(X,0);        
WriteDataLCM(DData);        
}                        

//延时5 us
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
}

//延时5毫秒
    void Delay5ms(){
    WORD n = 560;
    while (n--);
}

//转换开始信号
void BH1750_Start(){
    SDA = 1;//拉高数据线
    SCL = 1; //拉高时钟线
    Delay5us();//延时
    SDA = 0;//产生下降沿
    Delay5us();//延时
    SCL = 0;//拉低时钟线
}

//转换停止信号
void BH1750_Stop()
{
    SDA = 0;//拉低数据线
    SCL = 1;//拉高时钟线
    Delay5us();//延时
    SDA = 1;//产生上升沿
    Delay5us();//延时
}

//发送应答信号:入口参数:ack (0:ACK 1:NAK)
void BH1750_SendACK(bit ack)
{
    SDA = ack; //写应答信号
    SCL = 1;//拉高时钟线
    Delay5us();//延时
    SCL = 0;//拉低时钟线
    Delay5us(); //延时
}

//接收应答信号
bit BH1750_RecvACK()
{
    SCL = 1;//拉高时钟线
    Delay5us();//延时
    CY = SDA;//读应答信号
    SCL = 0;//拉低时钟线
    Delay5us();//延时

    return CY;
}

//向IIC总线发送一个字节数据
void BH1750_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++) //8位计数器
    {
        dat <<= 1;//移出数据的最高位
        SDA = CY;//送数据口
        SCL = 1;//拉高时钟线
        Delay5us();//延时
        SCL = 0;//拉低时钟线
        Delay5us();//延时
    }
    BH1750_RecvACK();
}

//从IIC总线接收一个字节数据
BYTE BH1750_RecvByte()
{
    BYTE i;
    BYTE dat = 0;

    SDA = 1;//使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)//8位计数器
    {
        dat <<= 1;
        SCL = 1;//拉高时钟线
        Delay5us();/延时
        dat |= SDA;//读数据              
        SCL = 0;//拉低时钟线
        Delay5us();//延时
    }
    return dat;
}

//对传感器写单个字符
void Single_Write_BH1750(uchar REG_Address)
{
    BH1750_Start();//起始信号
    BH1750_SendByte(SlaveAddress);//发送设备地址+写信号
    BH1750_SendByte(REG_Address);//内部寄存器地址,请参考中文pdf22页
  //BH1750_SendByte(REG_data);//内部寄存器数据,请参考中文pdf22页
    BH1750_Stop();//发送停止信号
}

//单字节读取
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++)//连续读取6个地址数据,存储中BUF
    {
        BUF = BH1750_RecvByte();//BUF[0]存储0x32地址中的数据
        if (i == 3)
        {

           BH1750_SendACK(1);//最后一个数据需要回NOACK
        }
        else
        {        
          BH1750_SendACK(0);//回应ACK
       }
   }

    BH1750_Stop();//停止信号
    Delay5ms();
}

//初始化BH1750,根据需要请参考pdf进行修改
void Init_BH1750()
{
   Single_Write_BH1750(0x01);  
}
/*************************************/
//主程序
void main(){  
   float temp;
   delay_nms(200);//延时200ms    
   InitLcd();//初始化LCD
   Init_BH1750();//初始化BH1750

    while(1)//循环
   {

    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);//计算数据和显示
    DisplayOneChar(1,0,'L');
    DisplayOneChar(2,0,'i');
    DisplayOneChar(3,0,'g');
    DisplayOneChar(4,0,'h');
    DisplayOneChar(5,0,'t');
    DisplayOneChar(6,0,':');

    DisplayOneChar(7,0,wan);//显示数据
    DisplayOneChar(0,1,qian);  
    DisplayOneChar(1,1,bai);
    DisplayOneChar(2,1,shi);
    DisplayOneChar(3,1,ge);

    DisplayOneChar(4,1,'L');//显示数单位
    DisplayOneChar(5,1,'u');
    DisplayOneChar(6,1,'x');  
  }
}
----------------------------------------------------
更多作品见:
51 + ADC0804【电压表】 http://bbs.mydigit.cn/read.php?tid=2511907
AT89S51 + DS18B20【温度计】http://bbs.mydigit.cn/read.php?tid=2515015
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共11条打赏 ,M币+155 ,专家+2
發騷友 M币 +51 以資鼓勵 2018-08-30
吉米吉米 M币 +5 謝謝分享 2018-08-29
温力口 专家 +1 谢谢分享。。。。。请问这光检测头是如何校准的?还是象18B20一样,有出厂精度保证? 2018-08-27
温力口 M币 +9 谢谢分享。。。。。请问这光检测头是如何校准的?还是象18B20一样,有出厂精度保证? 2018-08-27
哈哈猫驴 M币 +13 IC测试座用完求赠送 2018-08-27
cushion M币 +13 謝謝分享 2018-08-27
红色的狂想 M币 +30 兔子,你又在调皮了! 2018-08-27
懒虫包子 专家 +1 问下,怎么校准呢? 2018-08-27
懒虫包子 M币 +20 问下,怎么校准呢? 2018-08-27
潜隆 M币 +9 謝謝分享 2018-08-27
12
离线懒虫包子

发帖
9556
M币
1654
专家
69
粉丝
590
只看该作者 1楼 发表于: 2018-08-27
请登录后查看
离线小陈兔

发帖
4834
M币
1105
专家
26
粉丝
277
只看该作者 2楼 发表于: 2018-08-27
回 懒虫包子 的帖子
请登录后查看

发帖
5653
M币
2519
专家
1
粉丝
103
只看该作者 3楼 发表于: 2018-08-27
请登录后查看
离线apple1860

发帖
973
M币
1564
专家
6
粉丝
45
只看该作者 4楼 发表于: 2018-08-27
请登录后查看
离线哈哈猫驴

发帖
19257
M币
2
专家
737
粉丝
744
只看该作者 5楼 发表于: 2018-08-27
请登录后查看
离线温力口

发帖
60313
M币
51283
专家
569
粉丝
909
只看该作者 6楼 发表于: 2018-08-27
请登录后查看
离线elecfunwb

发帖
1539
M币
4506
专家
8
粉丝
16
只看该作者 7楼 发表于: 2018-08-27
回 哈哈猫驴 的帖子
请登录后查看
离线ygwpl

发帖
48
M币
39
专家
1
粉丝
6
只看该作者 8楼 发表于: 2018-08-28
请登录后查看
快速回复
限80 字节
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
 
上一个 下一个