找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2167|回复: 6
打印 上一主题 下一主题
收起左侧

关于单片机+ds18b20和数码管还有蜂鸣器乱叫的问题?

[复制链接]
跳转到指定楼层
楼主
大佬们我想问一下为什么数码管会突然闪一下呢,然后蜂鸣器就会叫有时候不会有时候就会这样是为什么呢,现在仿真不会这样了,但是实物会,求求了!!

单片机源程序如下:
  1. #include<reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. void ksxs();
  5. sbit DQ=P2^0;        //温度数据口
  6. sbit set=P3^1;                   //设置键
  7. sbit add=P3^2;                 //增加
  8. sbit dec=P3^3;                 //减少
  9. sbit beer=P2^5;                 //蜂鸣器
  10. sbit out =P2^1;      //风扇电机
  11. sbit wx1=P0^0;       //位选1
  12. sbit wx2=P0^1;       //位选2
  13. sbit wx3=P0^2;       //位选3
  14. sbit wx4=P0^3;       //位选4
  15. sbit wx5=P0^4;       //位选5
  16. sbit wx6=P0^5;       //位选6
  17. sbit wx7=P0^6;
  18. sbit wx8=P0^7;
  19. uint high=30,low=5;
  20. uint a=0;
  21. bit fg=0;
  22. uint temp,js,djs;
  23. uchar temp_xs,flag;

  24. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
  25.                     0x92,0x82,0xf8,0x80,0x90,
  26.                                         0x7f          };

  27. void init()
  28. {
  29.   TMOD=0x10;
  30.   TR1=1;
  31.   ET1=1;
  32.   IT1=1;  //脉冲方式
  33.   IT0=1;
  34.   EX1=1;  //打开中断
  35.   EX0=1;
  36.   EA=1;
  37.   TH1=(65536-50000)/256;
  38.   TL1=(65536-50000)%256;
  39. }

  40. /******延时程序*******/
  41. void delay_ms(unsigned int m)
  42.     {
  43.       unsigned int i,j;
  44.       for(i=m;i>0;i--)
  45.        for(j=110;j>0;j--);
  46.          }

  47. /******ds18b20延时程序(微秒)*******/
  48. void delay_us(unsigned int m)     //温度延时程序
  49.     {
  50.       for(m;m>0;m--);
  51.          }

  52. /***********ds18b20的初始化**************/
  53. void Init_DS18B20(void)  
  54. {
  55. unsigned char x=0;
  56. DQ = 1;          //DQ复位 ds18b20通信端口
  57. delay_us(8); //稍做延时
  58. DQ = 0;          //单片机将DQ拉低
  59. delay_us(80); //精确延时 大于 480us
  60. DQ = 1;          //拉高总线   
  61. delay_us(4);
  62. x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  63. delay_us(20);
  64. }

  65. /***********ds18b20读一个字节**************/
  66. uchar ReadOneChar(void)
  67. {
  68. unsigned char i;
  69. unsigned char dat = 0;
  70. for (i=8;i>0;i--)
  71. {        DQ=1;
  72.     delay_us(1);
  73.     DQ = 0; // 高电平拉成低电平时读周期开始
  74.     dat>>=1;
  75.     DQ = 1; // 给脉冲信号
  76.     if(DQ)
  77.     dat|=0x80;   //
  78.     delay_us(10);
  79. }
  80.    return(dat);
  81. }

  82. /*************ds18b20写一个字节****************/
  83. void WriteOneChar(unsigned char dat)
  84. {
  85.    unsigned char i;
  86.    for (i=8; i>0; i--)
  87.    {
  88.    DQ = 0; //从高电平拉至低电平时,写周期的开始
  89.     DQ = dat&0x01;   //数据的最低位先写入
  90.     delay_us(15); //60us到120us延时
  91.     DQ = 1;//释放总线准备下一次数据的写入        
  92.     dat>>=1; //从最低位到最高位传入
  93. }
  94. delay_us(4);
  95. }

  96. /**************读取ds18b20当前温度************/
  97. void ReadTemperature(bit flag)
  98.   {
  99.     uchar a=0;
  100.     uchar b=0;
  101.         uint i;
  102.     Init_DS18B20();
  103.     WriteOneChar(0xCC);    // 跳过读序号列号的操作/
  104.     WriteOneChar(0x44); // 启动温度转换
  105.         if(flag==1)
  106.         {
  107.          ksxs();
  108.         }
  109.         else
  110.     delay_us(125);       // this message is wery important
  111.     Init_DS18B20();
  112.     WriteOneChar(0xCC); //跳过读序号列号的操作
  113.     WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度/

  114.     a=ReadOneChar();    //读取温度值低位  /
  115.     b=ReadOneChar();      //读取温度值高位    /

  116.         i=b;
  117.         i>>=4;
  118.         if(i!=0)
  119.         {
  120.           fg=1;
  121.           a=~(a)+1;
  122.           b=~b;
  123.           if(a==0) b=b+1;   //写的过程发现-16度本来是0x10却输出0x00,20却是10,这样就好了
  124.           temp=((a>>4)|(b<<4));
  125.           a=(a&0x0f);
  126.           temp_xs=a;
  127.         }
  128.     else
  129.       {
  130.           fg=0;
  131.           temp=((a>>4)|(b<<4));
  132.           a=(a&0x0f);
  133.           temp_xs=a;
  134.           }
  135. }

  136. /*************主显示函数************/
  137. void display()
  138. {
  139.           uint a,b,c,d,e,j;
  140.           a=temp/100;              // 百位
  141.           b=temp/10%10;            // 十位
  142.           c=temp%10;               // 个位
  143.           temp_xs=(int)(temp_xs*6.25+0.5);
  144.           d=temp_xs/10;                            //  小数第一位
  145.           e=temp_xs%10;           //  小数第二位
  146.          for(j=0;j<7;j++)
  147.          {
  148.           switch(j)
  149.           {
  150.                 case 0:
  151.                 wx1=1;
  152.                 if(fg==0)
  153.                 {
  154.                  if(a==0)        P1=0Xff;
  155.                  else       P1=table[a];
  156.                 }
  157.                 if(fg==1)
  158.                 {
  159.                  if(b==0)        P1=0Xff;
  160.                  else       P1=0xbf;
  161.                 }
  162.                 delay_ms(1);
  163.                 wx1=0;
  164.                 break;
  165.                
  166.                 case 1:
  167.                 wx2=1;
  168.                 if(fg==0)
  169.                 {
  170.                  if((a==0)&&(b==0))      P1=0Xff;
  171.                  else                    P1=table[b];
  172.                 }
  173.                 if(fg==1)
  174.                 {
  175.                  if(b==0)      P1=0Xbf;
  176.                  else          P1=table[b];
  177.                 }
  178.                 delay_ms(1);
  179.                 wx2=0;
  180.                 break;

  181.                 case 3:
  182.                 wx3=1;
  183.                 P1=table[c];   //+0x80 表示字母加小数点
  184.                 delay_ms(1);
  185.                 wx3=0;
  186.                 break;

  187.             case 2:
  188.                 wx4=1;
  189.                 P1=table[10];
  190.                 delay_ms(1);
  191.                 wx4=0;
  192.                 break;

  193.                 case 4:
  194.                 wx5=1;
  195.                 P1=table[d];
  196.                 delay_ms(1);
  197.                 wx5=0;
  198.                 break;

  199.                 case 5:
  200.                 wx6=1;
  201.                 P1=table[e];
  202.                 delay_ms(1);
  203.                 wx6=0;
  204.                 break;
  205.           }
  206.          }

  207. }

  208. /**********调温显示函数***********/
  209. void xianshi(temp1)
  210. {
  211.   uint x,y,z,j;
  212.           x=temp1/100;              // 百位
  213.           y=temp1/10%10;            // 十位
  214.           z=temp1%10;               // 个位

  215.          for(j=0;j<4;j++)
  216.          {
  217.           switch(j)
  218.           {
  219.            case 0:
  220.            wx1=1;
  221.        if(a==1)            P1=0x89;
  222.            if(a==2)                           P1=0xc7;
  223.            delay_ms(5);
  224.            wx1=0;
  225.            
  226.            case 1:
  227.            wx5=1;
  228.            if(x==0)          P1=0Xff;
  229.            else       P1=table[x];
  230.            delay_ms(5);
  231.            wx5=0;
  232.            break;

  233.            case 2:
  234.            wx6=1;
  235.            if((x==0)&&(y==0))      P1=0Xff;
  236.            else                    P1=table[y];
  237.            delay_ms(5);
  238.            wx6=0;
  239.            break;

  240.            case 3:
  241.            wx7=1;
  242.            P1=table[z];
  243.            delay_ms(5);
  244.            wx7=0;
  245.            break;
  246.           }
  247.          }
  248. }

  249. /**********开机显示函数***********/
  250. void ksxs()
  251. { uchar i;
  252. for (i=0;i<120;i++)
  253. {

  254. P1=0x10c;
  255. wx1=1;
  256. delay_ms(1);
  257. wx1=0;

  258. P1=0x10c;
  259. wx2=1;
  260. delay_ms(1);
  261. wx2=0;

  262. P1=0x10c;
  263. wx3=1;
  264. delay_ms(1);
  265. wx3=0;

  266. P1=0x10c;
  267. wx4=1;
  268. delay_ms(1);
  269. wx4=0;

  270. P1=0x10c;
  271. wx5=1;
  272. delay_ms(1);
  273. wx5=0;

  274. P1=0x10c;
  275. wx6=1;
  276. delay_ms(1);
  277. wx6=0;

  278. wx7=1;
  279. P1=0x10c;
  280. delay_ms(1);
  281. wx7=0;

  282. wx8=1;
  283. P1=0x10c;
  284. delay_ms(1);
  285. wx8=0;
  286. }
  287. }

  288. /**********按键函数***********/
  289. void keyscan()
  290. {


  291. if(set==0)
  292. {

  293.   while(1)
  294.   {
  295.    if(set==0)
  296.    {
  297.     while(!set);
  298.         a++;
  299.          
  300.    }
  301.    if(a==1||a==2)
  302.    {
  303.      if(a==1) xianshi(high);
  304.          if(add==0)
  305.          {
  306.          delay_ms(10);
  307.          while(!add);
  308.          if(flag==1)
  309.          {
  310.           while(!flag);
  311.          if(a==1&&high<125)
  312.          {
  313.          high=high+5;
  314.          }
  315.          if(a==2)
  316.          low=low+5;
  317.           }
  318.           flag=0;
  319.           EX0=1;
  320.           }

  321.          if(a==2) xianshi(low);
  322.          if(dec==0)
  323.          {
  324.      delay_ms(5);
  325.          if(flag==2)
  326.          {
  327.          while(!flag);
  328.          if(a==1) high=high-1;
  329.          if(a==2) low=low-1;
  330.           }
  331.           flag=0;
  332.           EX1=1;
  333.           }
  334.    }
  335.    if(a>=3)
  336.    {
  337.         a=0;
  338.         break;
  339.    }
  340.   }
  341. }
  342. }

  343. /**********报警函数***********/
  344. void alarm()
  345. {
  346.   if(temp<=low||temp>=high)
  347.   {
  348.    delay_ms(10);
  349.    beer=0;
  350.    if(djs==0&&temp>=high)
  351.    {

  352.    TR1=0;
  353.    beer=1;
  354.    out=0;
  355.    }
  356.    else
  357.    {
  358.    beer=0;
  359.    out=1;
  360.    }
  361.   }

  362. else
  363.   {
  364.   out=1;
  365.   beer=1;
  366.    TR1=1;
  367.    djs=10;
  368.   }
  369. }
  370. /**********主函数***********/
  371. void main()
  372. {        
  373.          beer=1;
  374.          out=1;
  375.      init();
  376.            ReadTemperature(1);
  377.          ksxs();
  378.          djs=3;
  379.      js=0;
  380.   while(1)
  381. {
  382.            keyscan();
  383.        ReadTemperature(0);
  384.        display();
  385.            alarm();

  386. }
  387. }

  388. void exzd0(void)interrupt 0
  389. {
  390.   flag=1;
  391.   EX0=0;
  392. }
  393. void exzd1(void)interrupt 2
  394. {
  395.   flag=2;
  396.   EX1=0;
  397. }
  398. void time1() interrupt 3   //定时器中断1
  399. {
  400.   TH1=(65536-50000)/256;
  401.   TL1=(65536-50000)%256;
  402.   js++;
  403.   if(js>=20)
  404.   {
  405.    js=0;
  406.    djs--;
  407.   }
  408. }
