找回密码
 立即注册
楼主: t***

求一个STC15F104W单片机测温程序

[复制链接]
  • TA的每日心情
    开心
    2024-1-19 10:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    8

    回帖

    39

    积分

    新手上路

    积分
    39
     楼主| 发表于 2024-3-19 15:25:34 | 显示全部楼层
    神农鼎 发表于 2024-2-27 14:58
    一线制温度传感器,DS18B20演示程序 - SPI/I2S/I2C,DMA支持的3组SPI和I2C,一线制温湿度传感器 - 国芯论 ...

    大神 这是啥问题 检测不到温度
    #include<reg52.h>
    #include<intrins.h>
    #define uchar unsigned char
    #define uint unsigned int
    #define OVERTEMP 5
    #define     LCDIO      P0  //1602数据口
    sbit DQ=P3^4;//ds18b20与单片机连接口

    sbit rs=P3^0;  //1602数据命令选择引脚
    sbit rd=P3^1;        //读写选择
    sbit lcden=P3^5;        //1602选通引脚

    sbit OUTPUT_PIN = P3 ^ 3; // 温度报警输出端口P3.3




    void DelayXus(uchar n);
    void DS18B20_Reset();
    void DS18B20_WriteByte(uchar dat);
    uchar DS18B20_ReadByte();


    float f_temp; //浮点型温度值   
    uint tvalue;//温度值
    uchar tflag;

    uchar code table[]=        {"The temperature "};    //每行显示16个字符
    uchar code table1[]=        {"is:  000.0C wfu"};

    uchar data disdata[5];


    void delay(uint z)        //短延时
    {
            uint x,y;
            for(x=z;x>0;x--)
                    for(y=110;y>0;y--);
    }

    void write_com(uchar com)        //1602写命令子程序
    {
            rs=0;                //RS是数据命令选择短,高电平写数据,低电平写命令
            rd=0;                //RD是读写选择短,高电平读,低电平写
            lcden=0;        //1602选通端,高电平选通,低电平禁止
            LCDIO =com;
            delay(5);
            lcden=1;
            delay(5);
            lcden=0;        
    }

    void write_date(uchar date)        //1602写数据子程序
    {
            rs=1;        //RS是数据命令选择短,高电平写数据,低电平写命令
            rd=0;        //RD是读写选择短,高电平读,低电平写
            lcden=0;        //1602选通端,高电平选通,低电平禁止
            LCDIO =date;
            delay(5);
            lcden=1;
            delay(5);
            lcden=0;        
    }



    void init()                                //1602初始化程序
    {
            uchar num;
            lcden=0;

            write_com(0x38);        //0011 1000B,功能模式设置,设置为8为数据口,两行显示,5*7点阵
            write_com(0x0c);        //0000 1011B,显示开及光标设置,关显示,显示光标,光标闪烁
            write_com(0x06);        //0000 0110B,显示光标移动设置,读或写一个字符,地址指针减一且光标减一,写一个字符屏幕显示不移动
            write_com(0x01);        //0000 0001B,显示清屏,数据指针和所有显示清屏
            write_com(0x80);        //1000 000B,关闭显示
            delay(5);
            write_com(0x80);        //1000 000B,设置为2行显示,写入第一行字符的地址,第一行地址是00-2F
            for(num=0;num<16;num++)
                    {
                            write_date(table[num]);        //写入第一行数据
                            delay(5);
                    }
            write_com(0x80+0x40);        //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
            for(num=0;num<16;num++)        //写入第二行数据
                    {
                            write_date(table1[num]);//写入第二行数据
                            delay(5);
                    }      
            

    }

    /**************************************
    延时X微秒(STC12C5A60S2@12M)
    不同的工作环境,需要调整此函数
    此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
    **************************************/
    void DelayXus(uchar n)
    {
        while (n--)
        {
            _nop_();
            _nop_();
        }
    }

    /**************************************
    复位DS18B20,并检测设备是否存在
    **************************************/
    void DS18B20_Reset()
    {
        CY = 1;
        while (CY)
        {
            DQ = 0;                     //送出低电平复位信号
            DelayXus(240);              //延时至少480us
            DelayXus(240);
            DQ = 1;                     //释放数据线
            DelayXus(60);               //等待60us
            CY = DQ;                    //检测存在脉冲
            DelayXus(240);              //等待设备释放数据线
            DelayXus(180);
        }
    }

    /**************************************
    从DS18B20读1字节数据
    **************************************/
    uchar DS18B20_ReadByte()
    {
        uchar i;
        uchar dat = 0;

        for (i=0; i<8; i++)             //8位计数器
        {
            dat >>= 1;
            DQ = 0;                     //开始时间片
            DelayXus(1);                //延时等待
            DQ = 1;                     //准备接收
            DelayXus(1);                //接收延时
            if (DQ) dat |= 0x80;        //读取数据
            DelayXus(60);               //等待时间片结束
        }

        return dat;
    }

    /**************************************
    向DS18B20写1字节数据
    **************************************/
    void DS18B20_WriteByte(uchar dat)
    {
        char i;

        for (i=0; i<8; i++)             //8位计数器
        {
            DQ = 0;                     //开始时间片
            DelayXus(1);                //延时等待
            dat >>= 1;                  //送出数据
            DQ = CY;
            DelayXus(60);               //等待时间片结束
            DQ = 1;                     //恢复数据线
            DelayXus(1);                //恢复延时
        }
    }

    unsigned int ReadTemp(void)
    {
    unsigned char a=0;
    unsigned char b=0;


        DS18B20_Reset();                //设备复位
        DS18B20_WriteByte(0xCC);        //跳过ROM命令
        DS18B20_WriteByte(0x44);        //开始转换命令
        while (!DQ);                    //等待转换完成

        DS18B20_Reset();                //设备复位
        DS18B20_WriteByte(0xCC);        //跳过ROM命令
        DS18B20_WriteByte(0xBE);        //读暂存存储器命令
        a= DS18B20_ReadByte();       //读温度低字节
        b= DS18B20_ReadByte();       //读温度高字节


      tvalue=b;
      tvalue<<=8;
      tvalue=tvalue|a;
        if(tvalue<0x0fff)
       tflag=0;
        else
       {tvalue=~tvalue+1;
             tflag=1;
       }
    //tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数
    f_temp=tvalue*(0.0625);    // 温度在寄存器中为12位,分辨率为0.0625
    tvalue=f_temp*10+0.5;    //乘以10表示小数点后面只取1位,加0.5时四舍五入
    //f_temp=f_temp+0.05;
    //f_temp=tvalue*(0.0625);
    //tvalue=f_temp*100+(tvalue>0?0.5:-0.5);
             if ( tvalue> OVERTEMP)
                                            {
                OUTPUT_PIN = 1;   // 温度超过上限,输出高电平
            }
                                            else if ( tvalue < OVERTEMP)
                                            {
                OUTPUT_PIN = 0;   // 温度低于下限,输出低电平
            }


            return(tvalue);
      }


    void ds1820disp()//温度值显示
            { uchar flagdat;
              disdata[0]=tvalue/1000+0x30;//百位数
         disdata[1]=tvalue%1000/100+0x30;//十位数
         disdata[2]=tvalue%100/10+0x30;//个位数
         disdata[3]=tvalue%10+0x30;//小数位
       
         if(tflag==0)
                flagdat=0x20;//正温度不显示符号
         else
           flagdat=0x2d;//负温度显示负号:-

         if(disdata[0]==0x30)
               {disdata[0]=0x20;//如果百位为0,不显示
                     if(disdata[1]==0x30)
                      {disdata[1]=0x20;//如果百位为0,十位为0也不显示
                      }
                    }


               write_com(0x80+0x44);            //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
               write_date(flagdat);//显示符号位
               write_com(0x80+0x45);
               write_date(disdata[0]);//显示百位
               write_com(0x80+0x46);
               write_date(disdata[1]);//显示十位         
               write_com(0x80+0x47);
               write_date(disdata[2]);//显示个位         
               write_com(0x80+0x48);
               write_date(0x2e);//显示小数点         
               write_com(0x80+0x49);
               write_date(disdata[3]);//显示小数位
               write_com(0x80+0x4a);
               write_date('C');
       }



    void main()
    {        
            init();

            ReadTemp();//读取温度
            ds1820disp();//显示
            while(1)
            {

             ReadTemp();//读取温度
             ds1820disp();//显示
                                           

            }

    }
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    552

    主题

    9546

    回帖

    1万

    积分

    管理员

    积分
    14066
    发表于 2024-3-19 16:14:38 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    552

    主题

    9546

    回帖

    1万

    积分

    管理员

    积分
    14066
    发表于 2024-3-19 16:16:20 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-19 10:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    8

    回帖

    39

    积分

    新手上路

    积分
    39
     楼主| 发表于 2024-3-19 16:58:08 | 显示全部楼层
    神农鼎 发表于 2024-3-19 16:14
    STC8H 比 STC15 同频快,你加点延时

    谢谢,只改延时就行了吗
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    552

    主题

    9546

    回帖

    1万

    积分

    管理员

    积分
    14066
    发表于 2024-3-19 17:15:07 | 显示全部楼层
    看对方时序图,肯定从 STC8改到STC15 只需要改时序相关部分


    截图202403191715039687.jpg

    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-20 18:42 , Processed in 0.080891 second(s), 46 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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