我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 403|回复: 7

51单片机驱动空气传感器显示在lcd

[复制链接]

该用户从未签到

8

主题

9

回帖

21

积分

一级逆天

积分
21

终身成就奖

发表于 2023-12-20 16:12:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
#include<reg52.h>
#include<intrins.h>
#define LCD1602_DB  P0//LCD数据收发8位并行口
bit flag1s = 0;
bit state=0;
bit temp=0;//数据更新位定义

sbit clk=P1^2;
sbit dout=P1^0;
sbit cs=P1^1;
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_E  = P2^7;//LCD控制接口
sbit IO_18B20 = P3^7;//温度传感器接口
sbit beep=P3^6;//蜂鸣器控制接口

sbit key1=P2^0;

unsigned int flag,time=1,temper=0,result=0,xinlv=0,num=0,water=0,sulv=0;//数据更新时间计数值

//unsigned char IntToString(unsigned char *str, int dat);
void ShowDistance();
void InitLcd1602();

void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
bit Get18B20Temp(int *temp);
bit Start18B20();//函数声明
void DelayX10us(unsigned char t)//us级别延时
{
    do {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    } while (--t);
}
void delayms(unsigned int ms)//ms级别延时
{
    unsigned int i;
    for(i=0;i<123*ms;i++);
}
void keyscan()//按键读取
{
    if(key1==0)
    {
        key1=1;
        delayms(50); //消抖
        if(key1==0)
        {
            water++;//判断是否计数
        }
    }

}
unsigned char TLC549_ADC()
{
    unsigned char i,adc;
    clk=0;
    cs=0;
    for(i=0;i<8;i++)
    {
        adc<<=1;
        adc|=dout;
        clk=1;
        clk=0;
    }
    cs=1;
    delayms(1);
    return adc;
}
void main()
{
    bit res;                  
    int temp;        
    int intT, decT;  
    unsigned char len,co2;//变量定义
    unsigned char t[6],display[5],sudu[3];
    unsigned char name[]="T:";//初始显示内容
    unsigned char CO2[]="CO2:";//初始显示内容
    unsigned char water[]="W:";
    EA = 1;           
    TMOD=0x01;   
    TH0 = 0xFC;        
    TL0 = 0x18;
    ET0 = 1;           
    TR0 = 1;//定时器0初始化      
    EX1=1;//定时器1中断初始化      
    IT1 = 1;           
    InitLcd1602();
    Start18B20();//传感器初始化  
    LcdShowStr(0,1,name);
    LcdShowStr(8,1,CO2);
    LcdShowStr(11,0,water);
    beep=0;
    len=0;         
    while(1)
    {   
        co2=TLC549_ADC();
        display[0]=co2*195/10000+'0';
        display[1]='.';
        display[2]=co2*195%10000/1000+'0';
        display[3]=co2*195%1000/100+'0';
        display[4]='\0';
        keyscan();//读取按键值
        if(flag == 1) //每过100ms更新
        {    flag = 0;
            ShowDistance();
        }
        if(state == 1) //每过100ms更新
        {    state = 0;
            LcdShowStr(12,1,display);
        }
        if (flag1s)//每过100ms更新温度值  
        {   
            flag1s = 0;
            res = Get18B20Temp(&temp);  
            if (res)                    
            {    intT = temp >> 4;            
                decT = temp & 0xF;                  
                decT = (decT*10) / 16;        
            }
            Start18B20();
        }
        t[len] =intT/100+'0';   
        t[len+1] =(intT/10)%10+'0';                  
        t[len+2] =intT%10+'0';
        t[len+3] ='.';
        t[len+4] =decT/10+'0';   

        t[len+5] = '\0';              
        LcdShowStr(2,1, t);//动态显示温度

        sudu[0]=sulv/10+'0';
        sudu[1]=sulv%10+'0';
        sudu[2]='\0';
        LcdShowStr(13,0,sudu);
        if(temp)//每过100ms判断温度是否超过设定温度
        {
            temp=0;
            if(intT>=38||xinlv>=100||xinlv<=50||sulv<=40||sulv>=80||(co2*195/10000)>=2)
            {
                beep=1;
            }
            else
            {
                 beep=0;
            }
               
        }
   
    }
}
void Interrupt1() interrupt 2
{
    time++;
}
void InterruptTimer0() interrupt 1
{
    static unsigned int cnt = 0;   
    static unsigned char tmr1s = 0;
    TH0 = 0xFC;      
    TL0 = 0x18;
    temper++;
    if(temper>=100)//数据更新时间计数值
    {
        temper=0;
        temp=1;
        state=1;
    }
    cnt++;
    if(cnt >=1000)//数据更新时间计数值   
    {
        cnt = 0;     
        flag = 1;
        //time=time+1;
        num++;
        xinlv=result*60/num;
        result=time;
        sulv=water*60/num;  
    }
    tmr1s++;
    if (tmr1s >= 100)//数据更新时间计数值  
    {
        tmr1s = 0;
        flag1s = 1;
    }
   
}
void ShowDistance()   
{
    unsigned char buff[3];
    unsigned int Distance ;
    Distance=xinlv;
   
    buff[2] = Distance%10 + '0';
    buff[1] = (Distance/10)%10 + '0';
    buff[0] = Distance/100 + '0';    //在lcd上显示
   
    LcdShowStr(0, 0, "HR:");
    LcdShowStr(3, 0, &buff);
    LcdShowStr(6, 0, "/min");
}

