ds18b20 proteus'ta simule edebilmem için yardım

Başlatan ahmetzafer, 09 Ağustos 2014, 14:17:38

ahmetzafer

Merhaba arkadaşlar,

DS18b20 sensörünü proteusta simule etmeye çalışıyorum ama bir türlü 1-wire protokolünü kullanamadım veya yazamadım.
1-wire reset lemesini sağlayan reset(); fonksiyonunun çıktısı resimde de görüldüğü gibi hiçbir zaman 0 olmuyor. bu yüzden 1-wire çalışmıyor ya da ben yanlış yorumluyorum. bu yüzden ekranımada hiçbir görüntü gelmiyor. if(!reset) komutunu kaldırırsamda saçma değerler alıyorum.

main.c

// PIC18F452 Configuration Bit Settings

#include <xc.h>
#define _XTAL_FREQ 4000000

#include <xlcd.h>
#include <delays.h>
#include <stdio.h>
#include <string.h>
#include "picConfigure.h"
#include "lcd.h"
#include "ds18b20.h"

void main(void) {
    ADCON0 = 0b00000000;
    ADCON1 = 0b10000110;

    TRISA = 0;
    PORTA = 0;
    TRISB = 0;
    PORTB = 0;
    TRISC = 0;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0;
    TRISE = 0;
    PORTE = 0;

    unsigned char string[20] = "";
    unsigned int tempL, tempH;
    unsigned int i_int = 0; // declare a variable to store
    float i_float = 0;

    Serial_LCD_Init();
    Serial_LCD_Cmd(_LCD_CLEAR);
    Serial_LCD_Cmd(_LCD_CURSOR_OFF);

    while (1) {
        if (!reset()) {
            write(Skip_ROM);
            write(Convert_T);
            delay_ms(750);

            reset();
            write(Skip_ROM);
            write(Read_scratchpad);

            tempL = read(); //read low temp value
            tempH = read(); //read high temp value
            i_int = (tempH << 8) + tempL; //put both value in one variable
            i_float = (float) i_int * 6.25; //calcuation from the table provided

            sprintf(string, "%f", i_float);
            Serial_LCD_Out(1, 1, string);
        }
    }
    return;
}


ds18b20.h

#ifndef DS18B20_H
#define	DS18B20_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <xc.h>
#define _XTAL_FREQ 4000000

#define Skip_ROM 	0xCC
#define Convert_T 	0x44
#define Read_scratchpad 0xBE

#define Port_18B20 	PORTBbits.RB0
#define Tx_18B20 	TRISBbits.RB0 = 0
#define Rx_18B20 	TRISBbits.RB0 = 1

    void delay_ms(unsigned int ui_value) {
        while (ui_value-- > 0) {
            __delay_ms(1); // macro from HI-TECH compiler which will generate 1ms delay base on value of _XTAL_FREQ in system.h
        }
    }

    unsigned char reset() {
        Tx_18B20; // Tris = 0 (output)
        Port_18B20 = 0; // set pin# to low (0)
        __delay_us(480); // 1 wire require time delay
        Rx_18B20; // Tris = 1 (input)
        __delay_us(60); // 1 wire require time delay

        if (Port_18B20 == 0) // if there is a presence pluse
        {
            __delay_us(480);
            return 0; // return 0 ( 1-wire is presence)
        }
        else {
            __delay_us(480);
            return 1; // return 1 ( 1-wire is NOT presence)
        }
    }

    void write(char WRT) {
        char i, Cmd;
        Cmd = WRT;
        Rx_18B20; // set pin# to input (1)

        for (i = 0; i < 8; i++) {
            if ((Cmd & (1 << i)) != 0) {
                // write 1
                Tx_18B20; // set pin# to output (0)
                Port_18B20 = 0; // set pin# to low (0)
                __delay_us(1); // 1 wire require time delay
                Rx_18B20; // set pin# to input (release the bus)
                __delay_us(60); // 1 wire require time delay
            }
            else {
                //write 0
                Tx_18B20; // set pin# to output (0)
                Port_18B20 = 0; // set pin# to low (0)
                __delay_us(60); // 1 wire require time delay
                Rx_18B20; // set pin# to input (release the bus)
            }
        }
    }

    unsigned char read() {
        char i, result = 0;
        Rx_18B20; // TRIS is input(1)
        for (i = 0; i < 8; i++) {
            Tx_18B20; // TRIS is output(0)
            Port_18B20 = 0; // genarate low pluse for 2us
            __delay_us(2);
            Rx_18B20; // TRIS is input(1) release the bus
            if (Port_18B20 != 0)
                result |= 1 << i;
            __delay_us(60); // wait for recovery time
        }
        return result;
    }

