找回密码
 立即注册
楼主: tlx

求一个STC15F104W单片机测温程序

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-01-19 10:13:12

1

主题

8

回帖

41

积分

新手上路

积分
41
发表于 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();//显示
                                       

        }

}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:99
  • 最近打卡:2025-06-16 09:28:47

733

主题

1万

回帖

1万

积分

管理员

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

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:99
  • 最近打卡:2025-06-16 09:28:47

733

主题

1万

回帖

1万

积分

管理员

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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-01-19 10:13:12

1

主题

8

回帖

41

积分

新手上路

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

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

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:99
  • 最近打卡:2025-06-16 09:28:47

733

主题

1万

回帖

1万

积分

管理员

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


截图202403191715039687.jpg

回复 支持 反对

使用道具 举报 送花

0

主题

1

回帖

8

积分

新手上路

积分
8
发表于 2024-10-30 01:24:55 | 显示全部楼层
主控STC15F104W,OLED中文显示,DS18B20测温
程序源码链接:https://pan.baidu.com/s/140X_tEcWjTDbEZ-eh7H4MA  提取码:10ea
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-17 02:25 , Processed in 0.119344 second(s), 80 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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