c8051用ds18b20读温度的问题

[复制链接]
5035|6
 楼主| whdzh 发表于 2013-5-14 11:21 | 显示全部楼层 |阅读模式
用的c8051f340,读ds18b20,然后用串口发送数据在串口调试软件上显示,显示的数字一直就是10,各位帮忙看看程序哪里有问题啊?系统时钟是内部晶振,48M系统时钟。
  1. #include <c8051F340.h>
  2. #include <stdio.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define SYSCLK       48000000          // SYSCLK frequency in Hz
  7. #define BAUDRATE0     9600           // Baud rate of UART0 in bps
  8. #define BAUDRATE1     9600           // Baud rate of UART1 in bps
  9. sfr16 SBRL1 = 0xB4;
  10. sbit ds=P2^2;
  11. uchar flag ;
  12. uint temp;
  13. float wendu;
  14. bit UART = 0;
  15. void SYSCLK_Init (void)
  16. {
  17.     unsigned int iTmp;
  18.       OSCICN |= 0x83;
  19.     //Enable internal 4X MULL
  20.     if( !( CLKMUL & ( 1<<5 ) ) )
  21.     {
  22.         CLKMUL = 0;
  23.         CLKMUL = 0x00;
  24.         CLKMUL |= ( 1<<7 );
  25.         for( iTmp = 0; iTmp < 200; iTmp ++ );
  26.         CLKMUL |= ( 1<<6 ) | ( 1<<7 );
  27.         for( iTmp = 0; iTmp < 2000; iTmp ++ );
  28.         while( !( CLKMUL & ( 1<<5 ) ) );
  29.     }
  30.     //USB clock: 48MHz, system clock : 48MHz
  31.     CLKSEL = 0x03;
  32. }

  33. void delayus(int a)
  34. {
  35. int y ;
  36. for(;a>0;a--)
  37. {
  38.   for(y=0;y<5;y++);
  39. }
  40. }

  41. void delayms(int a)
  42. {
  43. int y ;
  44. for(;a>0;a--)
  45. {
  46.   for(y=0;y<4800;y++);
  47. }
  48. }
  49. void UART0_Init (void)
  50. {
  51.    SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
  52.                                        //        level of STOP bit is ignored
  53.                                        //        RX enabled
  54.                                        //        ninth bits are zeros
  55.                                        //        clear RI0 and TI0 bits

  56.    if (SYSCLK/BAUDRATE0/2/256 < 1) {
  57.       TH1 = -(SYSCLK/BAUDRATE0/2);
  58.       CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
  59.       CKCON |=  0x08;
  60.    } else if (SYSCLK/BAUDRATE0/2/256 < 4) {
  61.       TH1 = -(SYSCLK/BAUDRATE0/2/4);
  62.       CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01                 
  63.       CKCON |=  0x09;
  64.    } else if (SYSCLK/BAUDRATE0/2/256 < 12) {
  65.       TH1 = -(SYSCLK/BAUDRATE0/2/12);
  66.       CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
  67.    } else {
  68.       TH1 = -(SYSCLK/BAUDRATE0/2/48);
  69.       CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
  70.       CKCON |=  0x02;
  71.    }

  72.    TL1 = TH1;                          // init Timer1
  73.    TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
  74.    TMOD |=  0x20;                       
  75.    TR1 = 1;                            // START Timer1
  76.    TI0 = 1;                            // Indicate TX0 ready
  77. }
  78. void ds_rst() //初始化DS18B20
  79. {
  80. ds=1;         //         数据线置1
  81. delayus(1); //延时1us
  82. ds=0;                   //数据线置0
  83. delayus(700);         //延时700us
  84. ds=1;                         //数据线置1
  85. delayus(44);   //        延时44us
  86. if(ds==0)                //判断DS18B20的返回的低电平
  87.    flag=1;
  88. else
  89.    flag=0;
  90. delayus(140);
  91. ds=1;
  92. }

  93. bit ds_read_bit(void)//读一位
  94. {
  95. bit dat;
  96. ds=0;//单片机(微处理器)将总线拉低
  97. delayus(1);//读时隙起始于微处理器将总线拉低至少1us
  98. ds=1;//拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据
  99. delayus(2);//小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据
  100. //在读"时间隙"下降沿出现15us内有效
  101. dat=ds;//主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效
  102. delayus(77);//所有读"时间隙"必须60~120us,这里77us
  103. return(dat);//返回有效数据
  104. }

  105. uchar ds_read_byte(void ) //读一字节
  106. {
  107. uchar value,i,j;
  108. value=0;//一定别忘了给初值
  109.   for(i=0;i<8;i++)
  110.    {
  111.      j=ds_read_bit();
  112.          value=(j<<7)|(value>>1);//这一步的说明在一个word文档里面
  113.    }
  114. return(value);//返回一个字节的数据
  115. }

  116. void ds_write_byte(uchar dat) //写一个字节
  117. {
  118.   uchar i;
  119.   bit onebit;//一定不要忘了,onebit是一位
  120.   for(i=1;i<=8;i++)
  121.    {
  122.      onebit=dat&0x01;
  123.      dat=dat>>1;
  124.      if(onebit)//写 1
  125.        {
  126.          ds=0;
  127.          delayus(1);
  128.          delayus(1);//看时序图,至少延时1us,才产生写"时间隙"
  129.          ds=1;//写时间隙开始后的15μs内允许数据线拉到高电平
  130.          delayus(60);//所有写时间隙必须最少持续60us
  131.        }
  132.          else//写 0
  133.       {
  134.          ds=0;
  135.          delayus(63);//主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us
  136.          ds=1;
  137.          _nop_();
  138.          _nop_();
  139.       }
  140.    }
  141. }

  142. void tem_change()
  143. {
  144.   ds_rst();
  145.   delayms(2);//约2ms
  146.   ds_write_byte(0xcc);
  147.   ds_write_byte(0x44);
  148.   delayms(750);
  149. }

  150. uint get_temperature()
  151. {

  152.   uchar a,b;
  153.   ds_rst();
  154.   delayms(2);//约2ms
  155.   ds_write_byte(0xcc);
  156.   ds_write_byte(0xbe);
  157.   a=ds_read_byte();
  158.   b=ds_read_byte();
  159.   temp=b;
  160.   temp<<=8;
  161.   temp=temp|a;
  162.   wendu=temp*0.0625;
  163.   temp=wendu*10+0.5;
  164.   wendu=wendu+0.5;
  165.   return temp;
  166. }

  167. void main()
  168. {
  169. char input_char;

  170.   PCA0MD &= ~0x40;
  171.   SYSCLK_Init ();
  172.   XBR0     = 0x01;
  173.   XBR1     = 0x40;
  174.   P0MDOUT |= 0x11;                 
  175.   P2MDOUT |= 0x04;
  176.   UART0_Init ();
  177.   while(1)
  178.   {
  179.    tem_change();//12位转换时间最大为750ms
  180.    get_temperature();
  181.    input_char = getchar();
  182.    
  183.       
  184.       switch (input_char) {
  185.          case '1':
  186.                  printf ("%x\n",&wendu);
  187.             break;
  188.          default:
  189.             break;
  190.       }
  191.   }
  192. }

  193. char putchar (char c)  {

  194.    if (UART == 0) {

  195.       if (c == '\n')  {                // check for newline character
  196.          while (!TI0);                 // wait until UART0 is ready to transmit
  197.          TI0 = 0;                      // clear interrupt flag
  198.          SBUF0 = 0x0d;                 // output carriage return command
  199.       }
  200.       while (!TI0);                    // wait until UART0 is ready to transmit
  201.       TI0 = 0;                         // clear interrupt flag
  202.       return (SBUF0 = c);              // output <c> using UART 0
  203.    }

  204.    else if (UART == 1) {
  205.       if (c == '\n')  {                // check for newline character
  206.          while (!(SCON1 & 0x02));      // wait until UART1 is ready to transmit
  207.          SCON1 &= ~0x02;               // clear TI1 interrupt flag
  208.          SBUF1 = 0x0d;                 // output carriage return
  209.       }
  210.       while (!(SCON1 & 0x02));         // wait until UART1 is ready to transmit
  211.       SCON1 &= ~0x02;                  // clear TI1 interrupt flag
  212.       return (SBUF1 = c);              // output <c> using UART 1
  213.    }
  214. }

  215. //-----------------------------------------------------------------------------
  216. // _getkey
  217. //-----------------------------------------------------------------------------
  218. //
  219. // Return Value : byte received from UART0/1
  220. // Parameters   : none

  221. // This is an overloaded fuction found in the stdio library.  When the
  222. // function _getkey is called, either by user code or through calls to stdio
  223. // routines such as scanf, the following routine will be executed instead
  224. // of the function located in the stdio library.
  225. //
  226. // The function checks the UART global variable to determine which UART to
  227. // use to receive a character.
  228. //
  229. // The routine waits for RI0/RI1 to be set, indicating that a byte has
  230. // been received across the UART0/UART1 RX line.  The routine saves the
  231. // received character into a local variable, clears the RI0/RI1 interrupt
  232. // flag, and returns the received character value.
  233. //
  234. //-----------------------------------------------------------------------------
  235. char _getkey ()  {
  236.   char c;

  237.   if (UART == 0) {
  238.     while (!RI0);                      // wait until UART0 receives a character
  239.     c = SBUF0;                         // save character to local variable
  240.     RI0 = 0;                           // clear UART0 receive interrupt flag
  241.     return (c);                        // return value received through UART0
  242.   }

  243.   else if (UART == 1) {
  244.     while (!(SCON1 & 0x01));           // wait until UART1 receives a character
  245.     c = SBUF1;                         // save character to local variable
  246.     SCON1 &= ~0x01;                    // clear UART1 receive interrupt flag
  247.     return (c);                        // return value received through UART1
  248.   }
  249. }
若雪心情 发表于 2013-5-14 13:14 | 显示全部楼层
printf ("%x\n",&wendu);   是不是你把wendu这个变量的地址给打印出来了
ayb_ice 发表于 2013-5-14 13:31 | 显示全部楼层
printf ("%x\n",&wendu);

这个语句确实有问题
 楼主| whdzh 发表于 2013-5-14 14:44 | 显示全部楼层
若雪心情 发表于 2013-5-14 13:14
printf ("%x\n",&wendu);   是不是你把wendu这个变量的地址给打印出来了

是吗?这个还真心不清楚。。我是新手,以前没写过串口的。。。那应该怎么改才是打印这个变量的值呢?
 楼主| whdzh 发表于 2013-5-14 14:50 | 显示全部楼层
ayb_ice 发表于 2013-5-14 13:31
printf ("%x\n",&wendu);

这个语句确实有问题

好像确实有问题。。。我单独给变量赋值然后输出也是不对。。。
ayb_ice 发表于 2013-5-14 15:17 | 显示全部楼层
你这是打印输出变量地址,不是变量值
hfuter 发表于 2013-8-2 21:19 | 显示全部楼层
我的好像也是输出10.0,而且10.0还不是全亮,就是亮度不够
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部