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

[ATMEGA8][C] Termostat - prośba o sprawdzenie kodu

Shuriken 09 Gru 2010 22:51 3801 4
  • #1 8848561
    Shuriken
    Poziom 10  
    Jest to modyfikacja kodu termometru z kursu avr-gcc.

    Mój wkład to funkcje 'przyciski' i 'termostat', a więc błąd dotyczy tylko ich(ewentualnie usytuowania ich w programie).

    Problem polega na tym, zwarciu PC4 do masy dostaje krzaki na lcd.

    Oto kod:
    
    #include <stdio.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include "hd44780.h"
    #include "ds18b20.h"
    
    /* W tablicy będą formowane komunikaty tekstowe
       wysyłane do wyświetlacza */
    char str[17]=" Read       Set ";
    
    unsigned int n=20; // stan ustawienia termostatu, zaczyna od 20st
    
    int main(void)
    
    
    {
    
    DDRC=0xf; // 0000 1111, wejscia pc4-pc7, wyjscia pc0-pc3
    PORTC=0x30; // 0011 0000, pullup na pc4 i pc5
    
      /* Zmienna przechowuje aktualną wartość temperatury */        
      double temp;
      /* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
      unsigned char ds18b20_pad[9];
      
      /* Funkcja inicjalizuje wyświetlacz */
      lcd_init();
      /* Włącza wyświetlanie */
      LCD_DISPLAY(LCDDISPLAY);  
      /* Czyści  ekran */
      LCD_CLEAR;            
      
      /* Wyświetla tytuł */  
      LCD_LOCATE(0,0);
      lcd_puts(str);
    
      while(1)
      {
         void przyciski() 
    
       {
    	if(!(PINC & 0x10))  //jesli wcisniety na pc4
    	  {
    	   _delay_ms(80); //wygasniecie drgan
    	   
    	     while (!(PINC & 0x10)); // czeka na zwolnienie przycisku
    	  
    	   _delay_ms(80); //wygasniecie drgan
    	   
    	   n++; //zwieksz n o 1
    	  }
    	  
    	else if(!(PINC & 0x20))  //jesli wcisniety na pc5
    	  {
    	   _delay_ms(80); // jw
    	   
    	     while (!(PINC & 0x20)); // czeka na zwolnienie przycisku
    	     
    	   _delay_ms(80); // jw
    	   
    	   n--; //zmniejsz n o 1
    	  }
       }
       
        void termostat()
       {
    	unsigned char a=10; //n-a prog wlaczonych 3 grzalek
    	unsigned char b=5; //n-b prog wlaczanych 2 grzalek
    	
    	if(temp<=n-a) //'ponizej40'jesli  temp 20 i wiecej st nizsza od zadanaje to wlacz 3 grzalki
    	  {
    	   PORTC |=0x7; //'zeby nie zmienic pinow z wejsciami pc4-pc7
    	  }
    	else if(((n-a) < temp) && (temp <= (n-b)) ) //'40-45' jezeli temp z przedzialu n-a do n-b to wylacz grzalke nr2
    	  {
    	   PORTC ^=0x2;
    	  }
    	else if(((n-b) < temp) && (temp <= n) ) //'45-50' jw to wylacz 1 i 3 oraz wlacz 2
    	  {
    	   PORTC ^=0x7;
    	  }
    	else if(temp>n) //jezeli temp wieksza od zadanej to wylacz grzalke
    	  {
    	   PORTC ^=0x2;
    	  }
       }
      
      
        /* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20 
           polecenie pomiaru */      
         if(ds18b20_ConvertT())
        {
    
           /* 750ms - czas konwersji */
           _delay_ms(750);
    
          /* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad. 
             Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej 
         znaczący bajt wartość zmierzonej temperatury */            
           ds18b20_Read(ds18b20_pad);
              
          /* Składa dwa bajty wyniku pomiaru w całość. Cztery pierwsze bity mniej
             znaczącego bajtu to część ułamkowa wartości temperatury, więc całość
             dzielona jest przez 16 */       
           temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
           
    	   sprintf(str,"%4.1f\x27""C      %u\x27""C", temp, n);
    	   /* Formułuje komunikat w tablicy 'str' */
           LCD_LOCATE(0,1);
          /* Wysyła komunikat do wyświetlacza */
           lcd_puts(str);
        }
      }
    }
    


    Kompilator wywala 2 warningi:

    
    main.c:43: warning: function declaration isn't a prototype
    main.c:68: warning: function declaration isn't a prototype
    
  • #2 8848958
    Mexit
    Poziom 25  
    Jaki kwarc? Możliwe że jest problem z opóźnieniem.

    Po za tym brak deklaracji funkcji na samym początku programu.
    Gdzie jest wywoływana funkcja "termostat"?
  • #3 8848972
    maniex
    Poziom 10  
    funkcje musisz zadeklarować przed funkcją main, a w niej możesz je tylko wywołać.
  • #4 8852703
    Shuriken
    Poziom 10  
    Prawidłowe deklaracje i wywołania załatwiły sprawę.
    Krzaki na lcd były efektem meczenia i zwierania pinów wyświetlacza ;)

    Poprawiłem również funkcję załączania grzałek ponieważ nie działała zgodnie z założeniem. Jak dokończę schemat wrzucę finałowy projekt.

    Dziękuję za pomoc :)
    Pozdrawiam
  • #5 9005656
    Shuriken
    Poziom 10  
    Witam ponownie.

    Prośba jak w poprzednio. Zupełnej zmianie uległ sposób sterowania grzałkami.

    Obecnie problem polega na tym, że na wyjściu grzałek, bez względu na temp., nic się nie dzieje.

    Załączam zmodyfikowany kod:

    
    
    include <stdio.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include "hd44780.h"
    #include "ds18b20.h"
    
    
    char str[17]=" Read       Set ";
    
    unsigned int n=20; // stan ustawienia termostatu, zaczyna od 20st
    
    double temp;
    
    void przyciski(void);
    void termostat(void); 
    int main(void)
    
    
    {
    DDRB=0x8;
    
    TCCR2= _BV(WGM20) //wlaczenie pwm with phase correct
    	  |_BV(COM21) // Clear OC2 on Compare Match when up-counting
    	  |_BV(CS20)|(CS21)|(CS22); //  prescaller 1024
    
    DDRC=0xf; // 0000 1111, wejscia pc4-pc7, wyjscia pc0-pc3.obecnie nieuzywane
    PORTC=0x30; // 0011 0000, pullup na pc4 i pc5
    
      /* Zmienna przechowuje aktualną wartość temperatury */        
      
      /* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
      unsigned char ds18b20_pad[9];
      
      /* Funkcja inicjalizuje wyświetlacz */
      lcd_init();
      /* Włącza wyświetlanie */
      LCD_DISPLAY(LCDDISPLAY);  
      /* Czyści  ekran */
      LCD_CLEAR;            
      
      /* Wyświetla tytuł */  
      LCD_LOCATE(0,0);
      lcd_puts(str);
       
       
      while(1)
      {
      
       przyciski();
        
       
      
        /* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20 
           polecenie pomiaru */      
         if(ds18b20_ConvertT())
        {
    
           /* 750ms - czas konwersji */
           _delay_ms(750);
    
          /* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad. 
             Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej 
         znaczący bajt wartość zmierzonej temperatury */            
           ds18b20_Read(ds18b20_pad);
              
          /* Składa dwa bajty wyniku pomiaru w całość. Cztery pierwsze bity mniej
             znaczącego bajtu to część ułamkowa wartości temperatury, więc całość
             dzielona jest przez 16 */       
           temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
    	   
    	   
           
    	   sprintf(str,"%4.1f\x27""C      %u\x27""C", temp, n);
    	   /* Formułuje komunikat w tablicy 'str' */
           LCD_LOCATE(0,1);
          /* Wysyła komunikat do wyświetlacza */
           lcd_puts(str);
    	   
    	   termostat();
        }
    	
    	
      }
      
    }
    
    
      void przyciski(void) 
    
       {
    	if(!(PINC & 0x10))  //jesli wcisniety na pc4
    	  {
    	   //pominiete_delay_ms(80); //wygasniecie drgan
    	   
    	     while (!(PINC & 0x10)); // czeka na zwolnienie przycisku
    	  
    	   //pominiete_delay_ms(80); //wygasniecie drgan
    	   
    	   n++; //zwieksz n o 1
    	  }
    	  
    	else if(!(PINC & 0x20))  //jesli wcisniety na pc5
    	  {
    	   //pominiete _delay_ms(80); // jw
    	   
    	     while (!(PINC & 0x20)); // czeka na zwolnienie przycisku
    	     
    	   //pominiete _delay_ms(80); // jw
    	   
    	   n--; //zmniejsz n o 1
    	  }
       } 
    
    
     void termostat(void) 
       {
    	unsigned int a=10; //ponizej n-a wlacz 3 grzalki
    	unsigned int t=0; //powyzej n-a i ponizej n-b wlacz 2 grzalki
    	t=(temp);
    	
    	
    	
    	if(temp<=(n))
    	  {
    	    
    	    OCR2=((n-t)/t)*255;
    		
    	  }
    	 else 
    	 {
    		OCR2=0;
    	 
    	 }
    	}
    	


    Oraz schemat:

    [ATMEGA8][C] Termostat - prośba o sprawdzenie kodu

    Z góry dziękuję za pomoc.

    Pozdrawiam


    Edit:

    Problem tkwił w typach zmiennych w funkcji termostat, oraz częściowo w samym algorytmie tej funkcji. Poprawiłem w/w i wszystko działa jak należy.
    Poprawna funkcja termostat:
     void termostat(void) 
       {
    	float a=0; 
    	float t=0; 
    	float b=0;
    	t=(temp);
    	
    	
    	b=((n-t)/t);
    	if (b>1)
    		{
    		a=255;
    		}
    	else 
    	a=b*255;
    	
    	
    	if(t<=(n))
    	  {
    	    
    	    OCR2=a;
    		
    	  }
    	 else 
    	 {
    		OCR2=0;
    	 
    	 }
    	}
REKLAMA