找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6850|回复: 0
收起左侧

大神们帮帮菜鸟,adc0832读取不了湿度和光照强度?液晶显示为0,赶觉是主程序的问题,

[复制链接]
ID:215752 发表于 2017-6-29 11:08 | 显示全部楼层 |阅读模式
#include <reg52.h>                 //调用单片机头文件
#define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
#define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

#include <intrins.h>

sbit SCL=P1^4;                //SCL(CLK)定义为P1口的第3位脚,连接ADC0832SCL脚
sbit DO=P1^5;                //DO定义为P1口的第4位脚,连接ADC0832DO脚
sbit CS=P1^3;                //CS定义为P1口的第4位脚,连接ADC0832CS脚

sbit beep = P3^3;   //蜂鸣器IO口定义

sbit dq   = P1^7;        //18b20 IO口的定义

uint temperature ;  //温度的变量
uchar shidu;     //湿度等级
uchar s_high ,s_low;        //湿度报警参数

uint t_high ,t_low ;        //温度报警参数


sbit dianji = P1^6;     //电机IO定义
sbit fengshan = P2^7;     //风扇IO定义
sbit relay = P2^0;     //继电器IO定义

uint flag_250ms ;   //没懂什么意思???????????
uchar key_can;                 //按键值的变量
uchar menu_1,menu_2;        //菜单设计的变量
uchar guangxian;     //光线
uchar qiang_gx;                            //设置光线的强的变量
uchar ruo_gx;                            //设置光线的弱的变量
uchar flag_en = 1,flag_sd,flag_wd,flag_shoudong;
bit sd_sd,sd_wd,sd_gx;  //手动模式 的变量


//这三个引脚参考资料
sbit rs=P1^0;         //1602数据/命令选择引脚 H:数据              L:命令
sbit rw=P1^1;         //1602读写引脚                 H:数据寄存器          L:指令寄存器
sbit e =P1^2;         //1602使能引脚          下降沿触发
uchar code table_num[]="0123456789abcdefg"; // 什么意思???????????

/********************************************************************
* 名称 : delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_uint(uint q)
{
        while(q--);//什么意思?
}

/********************************************************************
* 名称 : write_com(uchar com)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void write_com(uchar com)
{
        e=0;
        rs=0;
        rw=0;
        P0=com;
        delay_uint(3);
        e=1;
        delay_uint(25);
        e=0;
}

/********************************************************************
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write_data(uchar dat)
{
        e=0;
        rs=1;
        rw=0;
        P0=dat;
        delay_uint(3);
        e=1;
        delay_uint(25);
        e=0;       
}

/********************************************************************
* 名称 : write_sfm2(uchar hang,uchar add,uchar date)
* 功能 : 显示2位十进制数,如果要让第一行,第五个字符开始显示"23" ,调用该函数如下
                  write_sfm1(1,5,23)
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_sfm2(uchar hang,uchar add,uint date)
{
        if(hang==1)   
        {   write_com(0x80+add);
                  write_data(0x30+date/10%10);
            write_data(0x30+date%10);
    }
        else
                write_com(0x80+0x40+add);
            write_data(0x30+date/10%10);
             write_data(0x30+date%10);       
}

/***********************lcd1602上显示特定的字符************************/
void write_zifu(uchar hang,uchar add,uchar date)
{
        if(hang==1)   
                write_com(0x80+add);
        else
                write_com(0x80+0x40+add);
        write_data(date);       
}


/********************************************************************
* 名称 : write_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
                  write_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
        if(hang==1)   
                write_com(0x80+add);
        else
                write_com(0x80+0x40+add);
                while(1)
                {
                        if(*p == '\0')  break;
                        write_data(*p++);
                    
                }       
}

/********************************************************************
* 名称 : init_1602()
* 功能 : 初始化1602液晶
* 输入 : 无
* 输出 : 无
***********************************************************************/
void init_1602()
{
        write_com(0x38);
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        delay_uint(1000);
        write_string(1,0,"     Sd:  %         ");       
        write_string(2,0,"  W:    GX:  %      ");
        write_zifu(2,6,0xdf);          //显示度       
}

/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
        uint i,j;
        for(i=0;i<q;i++)
                for(j=0;j<120;j++);
}

/***********************18b20初始化函数*****************************/
void init_18b20()
{
        bit q;
        dq = 1;                                //把总线拿高
        delay_uint(1);            //15us
        dq = 0;                                //给复位脉冲
        delay_uint(80);                //750us
        dq = 1;                                //把总线拿高 等待
        delay_uint(10);                //110us
        q = dq;                                //读取18b20初始化信号
        delay_uint(20);                //200us
        dq = 1;                                //把总线拿高 释放总线
}

