找回密码
 立即注册

QQ登录

只需一步,快速开始

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

有关定时器扫描数码管显示ds18b20温度值的问题

[复制链接]
回帖奖励 60 黑币 回复本帖可获得 10 黑币奖励! 每人限 2 次(中奖概率 70%)
跳转到指定楼层
楼主
ID:86791 发表于 2015-12-21 16:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为什么单独用定时器扫描数码管显示固定的数值能正常显示,
用来显示采集到的ds18b20温度值的时候出现异常?十位和个位隔一段时间循环显示?我延时两毫秒

程序:
#include<stc12c5a60s2.h>
#include"timer0.h"
#include"delay.h"
uchar num;
void Timer0Init(void)  //2毫秒@12.000MHz 定时器初始化
{
AUXR|=0x80;  //定时器时钟1T模式
TMOD&=0xF0;  //设置定时器模式
TMOD|=0x01;  //设置定时器模式
TL0=0x40;  //设置定时初值
TH0=0xA2;  //设置定时初值
TF0=0;  //清除TF0标志
EA=1;
ET0=1;
TR0=1;      //定时器0开始计时
}
void Timer0() interrupt 1
{
     TL0=0x40;  //设置定时初值
  TH0=0xA2;  //设置定时初值  
  num++;
}


数码管:
#include<stc12c5a60s2.h>
#include"shumaguan.h"
#include"timer0.h"
#define DataPort P0     //定义数据端口 程序中遇到DataPort 则用P1 替换
sbit LATCH2=P2^3;    //位选
sbit LATCH1=P2^2;    //段选
uchar code smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //段选
void display(uchar gw,uchar sw)
{
    switch(num)
{
    case 1:P0=0xbf;
           LATCH2=1;
     LATCH2=0;
     P0=smg_du[sw];
     LATCH1=1;
     LATCH1=0;
     break;
       case 2:num=0;
           P0=0x7f;
           LATCH2=1;
     LATCH2=0;
     P0=smg_du[gw];
     LATCH1=1;
     LATCH1=0;
     break;
}
}

ds18b20采集
#include<stc12c5a60s2.h>
#include"ds18b20.h"
#include"delay.h"      //注:stc12c5a60s2单片机执行一条语句的时间是普通51单片机的1/12,在写时序时一定要注意到
sbit DQ=P2^0;
uchar data disdata[2];
uint tvalue;         //温度值
void init_ds18b20()//ds1820复位   
{
DQ=1;          //DQ复位
delay_18B20(40); //延时
DQ=0;          //DQ拉低
delay_18B20(1000); //精确延时大于480us
DQ=1;          //拉高
delay_18B20(400);
}
void write_byte(uchar dat)      //写一个字节
{
    uchar i=0;
    for(i=8;i>0;i--)
    {
   DQ=0;
      DQ=dat&0x01;
      delay_18B20(100);
      DQ=1;
      dat>>=1;
    }
}
uchar read_byte()       //读一个字节
{
    uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{  
     DQ=0; //给脉冲信号
     dat>>=1;
     DQ=1; //给脉冲信号
     if(DQ)
     dat|=0x80;
     delay_18B20(100);
}
   return(dat);
}
uchar read_temp()   //读取温度值并转换
{
    uchar a,b;
float f_temp;
init_ds18b20();   
write_byte(0xcc);   //跳过读序列号
write_byte(0x44);         //启动温度转换
delay(5);
init_ds18b20();   
write_byte(0xcc);      //跳过读序列号
write_byte(0xbe);         //读取温度
a=read_byte();
b=read_byte();
tvalue=b;
tvalue<<=8;   
tvalue|=a;
f_temp=tvalue*0.0625;
tvalue=f_temp*10+0.5;
return(tvalue);
}


主函数:
#include"ds18b20.h"
#include"timer0.h"
#include"shumaguan.h"
#include"delay.h"

void main()
{
   uchar gw,sw;
   Timer0Init();  
   while(1)
   {
      read_temp();   
      sw=tvalue/100;
      gw=tvalue%100/10;
      display(gw,sw);
   }
}

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

使用道具 举报

沙发
ID:86421 发表于 2015-12-22 20:52 | 只看该作者

回帖奖励 +10 黑币