/*unsigned char IntToString(unsigned char *str, int dat) //数据格式转换
{
    signed char i = 0;
    unsigned char len = 0;
    unsigned char buf[6];
   
    if (dat < 0)  
    {
        dat = -dat;
        *str++ = '-';
        len++;
    }
    do {         
        buf[i++] = dat % 10;
        dat /= 10;
    } while (dat > 0);
    len += i;     
    while (i-- > 0)   
    {
        *str++ = buf + '0';
    }
    *str = '\0';  
   
    return len;   
}*/
bit Get18B20Ack() //温度传感器时钟应答判断是否连接
{
    bit ack;
   
    EA = 0;   
    IO_18B20 = 0;
    DelayX10us(50);
    IO_18B20 = 1;
    DelayX10us(6);   
    ack = IO_18B20;   
    while(!IO_18B20);
    EA = 1;
   
    return ack;
}
void Write18B20(unsigned char dat)//写命令
{
    unsigned char mask;
   
    EA = 0;   
    for (mask=0x01; mask!=0; mask<<=1)  
    {
        IO_18B20 = 0;         
        _nop_();
        _nop_();
        if ((mask&dat) == 0)  
            IO_18B20 = 0;
        else
            IO_18B20 = 1;
        DelayX10us(6);        
        IO_18B20 = 1;        
    }
    EA = 1;  
}
unsigned char Read18B20()//读温度数据
{
    unsigned char dat;
    unsigned char mask;
   
    EA = 0;   
    for (mask=0x01; mask!=0; mask<<=1)  
    {
        IO_18B20 = 0;         
        _nop_();
        _nop_();
        IO_18B20 = 1;      
        _nop_();              
        _nop_();
        if (!IO_18B20)        
            dat &= ~mask;
        else
            dat |= mask;
        DelayX10us(6);      
    }
    EA = 1;  

    return dat;
}
bit Start18B20()//起始时钟
{
    bit ack;
   
    ack = Get18B20Ack();   
    if (ack == 0)         
    {
        Write18B20(0xCC);  
        Write18B20(0x44);  
    }
    return ~ack;   
}
bit Get18B20Temp(int *temp)//温度数据转换为十进制
{
    bit ack;
    unsigned char LSB, MSB;
   
    ack = Get18B20Ack();   
    if (ack == 0)           
    {
        Write18B20(0xCC);   
        Write18B20(0xBE);  
        LSB = Read18B20();
        MSB = Read18B20();
        *temp = ((int)MSB << 8) + LSB;
    }
    return ~ack;
}  

void LcdWaitReady()//lcd初始化函数
{
    unsigned char sta;
   
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;
        sta = LCD1602_DB;
        LCD1602_E = 0;
    } while (sta & 0x80);
}

void LcdWriteCmd(unsigned char cmd)    //lcd写命令函数
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}

void LcdWriteDat(unsigned char dat)//lcd写数据函数
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}

void LcdSetCursor(unsigned char x, unsigned char y)//设置光标
{
    unsigned char addr;
   
    if (y == 0)  
    {
        addr = 0x00 + x;  
    }
    else
    {
        addr = 0x40 + x;  
    }
    LcdWriteCmd(addr | 0x80);  
}
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)//lcd显示字符串
{
    LcdSetCursor(x, y);   
    while (*str != '\0')  
    {
        LcdWriteDat(*str++);
    }
}


void InitLcd1602()//lcd初始化
{
    LcdWriteCmd(0x38);
    LcdWriteCmd(0x0C);  
    LcdWriteCmd(0x06);
    LcdWriteCmd(0x01);  
}
回复

使用道具 举报

  • TA的每日心情

    5 天前
  • 签到天数: 126 天

    [LV.7]常住居民III

    1

    主题

    911

    回帖

    1208

    积分

    二级逆天

    积分
    1208

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2023-12-20 17:01:35 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-10-7 21:17
  • 签到天数: 103 天

    [LV.6]常住居民II

    49

    主题

    1万

    回帖

    7万

    积分

    三级逆天

    积分
    73138

    终身成就奖特殊贡献奖原创先锋奖社区居民忠实会员社区劳模最爱沙发社区明星原创达人优秀斑竹奖宣传大使奖

    QQ
    发表于 2023-12-21 06:17:26 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    1794

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2023-12-21 08:45:17 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情

    昨天 15:37
  • 签到天数: 44 天

    [LV.5]常住居民I

    0

    主题

    488

    回帖

    643

    积分

    二级逆天

    积分
    643

    终身成就奖特殊贡献奖

    发表于 2023-12-21 08:57:26 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    前天 09:02
  • 签到天数: 119 天

    [LV.6]常住居民II

    183

    主题

    1795

    回帖

    3317

    积分

    二级逆天

    泰凌微是一家专业音视频的IC代理商、方案提供商和增值服务商

    积分
    3317

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2023-12-21 08:58:53 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:05
  • 签到天数: 144 天

    [LV.7]常住居民III

    1

    主题

    1709

    回帖

    2422

    积分

    二级逆天

    积分
    2422

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2023-12-21 09:29:48 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    2

    主题

    150

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖

    发表于 2023-12-22 08:56:57 | 显示全部楼层
    回复

    使用道具 举报

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

    本版积分规则

    每日签到,有金币领取。


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表