/*************写18b20内的数据***************/
void write_18b20(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {                                         //写数据是低位开始
                dq = 0;                         //把总线拿低写时间隙开始
                dq = dat & 0x01; //向18b20总线写数据了
                delay_uint(5);         // 60us
                dq = 1;                         //释放总线
                dat >>= 1;
        }       
}

/*************读取18b20内的数据***************/
uchar read_18b20()
{
        uchar i,value;
        for(i=0;i<8;i++)
        {
                dq = 0;                         //把总线拿低读时间隙开始
                value >>= 1;         //读数据是低位开始
                dq = 1;                         //释放总线
                if(dq == 1)                 //开始读写数据
                        value |= 0x80;
                delay_uint(5);         //60us        读一个时间隙最少要保持60us的时间
        }
        return value;                 //返回数据
}

/*************读取温度的值 读出来的是小数***************/
uint read_temp()
{
        uint value;
        uchar low;                           //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
        EA = 0;
        init_18b20();                   //初始化18b20
        write_18b20(0xcc);           //跳过64位ROM
        write_18b20(0x44);           //启动一次温度转换命令
        delay_uint(50);                   //500us

        init_18b20();                   //初始化18b20
       
        write_18b20(0xcc);           //跳过64位ROM
        write_18b20(0xbe);           //发出读取暂存器命令
       
        low = read_18b20();           //读温度低字节
        value = read_18b20();  //读温度高字节
        EA = 1;
        value <<= 8;                   //把温度的高位左移8位
        value |= low;                   //把读出的温度低位放到value的低八位中
        value *= 0.0625;               //转换到温度值
        return value;                   //返回读出的温度
}


/***********读数模转换数据********************************************************/       
//请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的
                                                //  1  0  0 通道
                                                //  1  1  1 通道
uchar ad0832read(uchar channel)
{
        uchar i,value1,value2;               
                SCL=0;
                DO=1;
                CS=0;                //开始
                SCL=1;                //第一个上升沿       
               
                SCL=0;
                DO=1;
                SCL=1;          //第二个上升沿

                SCL=0;
                DO=channel;
                SCL=1;
                SCL=0;            //第三个上升沿
                DO=1;

                for(i=0;i<8;i++)        //从高位到低位
                {
                        SCL=1;
                        SCL=0;
                        if(DO)
                        {  
                                value1|=0x80>>i;
                        }
                                                                       
                }
               
               
                for(i=0;i<8;i++)        //从低位到        高位
                {
                        if(DO)
                        {  
                          value2|=0x80<<i;
                        }
                        SCL=1;
                        SCL=0;                                               
                }
                CS=1;
                SCL=1;
                DO=1;//数据读取完成,释放总线
                if(value1==value2)       
        return value2;
                return 0;
            
       
}


/********************独立按键程序*****************/
uchar key_can;         //按键值

void key()         //独立按键程序
{
        static uchar key_new;
        key_can = 20;                   //按键值还原
        P3 |= 0xf0;
        if((P3 & 0xf0) != 0xf0)                //按键按下
        {
                delay_1ms(1);                     //按键消抖动
                if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
                {                                                //确认是按键按下
                        key_new = 0;
                        switch(P3 & 0xf0)
                        {
                                case 0xe0: key_can = 4; break;           //得到k1键值
                                case 0xd0: key_can = 3; break;           //得到k2键值
                                case 0xb0: key_can = 2; break;           //得到k3键值
                                case 0x70: key_can = 1; break;           //得到k4键值
                        }
                       
                                       
                }                       
        }
        else
                key_new = 1;       
}


