找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3051|回复: 9
收起左侧

单片机DS18B20导入温度来控制电机程序,哪里出错了

[复制链接]
ID:473410 发表于 2019-2-20 18:35 | 显示全部楼层 |阅读模式
我想在主程序中设置一个温度临界值(20度),通过DS18B20传感器来获取温度并显示在数码管上,达到临界值之后,使电机转动,但是实际情况是达到了20度也不能让电机停止转动,这是为什么?初学51,请多指教!
以下为主程序:
#include<reg52.h>
#include<temp.h>

typedef unsigned char u8;
typedef unsigned int u16;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit PWM=P1^0;

u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
u8 num=0,displaydata[8];


void delay(u16 i)
{
        while(i--);
}

void datapros(int temp)
{
        float tp;
        if(temp<0)
        {
                displaydata[0]=0x40;
                temp-=1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;                        
        }
        else
        {
                displaydata[0]=0x00;
                tp=temp;
                temp=tp*0.0625*100+0.5;                        
        }

        displaydata[1]=smgduan[temp/10000];
        displaydata[2]=smgduan[temp%10000/1000];
        displaydata[3]=smgduan[temp%10000%1000/100]|0x80;
        displaydata[4]=smgduan[temp%100/10];
        displaydata[5]=smgduan[temp%100%10];
}

void digdisplay()
{
        u8 i;
        for(i=0;i<6;i++)
        {
                switch(i)
                {
                        case(0):LSA=0;LSB=0;LSC=0;break;
                        case(1):LSA=1;LSB=0;LSC=0;break;
                        case(2):LSA=0;LSB=1;LSC=0;break;
                        case(3):LSA=1;LSB=1;LSC=0;break;
                        case(4):LSA=0;LSB=0;LSC=1;break;
                        case(5):LSA=1;LSB=0;LSC=1;break;
                }
                P0=displaydata[5-i];
                delay(50);
                P0=0x00;
        }
}

void main()
{
        while(1)
        {
                datapros(ds18b20readtemp());
                digdisplay();
                if(ds18b20readtemp()>=2000)         //20度
                        PWM=0;
                else
                        PWM=1;
        }
}


回复

使用道具 举报

ID:378182 发表于 2019-2-20 19:19 | 显示全部楼层
<temp.h>的内容是什么?无法判别ds18b20readtemp()的定义是否正确。
回复

使用道具 举报

ID:164602 发表于 2019-2-20 19:54 | 显示全部楼层
你的电机是直接接在VCC和IO口P10上的吧?!
51单片机的IO口电流是很小的,不足以带动直流电机的。
要想直流电机转动,都要用到电机驱动芯片,常用的有L298N等(这个我用得最多)。
回复

使用道具 举报

ID:473410 发表于 2019-2-21 10:14 | 显示全部楼层
HC6800-ES-V2.0 发表于 2019-2-20 19:54
你的电机是直接接在VCC和IO口P10上的吧?!
51单片机的IO口电流是很小的,不足以带动直流电机的。
要想直 ...

可以带动直流电机转动,但是不能达到温度达到临界值就使电机停下的效果
回复

使用道具 举报

ID:164602 发表于 2019-2-21 14:13 | 显示全部楼层
放眼天下 发表于 2019-2-21 10:14
可以带动直流电机转动,但是不能达到温度达到临界值就使电机停下的效果

找到你的问题了——可能
看看你的程序中的显示部分
显示的温度是一个保留两位小数且四舍五入的值,即tp*0.0625*100+0.5
再看看你的电机停转判断 if(ds18b20readtemp()>=2000)         //20度
知道了吧,你的判断语句中的温度,是2000*0.625=125度,不是20度——呵呵,不是你的程序吧,所以不知道这个。
20度应该是 if(ds18b20readtemp()>=320)         //20度
回复

使用道具 举报