复制代码


温度计.png (65.37 KB, 下载次数: 91)

温度计.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:180919 发表于 2020-11-12 08:48 | 只看该作者
1.建议把Q1,Q3换成NPN管,
2.不换也需要再D2,D3并一个上拉电阻,让Q1,Q3完全关关闭.
回复

使用道具 举报

板凳
ID:498772 发表于 2020-11-12 11:20 | 只看该作者
changhz 发表于 2020-11-12 08:48
1.建议把Q1,Q3换成NPN管,
2.不换也需要再D2,D3并一个上拉电阻,让Q1,Q3完全关关闭.

想问一下怎么并,实物做出来了不太好改了呜呜,感觉并简单一点,就是现在不知道是不是ds18b20的哪里我搞错了,就是数码管有的时候会跳然后蜂鸣器就叫一下,突然这样不知道为啥┭┮﹏┭┮
回复

使用道具 举报

地板
ID:687694 发表于 2020-11-12 15:27 | 只看该作者
软件中,你在按键函数中有一个while(1),这个执行到这里就跳不出去了。一直在等待中断,中断执行完毕后又回到这个无限循环中。这是不对的。while(1)不应该在子函数中出现。
硬件中,pnp三极管用法不对,你按照图中接,现实中有可能无法正常饱和导通,PNP管,发射极接电源正极,基极与驱动之间设限流电阻,为保证控制可靠,基极需上拉电阻,集电极与电源地之间接直接驱动负载。通常单片机直接驱动PNP管比较方便,因为灌电流一般比输出电流大,即驱动能力强一点。
如果需要高电平驱动,请查阅手册,可否将gpio配置为推挽输出,驱动与基极加限流电阻,基极加下拉电阻驱动NPN三极管,集电极与电源正极之间接负载,发射极接地。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:498772 发表于 2020-11-12 15:49 | 只看该作者
lovexulu 发表于 2020-11-12 15:27
软件中,你在按键函数中有一个while(1),这个执行到这里就跳不出去了。一直在等待中断,中断执行完毕后又 ...