/****************按键显示函数***************/
void key_with()
{
        if(menu_1 == 0)
        {
                if(key_can == 3)
                {
                        flag_en = 0;   //手动取消报警
                        beep = 1;   //关闭蜂鸣器
                }
        }
        if(key_can == 1)           //设置键
        {
                menu_1 ++;
                if(menu_1 > 3)
                {
                        menu_1 = 0;
                        init_1602();  //lcd1602初始化                       
                }
                if(menu_1 == 1)                                 //初始化显示
                {
                        write_string(1,0," WH:    WL:     ");
                        write_string(2,0," SH:  % SL:  %  ");
                        write_zifu(1,6,0xdf);          //显示度               
                        write_zifu(1,13,0xdf);          //显示度               
                        write_sfm2(1,4,t_high);          //显示温度
                        write_sfm2(1,11,t_low);          //显示温度
                        write_sfm2(2,4,s_high);   //显示湿度       
                        write_sfm2(2,11,s_low);   //显示湿度       
                }
                if(menu_1 == 2)                                 //初始化显示
                {
                        write_string(1,0,"  H-gx:  %        ");       
                        write_string(2,0,"  L-gx:  %        ");       
                        write_sfm2(1,7,qiang_gx);
                        write_sfm2(2,7,ruo_gx);         //设置光线的参数
                        write_com(0x80+6);              //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁       
                }       
                if(menu_1 == 3)                                 //初始化显示
                {
                        write_string(1,0,"    Sd:         ");       
                        write_string(2,0," W:     GX:     ");       
                        write_com(0x80+6);              //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁       
                }       
                menu_2 = 1;       
        }
        if(key_can == 2)        //选择键
        {
                if(menu_1 == 1)                  //设置
                {
                        menu_2 ++;
                        if(menu_2 > 4)
                                menu_2 = 1;
                }
                if(menu_1 == 2)                 //设置
                {
                        menu_2 ++;
                        if(menu_2 > 2)
                                menu_2 = 1;                               
                }
                if(menu_1 == 3)                 //设置
                {
                        menu_2 ++;
                        if(menu_2 > 3)
                                menu_2 = 1;                               
                }
        }
        if(menu_1 == 1)       
        {
                if(menu_2 == 1)                        //设置高温报警
                {
                        if(key_can == 3)
                        {
                                t_high ++ ;                //设置高温值加1        
                                if(t_high > 99)
                                        t_high = 99;
                        }
                        if(key_can == 4)
                        {
                                t_high -- ;                //设置高温值减1        
                                if(t_high <= t_low)
                                        t_high = t_low + 1;
                        }
                        write_sfm2(1,4,t_high);           //显示温度
                        write_com(0x80+3);             //将光标移动到秒个位
                        write_com(0x0f);                    //显示光标并且闪烁       
                }       
                if(menu_2 == 2)                        //设置低温报警
                {
                        if(key_can == 3)
                        {
                                t_low ++ ;                        //设置低温值加1
                                if(t_low >= t_high)
                                        t_low = t_high - 1;
                        }
                        if(key_can == 4)                         //设置高温值减1
                        {
                                t_low -- ;                       
                                if(t_low <= 1)
                                        t_low = 1;
                        }
                        write_sfm2(1,11,t_low);   //显示wen度       
                        write_com(0x80+10);            //将光标移动到秒个位
                        write_com(0x0f);                    //显示光标并且闪烁       
                }
                if(menu_2 == 3)                        //设置高湿报警
                {
                        if(key_can == 3)
                        {
                                s_high ++ ;                //设置高湿值加1        
                                if(s_high > 99)
                                        s_high = 99;
                        }
                        if(key_can == 4)
                        {
                                s_high -- ;                //设置高湿值减1        
                                if(s_high <= s_low)
                                        s_high = s_low + 1;
                        }
                        write_sfm2(2,4,s_high);           //显示湿度
                        write_com(0x80+0x40+3);             //将光标移动到秒个位
                        write_com(0x0f);                    //显示光标并且闪烁       
                }       
                if(menu_2 == 4)                        //设置低湿报警
                {
                        if(key_can == 3)
                        {
                                s_low ++ ;                        //设置低湿值加1
                                if(s_low >= s_high)
                                        s_low = s_high - 1;
                        }
                        if(key_can == 4)                         //设置低湿值减1
                        {
                                s_low -- ;                       
                                if(s_low <= 1)
                                        s_low = 1;
                        }
                        write_sfm2(2,11,s_low);           //显示湿度
                        write_com(0x80+0x40+10);            //将光标移动到秒个位
                        write_com(0x0f);                    //显示光标并且闪烁       
                }
        }
////////////////////////设置光线///////////////////////////////
        if(menu_1 == 2)       
        {
                if(menu_2 == 1)                                                //设置强光报警
                {
                        if(key_can == 3)  //
                        {
                                 qiang_gx ++;                                   //加强光报警数据
                                if(qiang_gx >= 100)
                                        qiang_gx = 99;
                        }       
                        if(key_can == 4)  //
                        {
                                 qiang_gx --;                                   //减强光报警数据
                                if(qiang_gx <= ruo_gx)
                                        qiang_gx = ruo_gx;
                        }
                        write_sfm2(1,7,qiang_gx);
                        write_com(0x80+6);         //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁               
                }       
                if(menu_2 == 2)                                                    //设置弱光报警
                {
                        if(key_can == 3)  //
                        {
                                 ruo_gx ++;                                    //加弱光报警数据
                                if(ruo_gx >= qiang_gx)
                                        ruo_gx = qiang_gx;
       
                        }       
                        if(key_can == 4)  //
                        {
                                 ruo_gx --;                                   //减强光报警数据
                                if(ruo_gx <= 1)
                                        ruo_gx = 1;
                        }
                        write_sfm2(2,7,ruo_gx);
                        write_com(0x80+0x40+6);              //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁               
                }
        }
////////////////////////手动模式///////////////////////////////
        if(menu_1 == 3)       
        {
                if(menu_2 == 1)                                                //设置
                {
                        if((key_can == 3) || (key_can == 4))  //
                        {
                                sd_sd = ~sd_sd;   //手动打开和关闭水泵
                        }
                }       
                if(menu_2 == 2)                                                //设置
                {
                        if((key_can == 3) || (key_can == 4))  //
                        {
                                sd_wd = ~sd_wd;   //手动打开和关闭风扇
                        }
                }       
                if(menu_2 == 3)                                                //设置
                {
                        if((key_can == 3) || (key_can == 4))  //
                        {
                                sd_gx = ~sd_gx;   //手动打开和关闭风扇
                        }
                }       
                if(sd_sd == 1)          //手动打开水泵
                {
                        write_string(1,7,"Open");       
                        dianji = 0;       //打开电机       
                }
                else
                {
                        write_string(1,7,"Off ");       
                        dianji = 1;       //关闭电机       
                }

                if(sd_wd == 1)          //手动打开风扇
                {
                        write_string(2,3,"Open");       
                        fengshan = 0;       //打开风扇       
                }
                else
                {
                        write_string(2,3,"Off ");       
                        fengshan = 1;      //关闭风扇       
                }

                if(sd_gx == 1)          //手动打开继电器补光
                {
                        write_string(2,11,"Open");       
                        relay = 0;       //打开       
                }
                else
                {
                        write_string(2,11,"Off ");       
                        relay = 1;       //关闭       
                }

                if(menu_2 == 1)                                       
                {
                        write_com(0x80+6);         //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁               
                }       
                if(menu_2 == 2)                               
                {
                        write_com(0x80+0x40+2);         //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁               
                }       
                if(menu_2 == 3)                               
                {
                        write_com(0x80+0x40+10);         //将光标移动到
                        write_com(0x0f);                //显示光标并且闪烁               
                }       
        }
        key_can = 0;
}




