xuan12321 发表于 2012-12-2 01:41:10

求助 cvavr 编程的ds18b20在protues中不能成功读取温度值

本帖最后由 xuan12321 于 2012-12-2 01:42 编辑

刚开始用cvavr,很多都不怎么会弄,我的程序没有调用库里带的1wire函数,改了n久,就出现fff.f 、37.6、 -000.0,我调ds18b20 温度时,它们都不动的,估计是没有成功读数据来。这个问题纠结死我了,我把我的程序贴上来,求高人指点,有好心人事以前编过的话,希望能提供些参考程序(最好是能仿真的)最近在网上搜了很多程序,都是仿真不过的(端口我都是按照我的原理图从新设置的),这使我更纠结。
我用51单片机,用keil软件按时序图编过ds18b20 的程序,在protues中也仿真成功了,我下面的程序主要是根据那个程序,用cvavr编写的,求大侠指点迷津,小弟在此先谢过啦~
/***************************************************************************
我先给出我的端口定义的头文件,ds18b20函数我也是写在头文件里的。在定义头文件的下面
****************************************************************************/
#ifndef _dspredef_h_
#define _dspredef_h_

#include <mega16.h>

#include <delay.h>

//#define nop() #asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")#asm ("nop")
                  
            


#define uchar unsigned char
#define uint unsigned int

#define openlcd DDRC = 0xc0;DDRB = 0xff
#define lcden PORTC.6
#define lcdrs PORTC.7

#define outdsdq DDRA.7 = 1
#define indsdq DDRA.7 = 0
#define ds18dqw PORTA.7
#define ds18dqr PINA.7


#endif

/********************************************************************************************************************
下面就会我编的ds18b20的函数,帮我看看是哪里出现的问题,这个程序仿真是,lcd一直显示的是037.6(我设置的是4位显示所以前面有个0);
*********************************************************************************************************************/


#ifndef _dsfun_h_
#define _dsfun_h_

#include <dspredef.h>

uchar numtable[] = "0123456789. -";
uchar tmpcode = {0,0,0,0,0,0};

uchar dsreset()
{
    uchar a;
    outdsdq;
    ds18dqw = 0;
   
    #asm("cli")
    delay_us(500);
    #asm("sei")
   
    ds18dqw = 1;
   
    #asm("cli")
    delay_us(100);
    #asm("sei")
   
    indsdq;
    a = ds18dqr;
    a = ds18dqr;
   
    #asm("cli")
    delay_us(500);
    #asm("sei")
   
    return (a);
      
}

uchar dsread()
{
    uchar i,k = 0,buf;
    i = 8;
    while(i--)
    {   
      outdsdq;
      ds18dqw = 0;
      
      #asm("cli")
      delay_us(10);
      #asm("sei")
      
      ds18dqw = 1;
      indsdq;
      k >>= 1;
      buf = ds18dqr;
      buf = ds18dqr;
      if(buf)k |= 0x80;
      
      #asm("cli")
      delay_us(50);
      #asm("sei")
      
    }
    return (k);
}

void dswrite(uchar dat)
{
    uint j;
    outdsdq;
    for(j = 1;j <= 8;j++)
    {
      ds18dqw = 0;
      
      #asm("cli")
      delay_us(10);
      #asm("sei")
      
      if(dat & 0x01)
      {
            ds18dqw =1;
            
//            #asm("cli")
//            delay_us(45);
//            #asm("sei")
      }
//      else
//      {
//            ds18dqw = 0;
//            
//            #asm("cli")
//            delay_us(45);
//            #asm("sei")
//            
//            ds18dqw = 1;
//            
//            #asm("cli")
//            delay_us(35);
//            #asm("sei")
//      }
      #asm("cli")
      delay_us(100);
      #asm("sei")
      ds18dqw = 1;   
      dat >>= 1;
    }
}

void dschange()
{
    dsreset();
    dswrite(0xcc);
    dswrite(0x44);   
}

uint dstmp()
{
    uchar tmpl,tmph;
    uint tmp;
    dsreset();
    dswrite(0xcc);
    dswrite(0xbe);
    tmpl = dsread();
    tmph = dsread();
   
    tmp = tmpl;
    tmp <<= 8;
    tmp |= tmph;
   
    return (tmp);
   
      
}

void tmpdispose(uint t)
{   
    if(t <= 0x07ff)
    tmpcode = numtable;
    else
    {
      tmpcode = numtable;
      t = ~t +1;
    }
    t *= 0.625;
    tmpcode = numtable;
    tmpcode = numtable[(t % 1000) / 100];
    tmpcode = numtable[(t % 100) / 10];
    tmpcode = numtable;
    tmpcode = numtable;
}

#endif

/************************************主函数是****************************/
#include <dspredef.h>
#include <lcdfun.h>
#include <dsfun.h>

void main()
{
    lcdinit();

    while(1)
    {
      dschange();
      delay_ms(750);
      tmpdispose(dstmp());
      lcddiss(0,1,6,tmpcode);
    }
}
/*******************************显示函数式ok的,些的不好也不难出来献丑了***************求大侠帮我看看,有什么好的建议或者是好的参考程序可以发到我的邮箱里,我的邮箱是xuanfengdanxin_002@163.com******/

xuan12321 发表于 2012-12-2 01:43:41

{:cry:}求大侠关注,求高人指点

xuan12321 发表于 2012-12-2 11:54:59

{:sleepy:}求人指点,给点意见吧

xuan12321 发表于 2012-12-4 20:07:04

咋就没人来呢,来了就留点痕迹啦,说不定能引起高手的关注的,

xqn2012 发表于 2012-12-12 16:37:43

CVAVR没用过。ICC的程序我倒是有

