tlx 发表于 2024-3-19 15:25:34

神农鼎 发表于 2024-2-27 14:58
一线制温度传感器,DS18B20演示程序 - SPI/I2S/I2C,DMA支持的3组SPI和I2C,一线制温湿度传感器 - 国芯论 ...

{:lol:} 大神 这是啥问题 检测不到温度
#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;


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);      //写入第一行数据
                        delay(5);
                }
      write_com(0x80+0x40);      //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
      for(num=0;num<16;num++)      //写入第二行数据
                {
                        write_date(table1);//写入第二行数据
                        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=tvalue/1000+0x30;//百位数
   disdata=tvalue%1000/100+0x30;//十位数
   disdata=tvalue%100/10+0x30;//个位数
   disdata=tvalue%10+0x30;//小数位
   
   if(tflag==0)
            flagdat=0x20;//正温度不显示符号
   else
       flagdat=0x2d;//负温度显示负号:-

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


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



void main()
{      
      init();

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

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

      }

}

神农鼎 发表于 2024-3-19 16:14:38


STC8H 比 STC15 同频快,你加点延时


一线制温度传感器,DS18B20演示程序 - SPI/I2S/I2C,DMA支持的3组SPI和I2C,一线制温湿度传感器 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

神农鼎 发表于 2024-3-19 16:16:20



深圳国芯人工智能有限公司-实验箱 (stcai.com)

tlx 发表于 2024-3-19 16:58:08

神农鼎 发表于 2024-3-19 16:14
STC8H 比 STC15 同频快,你加点延时




谢谢,只改延时就行了吗

神农鼎 发表于 2024-3-19 17:15:07

看对方时序图,肯定从 STC8改到STC15 只需要改时序相关部分




RCfans 发表于 2024-10-30 01:24:55

主控STC15F104W,OLED中文显示,DS18B20测温
程序源码链接:https://pan.baidu.com/s/140X_tEcWjTDbEZ-eh7H4MA提取码:10ea
页: 1 [2]
查看完整版本: 求一个STC15F104W单片机测温程序