/****************报警函数***************/
void clock_h_l()
{
//        static uchar value,value1,value2,value3,value4,value5,value6;
        if(shidu <= s_low)
        {
                        dianji = 0;       //打开电机
                        flag_sd = 1;
        }
       
        if(shidu >= s_high)
        {
                        dianji = 1;       //关闭电机
                        flag_sd = 0;
        }

/////////////////////////////////////
        if(temperature >= t_high)         //温度过高
        {
                        if(temperature < 85)
                        {
                                flag_wd = 1;
                                fengshan = 0;       //打开风扇
                        }
        }

        if(temperature <= t_low)
        {
                        flag_wd = 0;
                        fengshan = 1;       //关闭风扇
        }
                  
/////////////////////////////////////
        if(guangxian >= qiang_gx)         //光线过高
        {
                        relay = 0;       //关闭继电器补光       
        }

        if(guangxian <= ruo_gx)
        {
                relay = 1;       //打开继电器补光  
        }
                  
        if((shidu <= s_low) || (temperature >= t_high) || (guangxian>= qiang_gx))
        {
                        if(flag_en == 1)
                                beep = ~beep;           //蜂鸣器报警
        }
        else
        {
                beep = 1;
                flag_en = 1;
        }
        }



/***************主函数*****************/
void main()
{
        beep = 0;                                    //开机蜂鸣器叫一声
        delay_1ms(100);
        P0 = P1 = P2 = P3 = 0xff;   //初始化IO口
                                   //读取温度值
        init_1602();                           //1602液晶初始化
        delay_1ms(750);       
        while(1)
        {
                key();                                        //独立按键程序
                if(key_can != 0)
                {                          
                        key_with();                        //按键按下要执行的程序
                }
       
        flag_250ms ++;
                if(flag_250ms >= 250)
                {               
                        flag_250ms = 0;          
                        clock_h_l();         //报警函数
                        temperature = read_temp();  //读取温度值
                        shidu = ad0832read(0);        //读出湿度
                        shidu = ad0832read(0) * 99/ 255;
                        guangxian = ad0832read(1);            
                        guangxian = ad0832read(1) * 99.0 / 255;
                        if(menu_1 == 0)
                        {
                                write_sfm2(1,8,shidu);   //显示湿度       
                                write_sfm2(2,4,temperature);           //显示温度
                                write_sfm2(2,11,guangxian);          //显示光线       
                        }
                }
                delay_1ms(1);
        }
}









回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表