打印

c8051用ds18b20读温度的问题

[复制链接]
4614|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
whdzh|  楼主 | 2013-5-14 11:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用的c8051f340,读ds18b20,然后用串口发送数据在串口调试软件上显示,显示的数字一直就是10,各位帮忙看看程序哪里有问题啊?系统时钟是内部晶振,48M系统时钟。
#include <c8051F340.h>
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SYSCLK       48000000          // SYSCLK frequency in Hz
#define BAUDRATE0     9600           // Baud rate of UART0 in bps
#define BAUDRATE1     9600           // Baud rate of UART1 in bps
sfr16 SBRL1 = 0xB4;
sbit ds=P2^2;
uchar flag ;
uint temp;
float wendu;
bit UART = 0;
void SYSCLK_Init (void)
{
    unsigned int iTmp;
      OSCICN |= 0x83;
    //Enable internal 4X MULL
    if( !( CLKMUL & ( 1<<5 ) ) )
    {
        CLKMUL = 0;
        CLKMUL = 0x00;
        CLKMUL |= ( 1<<7 );
        for( iTmp = 0; iTmp < 200; iTmp ++ );
        CLKMUL |= ( 1<<6 ) | ( 1<<7 );
        for( iTmp = 0; iTmp < 2000; iTmp ++ );
        while( !( CLKMUL & ( 1<<5 ) ) );
    }
    //USB clock: 48MHz, system clock : 48MHz
    CLKSEL = 0x03;
}

void delayus(int a)
{
int y ;
for(;a>0;a--)
{
  for(y=0;y<5;y++);
}
}

void delayms(int a)
{
int y ;
for(;a>0;a--)
{
  for(y=0;y<4800;y++);
}
}
void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits

   if (SYSCLK/BAUDRATE0/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE0/2);
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } else if (SYSCLK/BAUDRATE0/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE0/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01                 
      CKCON |=  0x09;
   } else if (SYSCLK/BAUDRATE0/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE0/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else {
      TH1 = -(SYSCLK/BAUDRATE0/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;                       
   TR1 = 1;                            // START Timer1
   TI0 = 1;                            // Indicate TX0 ready
}
void ds_rst() //初始化DS18B20
{
ds=1;         //         数据线置1
delayus(1); //延时1us
ds=0;                   //数据线置0
delayus(700);         //延时700us
ds=1;                         //数据线置1
delayus(44);   //        延时44us
if(ds==0)                //判断DS18B20的返回的低电平
   flag=1;
else
   flag=0;
delayus(140);
ds=1;
}

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

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

void ds_write_byte(uchar dat) //写一个字节
{
  uchar i;
  bit onebit;//一定不要忘了,onebit是一位
  for(i=1;i<=8;i++)
   {
     onebit=dat&0x01;
     dat=dat>>1;
     if(onebit)//写 1
       {
         ds=0;
         delayus(1);
         delayus(1);//看时序图,至少延时1us,才产生写"时间隙"
         ds=1;//写时间隙开始后的15μs内允许数据线拉到高电平
         delayus(60);//所有写时间隙必须最少持续60us
       }
         else//写 0
      {
         ds=0;
         delayus(63);//主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us
         ds=1;
         _nop_();
         _nop_();
      }
   }
}

void tem_change()
{
  ds_rst();
  delayms(2);//约2ms
  ds_write_byte(0xcc);
  ds_write_byte(0x44);
  delayms(750);
}

uint get_temperature()
{

  uchar a,b;
  ds_rst();
  delayms(2);//约2ms
  ds_write_byte(0xcc);
  ds_write_byte(0xbe);
  a=ds_read_byte();
  b=ds_read_byte();
  temp=b;
  temp<<=8;
  temp=temp|a;
  wendu=temp*0.0625;
  temp=wendu*10+0.5;
  wendu=wendu+0.5;
  return temp;
}

void main()
{
char input_char;

  PCA0MD &= ~0x40;
  SYSCLK_Init ();
  XBR0     = 0x01;
  XBR1     = 0x40;
  P0MDOUT |= 0x11;                 
  P2MDOUT |= 0x04;
  UART0_Init ();
  while(1)
  {
   tem_change();//12位转换时间最大为750ms
   get_temperature();
   input_char = getchar();
   
      
      switch (input_char) {
         case '1':
                 printf ("%x\n",&wendu);
            break;
         default:
            break;
      }
  }
}

char putchar (char c)  {

   if (UART == 0) {

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

   else if (UART == 1) {
      if (c == '\n')  {                // check for newline character
         while (!(SCON1 & 0x02));      // wait until UART1 is ready to transmit
         SCON1 &= ~0x02;               // clear TI1 interrupt flag
         SBUF1 = 0x0d;                 // output carriage return
      }
      while (!(SCON1 & 0x02));         // wait until UART1 is ready to transmit
      SCON1 &= ~0x02;                  // clear TI1 interrupt flag
      return (SBUF1 = c);              // output <c> using UART 1
   }
}

//-----------------------------------------------------------------------------
// _getkey
//-----------------------------------------------------------------------------
//
// Return Value : byte received from UART0/1
// Parameters   : none

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

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

  else if (UART == 1) {
    while (!(SCON1 & 0x01));           // wait until UART1 receives a character
    c = SBUF1;                         // save character to local variable
    SCON1 &= ~0x01;                    // clear UART1 receive interrupt flag
    return (c);                        // return value received through UART1
  }
}

相关帖子

沙发
若雪心情| | 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这个变量的地址给打印出来了

是吗?这个还真心不清楚。。我是新手,以前没写过串口的。。。那应该怎么改才是打印这个变量的值呢?

使用特权

评论回复
5
whdzh|  楼主 | 2013-5-14 14:50 | 只看该作者
ayb_ice 发表于 2013-5-14 13:31
printf ("%x\n",&wendu);

这个语句确实有问题

好像确实有问题。。。我单独给变量赋值然后输出也是不对。。。

使用特权

评论回复
6
ayb_ice| | 2013-5-14 15:17 | 只看该作者
你这是打印输出变量地址,不是变量值

使用特权

评论回复
7
hfuter| | 2013-8-2 21:19 | 只看该作者
我的好像也是输出10.0,而且10.0还不是全亮,就是亮度不够

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