大佬按键那里我把while(1)那个去掉就可以了是吧,那我实物已经做出来了,有点不太好改pnp接法,那我再集电极和基极加一个10k的电阻嘛,那蜂鸣器会突然叫一下是这个原因嘛,
回复

使用道具 举报

6#
ID:687694 发表于 2020-11-12 18:14 | 只看该作者
2929198192 发表于 2020-11-12 15:49
大佬按键那里我把while(1)那个去掉就可以了是吧,那我实物已经做出来了,有点不太好改pnp接法,那我再 ...

89c52高电平驱动能力太弱,输出电流不到1ma,驱动三极管集电极电流就算管子放大系数200也不到200ma的电流,估计带蜂鸣器是可以的,带电机就悬了,不如改低电压驱动的场管吧,我记得si2302有直插封装的n管,直接代换,G接驱动R4/R7(2k)D接蜂鸣器/电机下端,S接地。G接个10K下拉电阻。驱动电流3A,耐压20V。
回复

使用道具 举报

7#
ID:180919 发表于 2020-11-13 09:20 | 只看该作者
2929198192 发表于 2020-11-12 11:20
想问一下怎么并,实物做出来了不太好改了呜呜,感觉并简单一点,就是现在不知道是不是ds18b20的哪里我搞 ...

现在有问题了,哥们不改不稳定.
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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