ID:473410 发表于 2019-2-21 14:56 | 显示全部楼层
HC6800-ES-V2.0 发表于 2019-2-21 14:13
找到你的问题了——可能
看看你的程序中的显示部分
显示的温度是一个保留两位小数且四舍五入的值,即tp ...

额,是我写的,这个地方应该是算错了,还好找到问题了
回复

使用道具 举报

ID:432823 发表于 2019-2-21 21:29 | 显示全部楼层
从程序看da18b20测出转换好的温度值是temp在数码上显示,而ds18b20readtemp()是直接读出的补码形式的,20度时并不等于2000.
回复

使用道具 举报

ID:495702 发表于 2019-5-19 23:03 | 显示全部楼层
  displaydata[0]=0x40;问一下这句啥意思
回复

使用道具 举报

ID:213173 发表于 2019-5-20 13:45 | 显示全部楼层
无标题.jpg

  1. #include <AT89X52.H>
  2. #include<temp.h>

  3. typedef unsigned char u8;
  4. typedef unsigned int u16;

  5. sbit LSA=P2^2;
  6. sbit LSB=P2^3;
  7. sbit LSC=P2^4;
  8. sbit PWM=P1^0;

  9. u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  10. u8 displaydata[8];
  11. u16 num=0;
  12. /*
  13. void delay(u16 i)
  14. {
  15.         while(i--);
  16. }*/

  17. void datapros(int temp)
  18. {
  19.         float tp;
  20.         if(temp<0)
  21.         {
  22.                 displaydata[0]=0x40;
  23.                 temp-=1;
  24.                 temp=~temp;
  25.                 tp=temp;
  26.                 temp=tp*0.0625*100+0.5;
  27.         }
  28.         else
  29.         {
  30.                 displaydata[0]=0x00;
  31.                 tp=temp;
  32.                 temp=tp*0.0625*100+0.5;
  33.         }
  34.         num=temp;//暂存
  35.         displaydata[1]=smgduan[temp/10000%10];
  36.         displaydata[2]=smgduan[temp/1000%10];
  37.         displaydata[3]=smgduan[temp/100%10]|0x80;
  38.         displaydata[4]=smgduan[temp/10%10];
  39.         displaydata[5]=smgduan[temp%10];
  40. }

  41. void digdisplay()
  42. {
  43.         static u8 i=0;
  44.         P0=0x00;
  45.         switch(i)
  46.         {
  47.                 case(0):LSA=0;LSB=0;LSC=0;break;
  48.                 case(1):LSA=1;LSB=0;LSC=0;break;
  49.                 case(2):LSA=0;LSB=1;LSC=0;break;
  50.                 case(3):LSA=1;LSB=1;LSC=0;break;
  51.                 case(4):LSA=0;LSB=0;LSC=1;break;
  52.                 case(5):LSA=1;LSB=0;LSC=1;break;
  53.         }
  54.         P0=displaydata[i];
  55.         i++;
  56.         i%=6;
  57. }

  58. void main()
  59. {
  60.         u8 j;
  61.         while(1)
  62.         {
  63.                 if(++j>=250)//计数延时
  64.                 {
  65.                         j=0;
  66.                         datapros(ds18b20readtemp());
  67.                 }
  68.                 digdisplay();
  69.                 if(num>=2000)         //20度
  70.                         PWM=0;
  71.                 else
  72.                         PWM=1;
  73.         }
  74. }
复制代码



回复

使用道具 举报

ID:511890 发表于 2019-5-20 14:46 | 显示全部楼层
if(ds18b20readtemp()>=2000)这一句错了。我把2000代入temp=tp*0.0625*100+0.5; 得到12500.5。这个应该是125°。把2000改成312应该就没问题了。不过最好的解决办法是在sbit PWM=P1^0;后面加一个变量int int temp1;在datapros里面最后面加:temp1 = temp/100;
最后把 if(ds18b20readtemp()>=2000)改为 if(temp1>=20)。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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