搜索
bottom↓
回复: 4

ds18b20 Proteus仿真没有问题,但实际不行,请教!!!

[复制链接]

出0入8汤圆

发表于 2010-3-18 12:59:54 | 显示全部楼层 |阅读模式
ds18b20 Proteus仿真没有问题,但实际不行,实际读出来的是乱码。
单片机为M16,晶体是7.3728MHz

#ifndef __Port_H_
#define __Port_H_

#include <avr/io.h>
// 数码显示
#define DISPLAY_LED                                PORTC
#define DISPLAY_BIT_CNT                            PORTA
// 按键       
#define KEY_UP_PAD                                PINA
#define KEY_UP                                0x01
#define KEY_MEUN_PAD                                   PIND                       
#define KEY_MEUN                                0x80

#define HT1381_IO                                PORTB       
#define ht1381_rst                                2
#define ht1381_ada                                1
#define ht1381_clk                                0
// DS18B20
#define DQ                                           4

#endif /* _Port_H_ */



#include <avr/io.h>
#include <util/delay.h>
#include "Port.h"
#include "SEG_MPX4_CA.h"


static void ds18b20_write_0(void);
static void ds18b20_write_1(void);

unsigned char ConvertTime;
unsigned int Thermometer;

void ds18b20_rst(void)
{
        DDRB |= (1 << DQ);                        // 输出
        PORTB &= ~(1 << DQ);                        // 0电平
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        PORTB |= (1 << DQ);                        // 输出高
        DDRB &= ~(1 << DQ);                        // 读
        _delay_us (15);                                // 等待50uS
        while (PINB & (1 << DQ));                // 等待DS18B20应答脉冲
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
        _delay_us (100);
}

void ds18b20_write_0(void)
{
        DDRB |= (1 << DQ);                        // 输出
        PORTB &= ~(1 << DQ);                        // 0电平
        _delay_us (15);                                // 主机拉低数据线
        _delay_us (15);                                // 60uS输出低电平
        _delay_us (30);                                // 60uS输出低电平
        PORTB |= (1 << DQ);                        // 主机写0完成       

}

void ds18b20_write_1(void)
{
        DDRB |= (1 << DQ);                        // 输出
        PORTB &= ~(1 << DQ);                        // 0电平
        _delay_us (15);                                // 主机拉低数据线
        PORTB |= (1 << DQ);                        // 主机写1
        _delay_us (15);
        _delay_us (30);                                // 30uS输出低电平
}


void ds18b20_write_comm(unsigned char val)
{
        unsigned char i;
        for (i=0; i<8; i++)
        {
                if (val & 0x01)
                {       
                        ds18b20_write_1();
                }
                else
                {
                        ds18b20_write_0();
                }
                _delay_us (20);
                val = val >> 1;
        }
}       
unsigned char ds18b20_read(void)
{
        unsigned char i;
        unsigned char temp;
        unsigned char ucData;
        for (i=0; i<8; i++)
        {
                ucData = ucData >> 1;
                DDRB |= (1 << DQ);                        // 输出
                PORTB &= ~(1 << DQ);                        // 0电平
                _delay_us(15);                                // 主机拉低数据线
                       
                PORTB |= (1 << DQ);                        // 输入上拉
                DDRB &= ~(1 << DQ);
                _delay_us(20);                                // 主机采样时间
                temp = PINB & (1 << DQ);                //  读单总线数据
                _delay_us (60);
                DDRB |= (1 << DQ);                        // 输出
                if (temp)
                {
                        ucData |= 0x80;
                }
                _delay_us (20);
        }
        return ucData;
}


void ds18b20_Convert(void)
{
        ds18b20_rst();
        ds18b20_write_comm(0xCC);
        ds18b20_write_comm(0x44);

}

void ds18b20_read_t(void)
{
        static float t;
        ds18b20_rst();
        ds18b20_write_comm(0xCC);
        ds18b20_write_comm(0xbe);
        ((unsigned char *)(&Thermometer))[0]  = ds18b20_read();
        ((unsigned char *)(&Thermometer))[1]  = ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        ds18b20_read();
        if (((unsigned char *)(&Thermometer))[1] & 0xf8)
        {        // 是0下温度

        }
        else
        {
                t = Thermometer * 0.0625;
                //Thermometer = t * 100 + (Thermometer > 0 ? 0.5 : -0.5);
                Thermometer = t * 100;
        }
        DisplayBuffer[0] = Thermometer / 1000;
        Thermometer = Thermometer % 1000;
       
        DisplayBuffer[1] = Thermometer / 100;
        Thermometer = Thermometer % 100;
       
        DisplayBuffer[2] = Thermometer / 10;
        DisplayBuffer[3]  = Thermometer % 10;       
}
void ds18b20_run(void)
{
        float t;
        ds18b20_rst();
        ds18b20_write_comm(0xCC);
        ds18b20_write_comm(0xbe);
        ((unsigned char *)(&Thermometer))[0]  = ds18b20_read();
        ((unsigned char *)(&Thermometer))[1]  = ds18b20_read();
        ds18b20_rst();
        ds18b20_write_comm(0xCC);
        ds18b20_write_comm(0x44);
       
        if (((unsigned char *)(&Thermometer))[1] & 0xf8)
        {        // 是0下温度

        }
        else
        {
                t = Thermometer * 0.0625;
                //Thermometer = t * 100 + (Thermometer > 0 ? 0.5 : -0.5);
                Thermometer = t * 100;
        }
        DisplayBuffer[0] = Thermometer / 1000;
        Thermometer = Thermometer % 1000;
       
        DisplayBuffer[1] = Thermometer / 100;
        Thermometer = Thermometer % 100;
       
        DisplayBuffer[2] = Thermometer / 10;
        DisplayBuffer[3]  = Thermometer % 10;
       
}

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

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

