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

3 x DS18B20 atmega32 LCD. Co zrobić ze stanami PINów?

CBR-MAR 04 Sie 2007 00:29 1739 5
REKLAMA
  • #1 4144314
    CBR-MAR
    Poziom 10  
    Posty: 37
    Witam
    Podłączylem czujniki pod kolejne piny PORTu A i niestety to nie chodzi:(
    Moglby mi ktos powiedzieć, co powinno sie zrobić ze stanami PIN'ów podczas przełączania z jednego czujnika na drugi ,aby to dzialalo??
    PIN, pod ktory podłączone są czujniki przypisalem zmiennej, którą przy każdym przełaczeniu zmieniam, ustawiam stan wysoki na kolejnym pinie przed odczytaniem z DS, co jeszcze powinno sie zrobic???

    dziekuje za wszelka pomoc:)

    Pozdrawiam.
  • REKLAMA
  • #2 4144472
    Pituś Bajtuś
    Poziom 28  
    Posty: 934
    Pomógł: 137
    Ocena: 10
    CBR-MAR napisał:
    co jeszcze powinno sie zrobic???

    Pokazać kod którym to robisz?
  • REKLAMA
  • #3 4215002
    CBR-MAR
    Poziom 10  
    Posty: 37
    Kod jest narazie na dwa DS'y...

    
    #define F_CPU 8000000
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    #define DDR_DB4  DDRB
    #define PORT_DB4 PORTB
    #define DB4      PB0
    
    #define DDR_DB5  DDRB
    #define PORT_DB5 PORTB
    #define DB5      PB1
    
    #define DDR_DB6  DDRB
    #define PORT_DB6 PORTB
    #define DB6      PB2
    
    #define DDR_DB7  DDRB
    #define PORT_DB7 PORTB
    #define DB7      PB3
    
    
    #define DDR_RS   DDRB
    #define PORT_RS  PORTB
    #define RS       PB5
    
    #define DDR_E    DDRB
    #define PORT_E   PORTB
    #define E        PB4
    
    #define SET_DB4 PORT_DB4 |= _BV(DB4)
    #define CLR_DB4 PORT_DB4 &= ~_BV(DB4)
    
    #define SET_DB5 PORT_DB5 |= _BV(DB5)
    #define CLR_DB5 PORT_DB5 &= ~_BV(DB5)
    
    #define SET_DB6 PORT_DB6 |= _BV(DB6)
    #define CLR_DB6 PORT_DB6 &= ~_BV(DB6)
    
    #define SET_DB7 PORT_DB7 |= _BV(DB7)
    #define CLR_DB7 PORT_DB7 &= ~_BV(DB7)
    
    #define SET_E PORT_E |= _BV(E)
    #define CLR_E PORT_E &= ~_BV(E)
    
    #define SET_RS PORT_RS |= _BV(RS)
    #define CLR_RS PORT_RS &= ~_BV(RS)
    
    unsigned pin;
    //ds18b20
    #define OWPORT PORTA
    #define OWPIN pin
    #define OWPININ PINA
    #define OWDDR DDRA
    #define OWIN 1 // 2^OWPIN
    
    #define delay_us(x) _delay_loop_2(x*2)
    //#define ow_lo() *ddr&=bm
    //#define ow_hi() *ddr|=bp
    #define ow_lo() OWDDR |= _BV(OWPIN)
    #define ow_hi() OWDDR &= ~_BV(OWPIN)
    
    int a,b;
    /*void setow(char bitnum)
    	{
    //	port=addr;
    //	ddr=addr-1;
    	pin=addr-2;
    //	bp=(1<<bitnum);
    //	bm=~(1<<bitnum);
    	ow_hi();
    	}
    */
    // funkcja wystawiająca na szynę danych połówkę bajtu
    // pod uwagę brana jest młodsza połówka parametru
    void out_nibble(char x)
    {
    if(x & _BV(0)) SET_DB4; else  CLR_DB4;
    if(x & _BV(1)) SET_DB5; else  CLR_DB5;
    if(x & _BV(2)) SET_DB6; else  CLR_DB6;
    if(x & _BV(3)) SET_DB7; else  CLR_DB7;
    }
    
    // funkcja zapisująca do LCD bajt danych
    void write_to_lcd(char x)
    {
       SET_E;
       out_nibble(x >> 4); // wystawienie na szynę danych starszej połówki bajtu
       CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
       SET_E;
       out_nibble(x); // wystawienie na szynę danych młodszej połówki bajtu
       CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
       _delay_ms(1); // opóźnienie ok 1 ms
    }
    
    // funkcja zapisująca do LCD rozkaz
    void write_command(char x)
    {
       CLR_RS; // niski stan na RS -> zapis instrukcji
       write_to_lcd(x); // zapis do LCD
    }
    
    // funkcja zapisujaca do LCD znak
    void write_char(char x)
    {
       SET_RS; // wysoki stan na RS -> zapis danej
       write_to_lcd(x); // zapis do LCD
    }
    
    // funkcja zapisu tekstu do wyświetlacza LCD
    void write_text(char * s)
    {
       while(*s) // do napotkania 0
         {
         write_char(*s); // zapisz znak wskazywany przez s na LCD
         s++; // zwiększ s (przygotuj nastepny znak)
         }
    }
    
    // funkcja inicjująca LCD
    void lcd_init(void)
    {
       // ustawienie wszystkich linii sterujących LCD jako wyjścia
       DDR_DB4 |= _BV(DB4);
       DDR_DB5 |= _BV(DB5);
       DDR_DB6 |= _BV(DB6);
       DDR_DB7 |= _BV(DB7);
       DDR_E |= _BV(E);
       DDR_RS |= _BV(RS);
    
      //
       _delay_ms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
       CLR_E; // E = 0
       CLR_RS; // RS = 0
       char i; // zmianna licznikowa
       for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
       {
          SET_E; // E = 1
          out_nibble(0x03);
          CLR_E; // E = 0
          _delay_ms(5); // czekaj 5ms
       }
       SET_E; // E = 1
       out_nibble(0x02);
       CLR_E; // E = 0
    
       _delay_ms(1); // czekaj 1ms
       //write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
       write_command(0x28);
       write_command(0x08); // wyłącz LCD, kursor i miganie
       write_command(0x01); // czyść LCD
       write_command(0x06); // bez przesuwania w prawo
       write_command(0x0C); // włącz LCD, bez kursora i mrugania
    }
    
    
    void czekaj(unsigned long pt) //procedura wytracania czasu
    {
     unsigned char tp1;
    
     for(;pt>0;pt--)
     {
      for(tp1=255;tp1!=0;tp1--);
     }
    }
    
    void lcd_goto(unsigned char column, unsigned char line)
    {
      unsigned char addr;
      line--;
      column--;
      addr = (line * 64) + column;
      write_command(addr | 0x80);
    }
    
    //ds18b20
    uint8_t ow_reset(void)
    {
       uint8_t a;
       ow_lo();
       delay_us(480);
       ow_hi();
       delay_us(70);
       a = OWPININ & OWIN; // 0 - obecny, else - nieobecny
       delay_us(410);
       return a;
    }
    
    void ow_wrbit(uint8_t bit)
    {
       ow_lo();
       if(bit == 0)
       {
          delay_us(60);
          ow_hi();
          delay_us(10);
       }
       else
       {
          delay_us(6);
          ow_hi();
          delay_us(64);
       }
    }
    
    uint8_t ow_rdbit(void)
    {
       uint8_t a;
       ow_lo();
       delay_us(6);
       ow_hi();
       delay_us(9);
       a = OWPININ & OWIN; //0 - 0, else -1
       delay_us(55);
       return a;
    }
    
    uint8_t ow_rdbyte(void)
    {
       uint8_t a, b;
       a = 0;
       for(b = 0; b <8; b++)
       {
          a >>= 1;
          if (ow_rdbit()) a += 128;
       }
       return a;
    }
    
    void ow_wrbyte(uint8_t data)
    {
       uint8_t a;
       for(a = 0; a < 8; a++)
       {
          ow_wrbit(data & 1);
          data >>= 1;
       }
    }
    
    void lcd_putuint8(uint8_t a)
    {
       uint8_t b;
       char c;
       b = a / 100;
       c= b + 0x30;
       if (b) write_char(c);
       a -= b * 100;
       b = a / 10;
       c= b + 0x30;
       write_char(c);
       a -= b * 10;
       c= a + 0x30;
       write_char(c);
    }
    
    
    
    int main(void)
    {
    int g;
    		 
    DDRC=0xff;
    PORTC=0xff;
    
    uint8_t a =0, b =0;
    lcd_init();
       
    for(;;)
      { 
       pin=0;
    
       PORTA &= ~_BV(0);
       DDRA &= ~_BV(0);
       
          if( ow_reset() != 0 )
          {
             lcd_goto(1,1);
             write_text("brak dallasa");
             return 1;
          }
         
             ow_wrbyte(0xCC); //SKIP ROM
             ow_wrbyte(0x44); //CONVERT T
    
             for(a = 1; a <100; a++)
             {
                delay_us(100000);
             }
    
             if( ow_reset() != 0 )
             {
                lcd_goto(1,1);
                write_text("brak dallasa");
               return 1;
             }
    		 		
             ow_wrbyte(0xCC); //SKIP ROM
             ow_wrbyte(0xBE); //READ SCRATCHPAD
             a = ow_rdbyte();
             b = ow_rdbyte();
             a >>= 4;
             b <<= 4;
             a = a | b;
             write_command(0x01); // czyść LCD
             lcd_goto(1,1);
             write_text("temperatura");
    		 lcd_goto(1,2);
    		 write_text("PD0:");
    		 
    		 
             lcd_goto(6,2);
             lcd_putuint8(a);
    		 lcd_goto(9,2);
             write_char(0x43);
     //        lcd_putuint16(e);
     
     	     czekaj(1000);
    
     
            DDRA |= _BV(0); //ow_low
    //		PORTA |= _BV(0);	 
    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    	
    		czekaj(400);
    
       ++pin;
    
       PORTA &= ~_BV(1);
    	DDRA &= ~_BV(1);
       
          if( ow_reset() != 0 )
          {
             lcd_goto(1,1);
             write_text("brak dallasa");
             return 1;
          }
          
             ow_wrbyte(0xCC); //SKIP ROM
             ow_wrbyte(0x44); //CONVERT T
    
             for(a = 1; a <100; a++)
             {
                delay_us(100000);
             }
    
             if( ow_reset() != 0 )
             {
                lcd_goto(1,1);
                write_text("brak dallasa");
               return 1;
             }
    		 	
             ow_wrbyte(0xCC); //SKIP ROM
             ow_wrbyte(0xBE); //READ SCRATCHPAD
             a = ow_rdbyte();
             b = ow_rdbyte();
             a >>= 4;
             b <<= 4;
             a = a | b;
             write_command(0x01); // czyść LCD
             lcd_goto(1,1);
             write_text("temperatura");
    		 lcd_goto(1,2);
    		 write_text("PD1:");
    		 	 
             lcd_goto(6,2);
             lcd_putuint8(a);
    		 lcd_goto(9,2);
             write_char(0x43);
     
     		czekaj(1000);
    	
    	    DDRA |= _BV(0);
    	 
      }		 
       return 1;
    }
    
    // ow_lo() DDRA |= _BV(0);
    // ow_hi() DDRA &= ~_BV(0);


    NIestety mi to nie chodzi:((((
    moze ktos ma jakis podobny programik który obsluguje dwa DS'Y ...
    Pilne !!!

    Dziekuje z gory i pozdrawiam...

    Mariusz
  • REKLAMA
  • #4 4215148
    Mad Bekon
    Poziom 23  
    Posty: 794
    Pomógł: 31
    Ocena: 36
    Ja Ci radzę, zrób najpierw działający, dla jednego DSa a potem po prostu zmień PIN.

    Swoją drogą, ja nie rozumiem dlaczego ludzie nie korzystają z zalety ONE WIRE jaką jest możliwość wpięcia kilku czujników równolegle?
    Różni się to tylko tym, że trzeba znać numery seryjne czujników i zamiast Skip Rom zrobić Match Rom... tyle

    https://www.elektroda.pl/rtvforum/topic818790.html#4207117
  • REKLAMA
  • #6 4216277
    Mad Bekon
    Poziom 23  
    Posty: 794
    Pomógł: 31
    Ocena: 36
    Ja od siebie dorzucę, że moim zdaniem to powinno być nie:
    
    a = OWPININ & _BV(OWIN); // 0 - obecny, else - nieobecny
    

    a
    
    a = OWPININ & _BV(OWPIN); // 0 - obecny, else - nieobecny
    

    Kolejna sprawa jest taka, że definiowanie OWIN, jest bez sensu, no chyba, że chciałeś sprawdzić czy będzie działać tylko dla jednego pinu.

    Po drugie definiowanie makra dla OWPIN też jest takie nijakie. Wystarczyło tą zmienną pin nazwać OWPIN


    Kolejna sprawa to, czy jesteś pewien że twoja funkcja delay_us() odmierza dobrze czas tych mikro sekund?
    Nawiasem mówiąc w pliku delay.h (przynajmniej tym co ja dostałem z WinAVR) jest funkcja _delay_us(). Trzeba tylko pamietać, że jej maksymalny argument to 768 / FCPU * 1000000 czyli w twoim przypadku 768 / 8 uS. Odliczanie czasu jest kluczową sprawą w 1wire

    Aha. I tak jeszcze zupełnie nawiasem mówiąc. Wrzuć sobie te procedury od LCD do innego pliku, program zrobi się dużo czytelnijszy, a z tego powtarzającego się kodu obsługi DS'a zrób funkcję w zależności od PINu
REKLAMA