#ifdef	__cplusplus
}
#endif

#endif	/* DS18B20_H */


picConfigure.h

#ifndef PICCONFIGURE_H
#define	PICCONFIGURE_H

#ifdef	__cplusplus
extern "C" {
#endif

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1H
#pragma config OSC = XT       // Oscillator Selection bits (RC oscillator w/ OSC2 configured as RA6)
#pragma config OSCS = OFF       // Oscillator System Clock Switch Enable bit (Oscillator system clock switch option is disabled (main oscillator is source))

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON         // Brown-out Reset Enable bit (Brown-out Reset enabled)
#pragma config BORV = 20        // Brown-out Reset Voltage bits (VBOR set to 2.0V)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 128      // Watchdog Timer Postscale Select bits (1:128)

// CONFIG3H
#pragma config CCP2MUX = OFF    // CCP2 Mux bit (CCP2 input/output is multiplexed with RB3)

// CONFIG4L
#pragma config STVR = OFF       // Stack Full/Underflow Reset Enable bit (Stack Full/Underflow will not cause RESET)
#pragma config LVP = ON         // Low Voltage ICSP Enable bit (Low Voltage ICSP enabled)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000200-001FFFh) not code protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000200-001FFFh) not write protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000200-001FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from Table Reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from Table Reads executed in other blocks)

#ifdef	__cplusplus
}
#endif

#endif	/* PICCONFIGURE_H */


proteus çizimi


ahmetzafer

#1
Tekrar merhaba arkadaşlar, bu problemi hala çözmeye çalışıyorum. Farklı codelar deniyorum.
Aşağıdaki ds18b20 için yazılmış kodu proteusta 16f628a ve 16f877a piclerinde çalıştırabiliyorum. kopyala yapıştır yapıyorum ve sadece 2. satırdaki pic kütüphanelerini değiştiriyorum. ancak 18f452 de çalıştıramıyorum. Bunun sebebi ne olabilir acaba ?
Başka bir ihtimalide değerlendirmiştim,
kullandığım pinden okuma yazma yaparken PORTD_bit.RD1 ile okuyup LATD_bit.LD1 ile yazma işlemi yaptım gene olmadı.
Teşekkürler.

#include <htc.h>
#include "pic18f452.h"

#define _XTAL_FREQ				4000000

//ONE-WIRE
#define ONE_WIRE_DATA_PIN			PORTDbits.RD1
#define ONE_WIRE_DATA_PIN_DIRECTION_REGISTER	TRISD
#define ONE_WIRE_DATA_PIN_MASK			0x02

bit bitReadOneBit(void)
{
unsigned char i;
	ONE_WIRE_DATA_PIN=0;
	ONE_WIRE_DATA_PIN_DIRECTION_REGISTER&=~ONE_WIRE_DATA_PIN_MASK;
	ONE_WIRE_DATA_PIN=0;
	__delay_us(1);
	ONE_WIRE_DATA_PIN_DIRECTION_REGISTER|=ONE_WIRE_DATA_PIN_MASK;
	__delay_us(1);
	return(ONE_WIRE_DATA_PIN);
}

void vWriteOneBit(unsigned char bValue)
{
	ONE_WIRE_DATA_PIN=0;
	ONE_WIRE_DATA_PIN_DIRECTION_REGISTER&=~ONE_WIRE_DATA_PIN_MASK;
	ONE_WIRE_DATA_PIN=0;
	__delay_us(1);
	if(bValue)
	{
		ONE_WIRE_DATA_PIN_DIRECTION_REGISTER|=ONE_WIRE_DATA_PIN_MASK;
		__delay_us(60);
		return;
	}
		else
		{
			__delay_us(60);
			ONE_WIRE_DATA_PIN_DIRECTION_REGISTER|=ONE_WIRE_DATA_PIN_MASK;
		}
}