给你一个程序,自已根据数码管的情况改一下,分析对照一下哪出了问题。这个程序用着挺好的。
  1. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #include "18b20.h"

  3. #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换

  4. sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
  5. sbit LATCH2=P2^3;//                 位锁存

  6. bit ReadTempFlag;//定义读时间标志

  7. unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
  8. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
  9. unsigned char TempData[8]; //存储显示值的全局变量


  10. void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
  11. void Init_Timer0(void);//定时器初始化
  12. /*------------------------------------------------
  13.                     主函数
  14. ------------------------------------------------*/
  15. void main (void)
  16. {                  
  17. unsigned int TempH,TempL,temp;
  18. Init_Timer0();
  19. while (1)         //主循环
  20.   {


  21. if(ReadTempFlag==1)
  22. {
  23.   ReadTempFlag=0;
  24.   temp=ReadTemperature();
  25.   if(temp&0x8000)
  26.      {
  27.      TempData[0]=0x40;//负号标志
  28.      temp=~temp;  // 取反加1
  29.          temp +=1;
  30.          }
  31.   else
  32.      TempData[0]=0;

  33.      TempH=temp>>4;
  34.      TempL=temp&0x0F;
  35.      TempL=TempL*6/10;//小数近似处理
  36.            
  37.     if(TempH/100==0)
  38.           TempData[1]=0;
  39.         else
  40.       TempData[1]=dofly_DuanMa[TempH/100]; //十位温度
  41.     if((TempH/100==0)&&((TempH%100)/10==0))//消隐
  42.           TempData[2]=0;
  43.         else
  44.      TempData[2]=dofly_DuanMa[(TempH%100)/10]; //十位温度
  45.      TempData[3]=dofly_DuanMa[(TempH%100)%10]|0x80; //个位温度,带小数点
  46.      TempData[4]=dofly_DuanMa[TempL];
  47.          TempData[6]=0x39;         //显示C符号
  48.   }       
  49. }
  50. }

  51. /*------------------------------------------------
  52. 显示函数,用于动态扫描数码管
  53. 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
  54. 如输入0表示从第一个显示。
  55. Num表示需要显示的位数,如需要显示99两位数值则该值输入2
  56. ------------------------------------------------*/
  57. void Display(unsigned char FirstBit,unsigned char Num)
  58. {
  59.       static unsigned char i=0;
  60.           

  61.            DataPort=0;   //清空数据,防止有交替重影
  62.        LATCH1=1;     //段锁存
  63.        LATCH1=0;

  64.        DataPort=dofly_WeiMa[i+FirstBit]; //取位码
  65.        LATCH2=1;     //位锁存
  66.        LATCH2=0;

  67.        DataPort=TempData[i]; //取显示数据,段码
  68.        LATCH1=1;     //段锁存
  69.        LATCH1=0;
  70.       
  71.            i++;
  72.        if(i==Num)
  73.               i=0;


  74. }
  75. /*------------------------------------------------
  76.                     定时器初始化子程序
  77. ------------------------------------------------*/
  78. void Init_Timer0(void)
  79. {
  80. TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  81. //TH0=0x00;              //给定初值
  82. //TL0=0x00;
  83. EA=1;            //总中断打开
  84. ET0=1;           //定时器中断打开
  85. TR0=1;           //定时器开关打开
  86. }
  87. /*------------------------------------------------
  88.                  定时器中断子程序
  89. ------------------------------------------------*/
  90. void Timer0_isr(void) interrupt 1
  91. {
  92. static unsigned int num;
  93. TH0=(65536-2000)/256;                  //重新赋值 2ms
  94. TL0=(65536-2000)%256;

  95. Display(0,8);       // 调用数码管扫描
  96. num++;
  97. if(num==300)        //
  98.    {
  99.     num=0;
  100.     ReadTempFlag=1; //读标志位置1
  101.         }
  102. }
复制代码
回复

使用道具 举报

板凳
ID:86421 发表于 2015-12-22 20:53 | 只看该作者
上面是主程序,下面是18B20的
  1. ------------------------------------------------*/
  2. #include"delay.h"
  3. #include"18b20.h"
  4. /*------------------------------------------------
  5.                     18b20初始化
  6. ------------------------------------------------*/
  7. bit Init_DS18B20(void)
  8. {
  9. bit dat=0;
  10. DQ = 1;    //DQ复位
  11. DelayUs2x(5);   //稍做延时
  12. DQ = 0;         //单片机将DQ拉低
  13. DelayUs2x(200); //精确延时 大于 480us 小于960us
  14. DelayUs2x(200);
  15. DQ = 1;        //拉高总线
  16. DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
  17. dat=DQ;        //如果x=0则初始化成功, x=1则初始化失败
  18. DelayUs2x(25); //稍作延时返回
  19. return dat;
  20. }

  21. /*------------------------------------------------
  22.                     读取一个字节
  23. ------------------------------------------------*/
  24. unsigned char ReadOneChar(void)
  25. {
  26. unsigned char i=0;
  27. unsigned char dat = 0;
  28. for (i=8;i>0;i--)
  29. {
  30.   DQ = 0; // 给脉冲信号
  31.   dat>>=1;
  32.   DQ = 1; // 给脉冲信号
  33.   if(DQ)
  34.    dat|=0x80;
  35.   DelayUs2x(25);
  36. }
  37. return(dat);
  38. }
  39. /*------------------------------------------------
  40.                     写入一个字节
  41. ------------------------------------------------*/
  42. void WriteOneChar(unsigned char dat)
  43. {
  44. unsigned char i=0;
  45. for (i=8; i>0; i--)
  46. {
  47.   DQ = 0;
  48.   DQ = dat&0x01;
  49.   DelayUs2x(25);
  50.   DQ = 1;
  51.   dat>>=1;
  52. }
  53. DelayUs2x(25);
  54. }

  55. /*------------------------------------------------
  56.                     读取温度
  57. ------------------------------------------------*/
  58. unsigned int ReadTemperature(void)
  59. {
  60. unsigned char a=0;
  61. unsigned int b=0;
  62. unsigned int t=0;
  63. Init_DS18B20();
  64. WriteOneChar(0xCC); // 跳过读序号列号的操作
  65. WriteOneChar(0x44); // 启动温度转换
  66. DelayMs(10);
  67. Init_DS18B20();
  68. WriteOneChar(0xCC); //跳过读序号列号的操作
  69. WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  70. a=ReadOneChar();   //低位
  71. b=ReadOneChar();   //高位

  72. b<<=8;
  73. t=a+b;

  74. return(t);
  75. }