出0入0汤圆

发表于 2010-3-19 03:02:09 | 显示全部楼层
回复【楼主位】skype  
-----------------------------------------------------------------------
Look at the following ...
                Init_DS18B20();
                WriteOneChar(SkipRom); // Skip ROM command
                WriteOneChar(ConvertT); // initiates a single temperature conversion
                _delay_ms(750); // must be wait 750ms after 0x44, otherwise it only showing 85 default value
                Init_DS18B20();
                WriteOneChar(SkipRom);
                WriteOneChar(ReadScratchpad); // read the contents of the scratchpad
                temp_data[0] = ReadOneChar();
                temp_data[1] = ReadOneChar();
You need 750 delay when issue 0x44 ConvertT command.

出0入0汤圆

发表于 2010-3-19 10:45:45 | 显示全部楼层
VL接5K的电阻再接地试试....

出0入8汤圆

 楼主| 发表于 2010-3-19 11:58:17 | 显示全部楼层
回1楼:
我的延时时间是1S。
2楼说的VL是什么?

完整的代码:
#ifndef __DS18B20_H_
#define __DS18B20_H_

#define CONVERT_T                        200
extern unsigned char ConvertTime;
extern void ds18b20_rst(void);
extern void ds18b20_write_comm(unsigned char val);
extern unsigned char ds18b20_read(void);
extern void ds18b20_run(void);
extern void ds18b20_Convert(void);
extern void ds18b20_read_t(void);

#endif

DS18B20.C上面已有我就不帖了

#include <avr/interrupt.h>
#include <avr/io.h>
#include "Port.h"
#include "SEG_MPX4_CA.h"
#include "softRtc.h"
#include "key.h"
#include "ht1381.h"
#include "ds18b20.h"

// 内部函数声明
static void timer0_COMP_Init(void);
#define BUZZER_TIME                6
unsigned char ucBuzzer_time;

// Fosc:7.3728MHz
//TIMER0 initialize - prescale:256
// WGM: COMP
// desired value: 10KHz
void timer0_COMP_Init(void)
{
        TCCR0 = 0;
        TCNT0 = 0;
        OCR0 = 3;                                        // TOP 值
        TCCR0 |= (1 << WGM01);                // timer0 ctc
        TCCR0 |= (1 << COM00);                // 比较匹配发生时OC0 取反
        TCCR0 |= (1 << CS02);                // clkI/O/256 ( 来自预分频器)启动定时器计数
        ucBuzzer_time = BUZZER_TIME;
}

void BUZZER_ON(void)
{
        timer0_COMP_Init();
}

void BUZZER_OFF(void)
{
        TCCR0 = 0;
}


void timer2_CTC_Init(void)
{
        TCNT2 = 0;
        OCR2 = 144;                                        // TOP 值
        TCCR2 |= (1 << WGM21);                // Timier2 CTC
        // clkI/O/256 ( 来自预分频器)启动定时器计数
        TCCR2 |= (1 << CS22)|(1 << CS21);
        TIMSK |= (1 << OCIE2);                // 使能比较匹配中断
}

// 比较匹配中服
ISR(TIMER2_COMP_vect)
{
        ShowLed();
        if (++Keytick >= KEY_TICK)       
        {
                Keytick = 0;
                KeyScan();
        }

        if (--ucBuzzer_time <= 0)
        {
                BUZZER_OFF();
        }
        --ReadTime;
        --ConvertTime;
}


(原文件名:QQ截图未命名.jpg)
仿真是OK,就是在实际中不行。


#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include "SEG_MPX4_CA.h"
#include "Port.h"
#include "PortConf.h"
#include "System.h"
#include "softRtc.h"
#include "key.h"
#include "ht1381.h"
#include "ds18b20.h"

// 数码管是共阳极
// SEG线硬件连接方法定义(某位为 '1' 表示与数码管相对应的引脚相连)



int main(void)
{
        cli();
        PortConf();
        KeyInit();
        timer2_CTC_Init();
        BUZZER_ON();
        DisplayState  =0x00;
        ReadTime = HT1381_READ_EN;
        bUpdateDisplayEn = 0;
        sei();                                //re-enable interrupts
       
        while(1)
        {
                KeyPress();
                if (bUpdateDisplayEn)
                {
                        if (ReadTime == 0)
                        {
                                ReadTime = HT1381_READ_EN;
                                 time.hour = ht1381_receive(0x85);
                                time.minute = ht1381_receive(0x83);
                                Updata_time(time.hour, time.minute);
                        }
                }
                if (ConvertTime == 0)
                {
                        ConvertTime = CONVERT_T;
                        ds18b20_run();
                }
        }
        return 0;
}

出0入8汤圆

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

本版积分规则

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

GMT+8, 2024-5-16 03:25

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

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