unsigned char bReadByte(void)
{
unsigned char i;
unsigned char bReturned=0;
	for (i=0;i<8;i++)
	{
		if(bitReadOneBit()) bReturned|=0x01<<i;
		__delay_us(120);
	}
	return(bReturned);
}

void vWriteByte(char bData)
{
unsigned char i;
	for (i=0; i<8; i++)
	{
		vWriteOneBit(bData&0x01);
		bData = bData>>1;
	}
	__delay_us(104);
}

bit bitReset(void)
{
unsigned char bReturned=0;
	ONE_WIRE_DATA_PIN=0;
	ONE_WIRE_DATA_PIN_DIRECTION_REGISTER&=~ONE_WIRE_DATA_PIN_MASK;
	ONE_WIRE_DATA_PIN=0;
	__delay_us(480);
	ONE_WIRE_DATA_PIN_DIRECTION_REGISTER|=ONE_WIRE_DATA_PIN_MASK;
	__delay_us(72);
	if(ONE_WIRE_DATA_PIN) bReturned=1;
	__delay_us(424);
	if(bReturned) return 1;
		else return 0;
}

void vConfigure(void)
{
	bitReset();
	vWriteByte(0x4E);
	vWriteByte(0x00);
	vWriteByte(0x00);
	vWriteByte(0x00);
}

void vInitializeTemperatureSensor(void)
{
	vConfigure();
}

unsigned char bGetTemperature(void)
{
unsigned char bTemperatureLSB, bTemperatureMSB, i;
	bitReset();
	vWriteByte(0xCC);
	vWriteByte(0x44);
	__delay_ms(100);
	bitReset();
	vWriteByte(0xCC);
	vWriteByte(0xBE);
	bTemperatureLSB=bReadByte();
	bTemperatureMSB=bReadByte();
	for (i=0;i<7;i++) bReadByte();


	{
	float fRealTemperature;
	unsigned short wTemperature=bTemperatureMSB;
		wTemperature<<=8;
		wTemperature|=bTemperatureLSB;

		fRealTemperature=(float)wTemperature;
		fRealTemperature/=16;

		//floating part
		//fRealTemperature*=10;
		//return (((unsigned char)fRealTemperature)%10);

		//decimal part
		return (((unsigned char)fRealTemperature));
	}

}

void main(void)
{
	TRISB=0;
	PORTB=0x00;

	vInitializeTemperatureSensor();

	while(1)
	{
		PORTB=bGetTemperature();
	}
}





ahmetzafer

Sorunu sebebini buldum arkadaşlar.
Mplab'ın __delay_ms(), __delay_us(), fonksiyonları stabil çalışmıyormuş. Bunlar yerine Delay1TCYx(), Delay10TCYx() gibi delay.h kütüphanesindeki fonksiyonları kullandım. Sorunsuz çalışıyor.

Gökhan BEKEN

Delay1TCYx(), Delay10TCYx() türünden olan fonksiyonlar cycle(saykıl) cinsinden bekleme yapar, assembly'deki nop'lar gibi, kaç kere nop komutunun işletileceğini belirtirsiniz, ona göre o bekler.

__delay_ms() fonksiyonu ise, ayarladığınız osilatöre göre, kaç milisaniye bekleyeceğini (gerçek zaman) belirtirsiniz, fonksiyonun düzgün çalılabilmesi için, osilatör değerini belirtmeniz gerekir. Sizin kodda: #define _XTAL_FREQ 4000000
yazıyor. Bu fonksiyon yanlış çalışıyorsa, osilatör ayarlarınıza, kullandığınız kristal değerine bir göz atın yanlışlık var mı diye. Sorun isis'ten de kaynaklanabilir. Belkide bekleme süreleri yetersizdir, artırırsanız düzelebilir.

Özel mesaj okumuyorum, lütfen göndermeyin.