搜索
bottom↓
回复: 8

CVAVR写的DS18B20只显示15的问题!菜鸟跪求解决

[复制链接]

出0入0汤圆

发表于 2012-6-1 21:13:45 | 显示全部楼层 |阅读模式
本人刚学AVR是学习马老师的书,试学着用CVAVR写个DS18B20检测温度在LCD1602上显示就出现了问题




     
#include <mega16.h>
#include <delay.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
uchar teml,temh,tem,tt,a,b;
flash uchar table[]={'0','1','2','3','4','5','6','7','8','9',};
// 1 Wire Bus functions
#asm
   .equ __w1_port=0x1B ;PORTA
   .equ __w1_bit=0
#endasm
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// 1 Wire Bus initialization
//w1_init();

// LCD module initialization
lcd_init(16);
while (1)
      {
      w1_write(0XCC); //发转换命令
      w1_write(0X44); //启动
      delay_ms(750);
        w1_init();
        w1_write(0XCC); //读
        w1_write(0XBE);

        teml=w1_read();
        temh=w1_read();
        delay_ms(750); //延时
        tem=temh;
        tem=tem*256;
        tem|=teml;
        tt=tem*0.0625;
        tem=tt*10+0.5;

        //tem=ds1820_read_spd(0xbe);
        //tem=0x16;
        a=tem/100;
        b=tem%100/10;
        
        //a=4;b=5;
        
         lcd_clear();
         lcd_gotoxy(6,0 );
         lcd_putsf("temp");
         lcd_gotoxy(6,1 );     
         lcd_putchar(table[a]);
         lcd_gotoxy(8,1 );
         lcd_putchar(table[b]);
         
      };
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-6-16 00:06:21 | 显示全部楼层
当年也遇到过,好像是时序的问题,不记得了

出0入0汤圆

发表于 2012-8-28 19:41:22 | 显示全部楼层
你的液晶能显示出来东西吗

出0入0汤圆

发表于 2012-12-12 23:10:09 | 显示全部楼层
我没调用1_wire函数,也仿真不出来数据,郁闷了,我通过下面的延时程序:
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要调什么东西,让它和实物的运行时间一致啊?
液晶显示是ok的,

出0入0汤圆

发表于 2012-12-12 23:13:21 | 显示全部楼层
我还是把我的所有程序都给出来吧
#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[i]);
}
/**********************************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[0] = numtable[11];
    else
    {
        temperature[0] = numtable[12];
        t = ~t+1;
    }
    t *= 0.625;
    temperature[1] = numtable[t/1000];
    temperature[2] = numtable[(t % 1000)/100];
    temperature[3] = numtable[(t % 100)/10];
    temperature[4] = numtable[10];
    temperature[5] = numtable[t % 10];
   
   
}

//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[t / 1000]);
//        lcdwritedat(1,numtable[(t % 1000)/100]);
//        lcdwritedat(1,numtable[(t%100)/10]);
//        lcdwritedat(1,'.');
//        lcdwritedat(1,numtable[t%10]);
//}

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,估计是没读到真实数据。求高手点解~

出0入0汤圆

发表于 2012-12-18 09:41:14 | 显示全部楼层
你没reset吧,每次

出0入0汤圆

发表于 2012-12-18 17:55:54 | 显示全部楼层
xuan12321 发表于 2012-12-12 23:13
我还是把我的所有程序都给出来吧
#include

朋友  我和你一样的问题  我的问题也是出现15   我感觉应该是掩饰函数有问题   我用的是8M的内部晶振   在网上找的8M的微妙延时函数    应该就是这里出问题了 导致读写时序不正常 可是我也不会DEBUG,

加我我的QQ16264405     我们互相讨论互相学习一下

出0入0汤圆

发表于 2012-12-18 20:56:30 | 显示全部楼层
先看CVAVR的HELP中的例子

Maxim/Dallas Semiconductor DS18B20 Temperature Sensor Functions Previous Top Next  
--------------------------------------------------------------------------------

These functions are intended for easy interfacing between C programs and the DS18B20 1 Wire bus temperature sensor.
The prototypes for these functions are placed in the file ds18b20.h, located in the .\INC subdirectory. This file must be #include -d before using the functions.
The 1 Wire bus functions prototypes are automatically #include -d with the ds18b20.h.


The 1 Wire functions must be configured, by specifying the I/O port and bit used for communication through the 1 Wire protocol.
This is accomplished in the Project|Configure|C Compiler|Libraries|1 Wire menu:
·   the Enable 1 Wire Bus Interface Support option must be activated
·   the I/O Port and Bit must be specified in Data Connection.




The DS18B20 functions are:


unsigned char ds18b20_read_spd(unsigned char *addr)


      this function reads the contents of the SPD for the DS18B20 sensor with the ROM code stored in an array of 8 bytes located at address addr.
The functions returns the value 1 on succes and 0 in case of error.
If only one DS18B20 sensor is used, no ROM code array is necessary and the pointer addr must be NULL (0).
The contents of the SPD will be stored in the structure:


struct __ds18b20_scratch_pad_struct
       {
       unsigned char temp_lsb,temp_msb,
                temp_high,temp_low,
                conf_register,
                res1,
                res2,
                res3,
                crc;
       } __ds18b20_scratch_pad;


defined in the ds18b20.h header file.


unsigned char ds18b20_init(unsigned char *addr,signed char temp_low,signed char temp_high,unsigned char resolution)


      this function sets the low (temp_low) and high (temp_high) temperature alarms and specifies the temperature measurement resolution of the DS18B20.
The resolution argument may take the value of one of the following macros defined in the ds18b20.h header file:


      DS18B20_9BIT_RES for 9 bit tempearture measurement resolution (0.5°C)
      DS18B20_10BIT_RES for 10 bit tempearture measurement resolution (0.25°C)
      DS18B20_11BIT_RES for 11 bit tempearture measurement resolution (0.125°C)
      DS18B20_12BIT_RES for 12 bit tempearture measurement resolution (0.0625°C)


In case of success the function returns the value 1, else it returns 0.
The alarm temperatures and resolution are stored in both the DS18B20's scratchpad SRAM and its EEPROM.
The ROM code needed to address the device is stored in an array of 8 bytes located at address addr.
If only one DS18B20 sensor is used, no ROM code array is necessary and the pointer addr must be NULL (0).
The alarm status for all the DS18B20 devices on the 1 Wire bus can be determined by calling the w1_search function with the Alarm Search (ECh) command.


float ds18b20_temperature(unsigned char *addr)


      this function returns the temperature of the DS18B20 sensor with the ROM code stored in an array of 8 bytes located at address addr.
The temperature is measured in °C. In case of error the function returns the value -9999.
If only one DS18B20 sensor is used, no ROM code array is necessary and the pointer addr must be NULL (0).
Prior on calling the the ds18b20_temperature function for the first time, the ds18b20_init function must be used to specify the desired temperature measurement resolution.
If more several sensors are used, then the program must first identify the ROM codes for all the sensors.
Only after that the ds18b20_temperature function may be used, with the addr pointer pointing to the array which holds the ROM code for the needed device.


Example:


#include <mega8515.h>


/* the ATmega8515 port and bit used for the 1 Wire bus must be
   specified in the Project|Configure|C Compiler|Libraries 1 Wire
   menu */