xuan12321 发表于 2012-12-12 23:06:44

哦,有仿真图和源程序么,有的话发到我邮箱里咯,164148250@qq.com先谢过啦,我现在遇到的问题是,我通过下面的延时程序:
void delayus(uchar xus)
{
    uchar a,b;
    for(b = xus;b > 0;b--)
      for(a = 5;a > 0;a--);            
}

void delay1ms()
{
    uchar a,b,c;
    for(c = 17;c > 0;c--)
      for(b = 134;b > 0;b--)
            for(a = 2;a > 0;a--);
}

void delayms(uint xms)
{
    uint i;
    for(i = 0;i < xms;i++)
      delay1ms();
}
我用的16M的晶振,按照ds18b20的时序进行仿真,结果在protues开始仿真的时候,感觉速度好慢,整个程序一个都没用超过两秒的延迟,结果,过了30多秒才开始读到数据,是不是在protues要调什么东西,让它和实物的运行时间一致啊?

xuan12321 发表于 2012-12-12 23:16:36

我今天用下面程序调试了还是没结果
#include <mega16.h>

#define uchar unsigned char
#define uint unsigned int

/*******************lcd define*************/
#define lcdopen DDRB = 0xff;DDRC = 0xc0
#define lcden PORTC.6
#define lcdrs PORTC.7

/*******************DS18B20 define **********************/
#define dqout DDRA.7 = 1
#define dqin DDRA.7 = 0
#define dqset PORTA.7 = 1
#define dqcli PORTA.7 = 0
#define dq PINA.7

/*****************variable define************************/

uchar numtable[] = "0123456789.+-";
uchar table1[]="hello20121212!";
uchar table2[]="temperature:";
uchar temperature[]={0,0,0,0,0,0};
/*****************delay function*****************/
void delayus(uchar xus)
{
   uchar a,b;
   for(b = xus;b > 0;b--)
         for(a = 5;a > 0;a--);            
}

void delay1ms()
{
   uchar a,b,c;
   for(c = 17;c > 0;c--)
         for(b = 134;b > 0;b--)
             for(a = 2;a > 0;a--);
}

void delayms(uint xms)
{
   uint i;
   for(i = 0;i < xms;i++)
         delay1ms();
}

/*****************lcd function******************/
void lcdwritedat(uchar rs,uchar dat)
{
   lcdrs = rs;
   PORTB = dat;
   delayus(16);
   lcden = 1;
   lcden = 0;
   if(!rs)delayus(16);
}

void lcdinit()
{
   delayms(40);
   lcdopen;
   lcdwritedat(0,0x38);
   lcdwritedat(0,0x01);
   lcdwritedat(0,0x06);
   lcdwritedat(0,0x0c);
}

void lcddis(uchar line,uchar addr,uchar digit,uchar *dat)
{
   uchar linecode,i;
   switch(line)
   {
   case 1:linecode = 0x00;break;
   case 2:linecode = 0x40;break;
   case 3:linecode = 0x14;break;
   case 4:linecode = 0x54;break;
   }
   lcdwritedat(0,0x80+addr+linecode);
   for(i = 0;i < digit;i++)
   lcdwritedat(1,dat);
}
/**********************************DS18B20 function********************/
void dsinit()
{
   dqout;
   dqcli;
   delayus(480);
   dqset;
   
    delayus(480);
}
uchar dsread()
{
   uchar i,k = 0;
   for(i = 8;i > 0;i--)
   {   
         dqout;
         dqcli;
         delayus(1);
         dqset;
         dqin;
         k >>= 1;
         if(dq)k |= 0x80;
         delayus(60);
   }
   return (k);
}

void dswrite(uchar dat)
{
   uchar i;
   dqout;
   for(i = 0;i < 8;i++)
   {
         dqcli;
         delayus(1);
         if(dat & 0x01)
         {
             dqset;
             delayus(60);
         }
         else
         {
             dqcli;
             delayus(60);
             dqset;
             delayus(2);
         }
         dat >>= 1;
   }
         
}

void dschange()
{
   dsinit();

    dswrite(0xcc);
   dswrite(0x44);
}

void dstmp()
{
   uchar tmpl = 0,tmph = 0;
   uint t = 0;
   dsinit();

    dswrite(0xcc);
   dswrite(0xbe);
   tmpl = dsread();
   tmph = dsread();
   
    t = tmph;
   t <<= 8;
   t += tmpl;
   
    if(t <=0x7ff)
   temperature = numtable;
   else
   {
         temperature = numtable;
         t = ~t+1;
   }
   t *= 0.625;
   temperature = numtable;
   temperature = numtable[(t % 1000)/100];
   temperature = numtable[(t % 100)/10];
   temperature = numtable;
   temperature = numtable;
   
   
}

//void displayt(uchar line,uchar address,uint t)
//{      
//      t *= 0.625;
//      lcdwritedat(0,0x80+(line-1)*0x40 +address);
//      if(tflag == 1)
//      lcdwritedat(1,'-');
//      else lcdwritedat(1,' ');
//
//      lcdwritedat(1,numtable);
//      lcdwritedat(1,numtable[(t % 1000)/100]);
//      lcdwritedat(1,numtable[(t%100)/10]);
//      lcdwritedat(1,'.');
//      lcdwritedat(1,numtable);
//}

void main()
{
   lcdinit();
   lcddis(1,0,14,table1);
   lcddis(2,0,12,table2);
   
   
    while(1)
   {
         dschange();
         delayms(750);
         dstmp();
         
         lcddis(3,0,6,temperature);
   }
}
得到的显示的数据时-000.0,估计是没读到真实数据。求高手点解~
页: [1]
查看完整版本: 求助 cvavr 编程的ds18b20在protues中不能成功读取温度值