复制代码
回复

使用道具 举报

地板
ID:86421 发表于 2015-12-22 20:54 | 只看该作者

回帖奖励 +10 黑币

延时文件
  1. #include "delay.h"
  2. /*------------------------------------------------
  3. uS延时函数,含有输入参数 unsigned char t,无返回值
  4. unsigned char 是定义无符号字符变量,其值的范围是
  5. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  6. 长度如下 T=tx2+5 uS
  7. ------------------------------------------------*/
  8. void DelayUs2x(unsigned char t)
  9. {   
  10. while(--t);
  11. }
  12. /*------------------------------------------------
  13. mS延时函数,含有输入参数 unsigned char t,无返回值
  14. unsigned char 是定义无符号字符变量,其值的范围是
  15. 0~255 这里使用晶振12M,精确延时请使用汇编
  16. ------------------------------------------------*/
  17. void DelayMs(unsigned char t)
  18. {
  19.      
  20. while(t--)
  21. {
  22.      //大致延时1mS
  23.      DelayUs2x(245);
  24.          DelayUs2x(245);
  25. }
  26. }
复制代码
回复

使用道具 举报

5#
ID:86421 发表于 2015-12-22 20:56 | 只看该作者
  1. #ifndef __DELAY_H__
  2. #define __DELAY_H__
  3. /*------------------------------------------------
  4. uS延时函数,含有输入参数 unsigned char t,无返回值
  5. unsigned char 是定义无符号字符变量,其值的范围是
  6. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  7. 长度如下 T=tx2+5 uS
  8. ------------------------------------------------*/
  9. void DelayUs2x(unsigned char t);
  10. /*------------------------------------------------
  11. mS延时函数,含有输入参数 unsigned char t,无返回值
  12. unsigned char 是定义无符号字符变量,其值的范围是
  13. 0~255 这里使用晶振12M,精确延时请使用汇编
  14. ------------------------------------------------*/
  15. void DelayMs(unsigned char t);

  16. #endif



  17. #ifndef __DS18B20_H__
  18. #define __DS18B20_H__

  19. #include<reg52.h>     //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  20. #include<intrins.h>

  21. #define uchar unsigned char
  22. #define uint   unsigned int;
  23. /*------------------------------------------------
  24.                     端口定义
  25. ------------------------------------------------*/
  26. sbit DQ=P1^3;//ds18b20 端口
  27. /*------------------------------------------------
  28.                   函数声明
  29. ------------------------------------------------*/
  30. unsigned int ReadTemperature(void);
  31. bit Init_DS18B20(void);
  32. unsigned char ReadOneChar(void);
  33. void WriteOneChar(unsigned char dat);

  34. #endif
复制代码
回复

使用道具 举报

6#
ID:86421 发表于 2015-12-22 20:56 | 只看该作者
上面是两上.H文件
回复

使用道具 举报

7#
ID:108622 发表于 2016-3-29 13:22 | 只看该作者

回帖奖励 +10 黑币

有数码管能用的程序吗?复制的文本错误
回复

使用道具 举报

8#
ID:87568 发表于 2016-3-29 21:36 | 只看该作者

回帖奖励 +10 黑币


回复

使用道具 举报

9#
ID:373388 发表于 2018-10-15 13:47 | 只看该作者
case = 0 时,就会显示上次数据,所以就乱了
回复

使用道具 举报

10#
ID:373388 发表于 2018-10-15 13:48 | 只看该作者
没有处理case 0 时的情况,当num = 0,就会显示上次数据,所以就乱了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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