/* include the DS18B20 functions prototypes */
#include <ds18b20.h>


/* include the printf function prototype */
#include <stdio.h>


/* quartz crystal frequency [Hz] */
#define xtal 4000000L


/* Baud rate */
#define baud 9600


/* maximum number of DS18B20 connected to the bus */
#define MAX_DEVICES 8


/* DS18B20 devices ROM code storage area,
   9 bytes are used for each device
   (see the w1_search function description),
   but only the first 8 bytes contain the ROM code
   and CRC */
unsigned char rom_codes[MAX_DEVICES][9];


/* allocate space for ROM codes of the devices
   which generate an alarm */
unsigned char alarm_rom_codes[MAX_DEVICES][9];


main()
{
unsigned char i,devices;


/* initialize the UART's baud rate */
UBRR=xtal/16/baud-1;


/* initialize the UART control register
   TX enabled, no interrupts, 8 data bits */
UCR=8;


/* detect how many DS18B20 devices
   are connected to the bus and
   store their ROM codes in the rom_codes array */
devices=w1_search(0xf0,rom_codes);


/* display the number */
printf("%-u DEVICE(S) DETECTED\n\r",devices);


/* if no devices were detected then halt */
if (devices==0) while (1); /* loop forever */


/* set the temperature alarms & temperature
   measurement resolutions for all the devices
   temp_low=25°C temp_high=35°C resolution 12bits */
for (i=0;i<devices;i++)
    {
    printf("INITIALIZING DEVICE #%-u ",i+1);
    if (ds18b20_init(&rom_codes[i][0],25,35,DS18B20_12BIT_RES))
       putsf("OK"); else putsf("ERROR");
    };


while (1)
      {
      /* measure and display the temperature(s) */
      for (i=0;i<devices;)
          printf("t%u=%+.3f\xf8C\n\r",i+1,
          ds18b20_temperature(&rom_codes[i++][0]));


      /* display the number of devices which
         generated an alarm */      
      printf("ALARM GENERATED BY %-u DEVICE(S)\n\r",
      w1_search(0xec,alarm_rom_codes));
      };
}


Refer to the DS18B20 data sheet for more information.


  

出0入0汤圆

发表于 2014-4-27 21:06:32 | 显示全部楼层
路过路过了  顺便看看
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 01:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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