logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega88][C] DS18B20 pomiar temperatury i zapis do EEPROM

Kegeer 03 Lut 2011 14:51 2712 4
REKLAMA
  • #1 9097084
    Kegeer
    Poziom 10  
    Witam,

    Mógłby ktoś sprawdzić, gdzie jest błąd?
    W pamięci EEPROM program zapisuje same zera.

    Czujnik podpięty do portu PD5. 5V - 5V, GND - GND, wyjście - PD5, między 5V a wyjściem sygnałowym rezystor 3,2kOhm.

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/eeprom.h>
    #include <string.h>
    #include <avr/signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <avr/pgmspace.h>
    #include <inttypes.h>
    #include <util/delay.h>
    #define f_CPU 8000000UL
    
    ////////////////////eeprom////////////////////////////////
    //inicjalizacja 
    int p_i=0, pomiar_t=0;
    uint8_t eeprom_val[512] __attribute__((section(".eeprom")));
    //funkcja zapisu do pamieci eeprom
    void zapisz(uint8_t pozycja, uint8_t wartosc ) {
       uint8_t uiStatusSREG = SREG;
       cli();
       eeprom_busy_wait();
       eeprom_write_byte(&eeprom_val[pozycja],wartosc);
       SREG|=uiStatusSREG&0x80;
    }
    //funkcja odczytu z pamieci eeprom
    char odczyt(uint8_t pozycja) {
    eeprom_busy_wait();
    return eeprom_read_byte(&eeprom_val[pozycja]);
    } 
    
    ////////////////////termometr////////////////////////////////
    #define WE 5 //czujnik podłączony do portu D pin 5
    #define PORT_1WIRE PIND   
    #define CLEAR_1WIRE DDRD |= _BV(WE)
    #define SET_1WIRE DDRD &=  ~_BV(WE)
    char buf[8];
    
    ////////////////////////////////////termometr//////////////////////////
    void owire_delay(unsigned int __count)
    {
       __asm__ volatile (
          "1: sbiw %0,1" "\n\t"
          "brne 1b"
          : "=w" (__count)
          : "0" (__count)
       );
    }
    
    
    
    
    // reset magistrali
    unsigned char RESET_PULSE(void)
    {
    unsigned char PRESENCE;
    CLEAR_1WIRE;
       owire_delay(1920);    
    SET_1WIRE;
    
     owire_delay(120);    
    if (bit_is_clear(PORT_1WIRE, WE)) {PRESENCE=1;} else {PRESENCE=0;}
    
    owire_delay(1920);
    if (bit_is_set(PORT_1WIRE, WE)) {PRESENCE=1;} else {PRESENCE=0;}
    
    
    return PRESENCE;
    }
    
    void send(char bit)
    {
    //cli();
    CLEAR_1WIRE;
    
    owire_delay(20);    
    if(bit==1)
    SET_1WIRE;
    
    owire_delay(320);
    SET_1WIRE;
    //sei();
    }
    
    unsigned char read(void)
    {
    unsigned char PRESENCE=0;
    //cli();
    CLEAR_1WIRE;
     owire_delay(8);
    SET_1WIRE;
    owire_delay(60);
    if (bit_is_set(PORT_1WIRE, WE)) PRESENCE=1; else PRESENCE=0;
    return (PRESENCE);
    //sei();
    }
    
    unsigned  send_byte(char wartosc)
    {
    unsigned char i;
    unsigned char pom;
    for (i=0; i<8; i++)
    {
    pom = wartosc>>i;
    pom &= 0x01;
    send(pom);
    }
    
     owire_delay(400);
    }
    
    
    
    
    unsigned char read_byte(void)
    {
    unsigned char i;
    unsigned char wartosc = 0;
    for (i=0; i<8; i++)
    {
    if(read()) wartosc|=0x01<<i;
    
    owire_delay(60);    
    }
    return (wartosc);
    }
    char *tp="                  ";
    
    
    int main (void)
    {
    ////////////////////inicjalizacja_diody_i_przekaznika////////////////
    DDRB = _BV(4)|_BV(5);
    
    unsigned char sprawdz;
    char temp1=0, temp2=0;
    
    for(;;) {
    sprawdz=RESET_PULSE();
    if (sprawdz == 1)
    {
    
    send_byte(0xCC);
    send_byte(0x44);
    owire_delay(3000);
    
    sprawdz = RESET_PULSE();
    send_byte(0xCC);
    send_byte(0xBE);
    temp1=read_byte();
    temp2=read_byte();
    
    sprawdz=RESET_PULSE();
    float temp=0;
    temp=(float)(temp1+(temp2*256))/16;
    dtostrf(temp,1,1,buf);
    
    pomiar_t = atoi (buf);
    //int pomiar_t = (int) buf;
    if (pomiar_t>28) PORTB = 0b11101111;
    zapisz( p_i, pomiar_t );
    p_i++;
    if (p_i>100) p_i=0;
    }
    } 
    
  • REKLAMA
  • #2 9097300
    hotdog
    Poziom 26  
    Nie rozumiem co ty chcesz zapiać w eepromie. Konwertujesz temperaturę do float, później do stringa, ze stringa do liczby całkowitej.

    Jesteś pewien że w zmiennej pomiar_t po twoich kosmicznych operacjach jest liczba różna od 0?
  • REKLAMA
  • #3 9097706
    Kegeer
    Poziom 10  
    To jest przerobiony kod, wczesniej wysylalem to na LCD, stad te przejscia.
    Moze ktos zaproponowac wasciwe rozwiazanie?
  • REKLAMA
  • #4 9097806
    nsvinc
    Poziom 35  
    obsługa czujnika, formaty temperatury jak i zapis do pamięci nieulotnych był już tu setki razy przerabiany. Float do przechowywania temperatury z DS18B20 to przerost formy nad treścią. To się wszystko robi na zwykłych intach, niezależnie czy wyrzucasz to na wyświetlacz, czy nie....

    Uzyj szukaj!
  • #5 9140801
    Kegeer
    Poziom 10  
    Odświeżam trochę... Po tym jak mnie tu pojechano, postanowiłem pominąć eeprom i wysłać temperaturę na LCD.

    Po części się to udało ale układ wskazuje ciągle -0.1 st.C.
    Czujnik na pewno jest sprawny, bo wymieniałem i dalej to samo.
    Połączenie i odwołanie do portu też jest ok, bo jak odłączam czujnik, to wyświetla mi info o błędnym odczycie.

    Między nóżkę sygnałową i +5V wstawiłem rezystor 4,7k.

    Mógłby ktoś rzucić okiem na kod?

    #define F_CPU 4000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "hd44780.h"
    
    #define PIN_1WIRE 0
    #define PORT_1WIRE PINB
    
    #define OUT_1WIRE_LOW PORT_1WIRE&=~(1<<PIN_1WIRE);
    #define OUT_1WIRE_HIGH PORT_1WIRE|=1<<PIN_1WIRE;
    #define DIR_1WIRE_IN DDRB&=~(1<<PIN_1WIRE);
    #define DIR_1WIRE_OUT DDRB|=1<<PIN_1WIRE;
    
    void delayus(unsigned int __count)
    {
       __asm__ volatile (
          "1: sbiw %0,1" "\n\t"
          "brne 1b"
          : "=w" (__count)
          : "0" (__count)
       );
    }
    
    unsigned char uc_1Wire_ResetPulse(void)
    {
       unsigned char ucPresenceImpulse;
       OUT_1WIRE_LOW;
       DIR_1WIRE_OUT;
       delayus(500);
       DIR_1WIRE_IN;
       delayus(30);
       if(bit_is_clear(PORT_1WIRE,PIN_1WIRE))
          ucPresenceImpulse = 1;
       else
          ucPresenceImpulse = 0;
       
       delayus(470);
       
       if(bit_is_set(PORT_1WIRE,PIN_1WIRE))
          ucPresenceImpulse = 1;
       else
          ucPresenceImpulse = 0;
          
       return ucPresenceImpulse;
    }
    
    void v1Wire_SendBit(char cBit)
    {
       DIR_1WIRE_OUT;
       delayus(5);
       
       if(cBit == 1)
          DIR_1WIRE_IN;
       
       delayus(80);
       DIR_1WIRE_IN;
    }
    
    unsigned char uc1Wire_ReadBit(void)
    {
       unsigned char ucBit;
       
       DIR_1WIRE_OUT;
       delayus(2);
       DIR_1WIRE_IN;
       delayus(15);
       
       if(bit_is_set(PORT_1WIRE,PIN_1WIRE))
          ucBit = 1;
       else
          ucBit = 0;
       
       return ucBit;
    }
    
    void v1Wire_SendByte(char ucByteValue)
    {
       unsigned char ucCounter;
       unsigned char ucValueToSend;
       
       for(ucCounter =0;ucCounter <8;ucCounter++)
       {
          ucValueToSend = ucByteValue>>ucCounter;
          ucValueToSend &= 0x01;
          v1Wire_SendBit(ucValueToSend);
       }
       delayus(100);
    }
    
    unsigned char uv1Wire_ReadByte(void)
    {
       unsigned char ucCounter;
       unsigned char ucReadByte = 0;
       for(ucCounter=0;ucCounter<8;ucCounter++)
       {
          if(uc1Wire_ReadBit())
             ucReadByte |= 0x01<<ucCounter;
          delayus(15);
       }
       return ucReadByte;
    }
    
    int main(void)
    {
    
    DDRD=0xFF;
    unsigned char ucReset;
    char cTempH =0, cTempL =0;
    
    float fTemp = 0;
    /* Funkcja inicjalizuje wyťwietlacz*/
    lcd_init();
    /* W-¦cza wyťwietlanie */
    LCD_DISPLAY(LCDDISPLAY);
    LCD_LOCATE(0,0);
    lcd_puts("Rozpoczecie");
    LCD_LOCATE(0,1);
    lcd_puts("programu");
    char w_temp[16] ="{0}";
    _delay_ms(1000);
    
    while(1)
    {
       LCD_CLEAR;
       LCD_LOCATE(0,0);
       lcd_puts("Zaczynam odzyt");
       LCD_LOCATE(0,1);
       lcd_puts("temperatury");
       _delay_ms(500);
       
       ucReset = uc_1Wire_ResetPulse();
       if(ucReset == 1)
       {
          v1Wire_SendByte(0xCC);
          v1Wire_SendByte(0x44);
          _delay_ms(750);
          ucReset = uc_1Wire_ResetPulse();
          v1Wire_SendByte(0xCC);
          v1Wire_SendByte(0xBE);
          cTempL = uv1Wire_ReadByte();
          cTempH = uv1Wire_ReadByte();
          ucReset = uc_1Wire_ResetPulse();
          
          fTemp = (float)(cTempL+(cTempH<<8))/16;
          dtostrf(fTemp,1,1,w_temp);
          LCD_CLEAR;
          lcd_puts(w_temp);
          _delay_ms(2000);
       }
       else
       {
          LCD_CLEAR;
          lcd_puts("Brak odczytu");
       }
       
       _delay_ms(1000);
    }
    }
    
REKLAMA