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

[ATMEGA8][C] Sterownik do zgrzewarki

pawelek1990 12 Wrz 2010 12:40 4631 14
  • #1 8502325
    pawelek1990
    Poziom 10  
    Witam,
    Jestem poczatkujący w dziedzinie programowania nie jest to mój pierwszy program lecz mam z nim problem.Załączam schemat podzielony na dwie części co prawda rysowany ręcznie bo nie miałem inej możliwości ale tu nie o tym... :|

    [ATMEGA8][C] Sterownik do zgrzewarki [ATMEGA8][C] Sterownik do zgrzewarki [ATMEGA8][C] Sterownik do zgrzewarki

    Ten projekt to zgrzewarka a raczej sterownik do zgrzewarki która wykonuje proste zadanie:

    MIKRO SWITCH:
    1-PC0 (+ dodaje cyfre na wyswietlaczu segmentowym)
    2-PC1 (- odejmuje cyfre na wyświetlaczu)
    3-PC2 (pedał nożny wykonuaje instrukcje zgrzania w wyznaczonym na wyswietlaczu czasie)

    WYŚWIETLACZ:
    1-100ms
    2-200ms
    ...
    9-900ms
    0.-1000ms

    np:
    to znaczy gdy na wyświetlaczu jest 5 to po nacisnięciu pedała i jego zwolnieniu program wykonuje zgrzanie przez 0,5s

    na schemacie widać diode IR jest to część transoptora narazie to niema zaczenia do testów zastosowałem zwykłego leda

    #define F_CPU 4000000L 
    #include <avr/io.h>
    #include <util/delay.h>
    
    
    //   -- 7 --                1-PD7
    //  |       |               2-PD6
    //  9       6               3-VCC
    //  |       |     3,8-VCC   4-PD5
    //   ---10--                5-PD4
    //  |       |               6-PD3
    //  1       4               7-PD2
    //  |       |               8-VCC
    //   -- 2 --  o 5           9-PD1
    //                          10-PD0
    
    #define WYS_0   0x00  // 0000 0000
    #define WYS_1   0x28  // 0010 1000 
    #define WYS_2   0xcd  // 1100 1101
    #define WYS_3   0x6d  // 0110 1101
    #define WYS_4   0x2b  // 0010 1011
    #define WYS_5   0x67  // 0110 0111
    #define WYS_6   0xe7  // 1110 0111
    #define WYS_7   0x2c  // 0010 1100
    #define WYS_8   0xef  // 1110 1111
    #define WYS_9   0x6f  // 0110 1111
    #define WYS_10   0xfe // 1111 1110
    
    #define BUZZ   0x01     // 0000 0001
    #define TOPTON   0x02   // 0000 0010
    #define TOPTOFF   0x00  // 0000 0000
    
    #define SW_1   0x01  // 0000 0001
    #define SW_2   0x02  // 0000 0010
    #define SW_3   0x04  // 0000 0100
    
    int main(void)
    {
      DDRD = 0xff;  //1111 1111
      PORTD = 0xff; //1111 1111
      
      DDRB = 0x03;  //0000 0011
      PORTB = 0x03; //0000 0011
      
      DDRC  = 0x00; //0000 0000
      PORTC = 0x07; //0000 0111
      
      
      
      while(1)
      {
        if(!(PINC & SW_1))
        {
    
    	   if(PORTD & ~WYS_10)
          {
           PORTB |= BUZZ;
           _delay_ms(100);
           PORTB &= ~BUZZ;
          }	
    	  if(PORTD & ~WYS_9)
          {
           PORTD = ~WYS_10;
          }
    	  if(PORTD & ~WYS_8)
          {
           PORTD = ~WYS_9;
          }
    	  if(PORTD & ~WYS_7)
          {
           PORTD = ~WYS_8;
          }
    	  if(PORTD & ~WYS_6)
          {
           PORTD = ~WYS_7;
          }
    	  if(PORTD & ~WYS_5)
          {
           PORTD = ~WYS_6;
          }
    	  if(PORTD = ~WYS_4)
          {
           PORTD = ~WYS_5;
          }
    	  if(PORTD = WYS_3)
          {
           PORTD = ~WYS_4;
          }
    	  if(PORTD = WYS_2)
          {
           PORTD = ~WYS_3;
          }
    	  if(PORTD = WYS_1)
          {
           PORTD = ~WYS_2;
          }
          if(PORTD = ~WYS_0)
          {
    	  PORTD = ~WYS_1;      
    	  }
         _delay_ms(80);
         while(!(PINC & SW_1)) {}
         _delay_ms(80);
        }
    	
    
        if(!(PINC & SW_2))
        {
          if(PORTD & ~WYS_1)
          {
            PORTB |= BUZZ;
            _delay_ms(100);
            PORTB &= ~BUZZ;
          }
    	  if(PORTD & ~WYS_2)
          {
           PORTD = ~WYS_1;
          }
    	  if(PORTD & ~WYS_3)
          {
           PORTD = ~WYS_2;
          }
    	  if(PORTD & ~WYS_4)
          {
           PORTD = ~WYS_3;
          }
    	  if(PORTD & ~WYS_5)
          {
           PORTD = ~WYS_4;
    	  }
    	  if(PORTD & ~WYS_6)
          {
           PORTD = ~WYS_5;
          }
    	  if(PORTD & ~WYS_7)
          {
           PORTD = ~WYS_6;
          }
    	  if(PORTD & ~WYS_8)
          {
           PORTD = ~WYS_7;
          }	  
    	  if(PORTD & ~WYS_9)
          {
           PORTD = ~WYS_8;
          }	 
          if(PORTD & ~WYS_10)
          {
           PORTD = ~WYS_9;
          }
           _delay_ms(80);
           while(!(PINC & SW_2)) {}
           _delay_ms(80);
        }
    	
    	
    	
    	
    	if(!(PINC & SW_3))
        {
          if(PORTD & WYS_1)
          {
           PORTB = TOPTON;
           _delay_ms(100);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_2)
          {
           PORTB = TOPTON;
           _delay_ms(200);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_3)
          {
           PORTB = TOPTON;
           _delay_ms(300);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_4)
          {
           PORTB = TOPTON;
           _delay_ms(400);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_5)
          {
           PORTB = TOPTON;
           _delay_ms(500);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_6)
          {
           PORTB = TOPTON;
           _delay_ms(600);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_7)
          {
           PORTB = TOPTON;
           _delay_ms(700);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_8)
          {
           PORTB = TOPTON;
           _delay_ms(800);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_9)
          {
           PORTB = TOPTON;
           _delay_ms(900);
           PORTB = TOPTOFF;
    	  }
    	  if(PORTD & WYS_10)
          {
           PORTB = TOPTON;
           _delay_ms(1000);
           PORTB = TOPTOFF;
    	  }
    	  _delay_ms(80);
          while(!(PINC & SW_3)) {}
          _delay_ms(80);
    	}
    	else
    	{
    	PORTB = TOPTOFF;
    	}
     
      }
    }


    Problem polega na tym że gdy odpalam program wyświetlacz jest czysty, gdy nacisne '+' pokazuje sie '1' i dźwiek, gdzy ponownie nacise '+' tylko dźwięk na wyświetlaczu zostaje '1'.
    Gdy nacisne '-' na wyswietlaczu pokazuje się '8' i dżwięk, gdy ponownie nacisne '-' jest tylko dźwięk a na wyświetlaczu zostaje '8'
    Gdy wcisne pedal nożny na na '1' lub na '8' to i tak czas świeceia testowej diody Led jest dłuższy niż przewidywany...:cry:

    prosze o pomoc, podpowiedzi, naprowadzenia lub konkretne przykłady z góry dziękuje pawelek1990

    PS
    tu jeszcze foto całośći na płytce stykowej:
    [ATMEGA8][C] Sterownik do zgrzewarki
  • Pomocny post
    #2 8502439
    sulfur
    Poziom 24  
    Prawdopodobnie nie rozróżnia kolega operatora przypisania (=) od porównania (==).

    Niepotrzebnie robi to kolega na około.

    WYS_0 do WYS_10 zamienić na tablicę, Może być char albo uint8_t. Dodać jedną zmienną np czas.

    Wtedy można użyć warunku:

    if (bit_is_clear(PINC, SW_1) && czas < 10)
    {
    czas++;
    PORTD = WYS[czas];
    // dodac eliminacje drgania stykow i ew ten buzer
    }


    Analogicznie postąpić z odejmowaniem. Dużo mniej zbędnego kodu.

    EDIT: może się okazać, że poprawna linijka
    PORTD = ~WYS[czas];
    w zależności od tego czy sterujesz masą czy plusem i jaki zapis w tablicy.
  • #3 8502449
    gaskoin
    Poziom 38  
    sulfur napisał:
    Prawdopodobnie nie rozróżnia kolega operatora przypisania (=) od porównania (==).


    Nie jest on przecież nigdzie potrzebny ani użyty :)
  • Pomocny post
    #4 8502460
    sulfur
    Poziom 24  
    Proszę zatem o podpowiedź, co robią te linijki i jakie jest ich zadanie.

    if(PORTD = ~WYS_4) 
          { 
           PORTD = ~WYS_5; 
          } 
         if(PORTD = WYS_3) 
          { 
           PORTD = ~WYS_4; 
          } 
         if(PORTD = WYS_2) 
          { 
           PORTD = ~WYS_3; 
          } 
         if(PORTD = WYS_1) 
          { 
           PORTD = ~WYS_2; 
          }


    Z góry dziękuję.
  • #5 8502495
    pawelek1990
    Poziom 10  
    te znaki '=' były zmieniane bo próbowałem róznych rzeczy ale teraz wiem gdzie lezy błąd postaram sie to naprawić i podam prawidłowy kod

    dzięki :D
  • #6 8502516
    gaskoin
    Poziom 38  
    sulfur napisał:
    Proszę zatem o podpowiedź, co robią te linijki i jakie jest ich zadanie.



    W tym gąszczu andów i równasiek nie zauważyłem tego nawet :P Gratuluję bystrego wzroku :)
  • #7 8502679
    pawelek1990
    Poziom 10  
    #define F_CPU 4000000L 
    #include <avr/io.h>
    #include <util/delay.h>
    
    
    //   -- 7 --                1-PD7
    //  |       |               2-PD6
    //  9       6               3-VCC
    //  |       |     3,8-VCC   4-PD5
    //   ---10--                5-PD4
    //  |       |               6-PD3
    //  1       4               7-PD2
    //  |       |               8-VCC
    //   -- 2 --  o 5           9-PD1
    //                          10-PD0
    
    
    #define WYS_1   0x28  // 0010 1000 
    #define WYS_2   0xcd  // 1100 1101
    #define WYS_3   0x6d  // 0110 1101
    #define WYS_4   0x2b  // 0010 1011
    #define WYS_5   0x67  // 0110 0111
    #define WYS_6   0xe7  // 1110 0111
    #define WYS_7   0x2c  // 0010 1100
    #define WYS_8   0xef  // 1110 1111
    #define WYS_9   0x6f  // 0110 1111
    #define WYS_10   0xfe // 1111 1110
    
    
    
    #define BUZZ   0x01     // 0000 0001
    #define TOPTON   0x02   // 0000 0010
    #define TOPTOFF   0x00  // 0000 0000
    
    #define SW_1   0x01  // 0000 0001
    #define SW_2   0x02  // 0000 0010
    #define SW_3   0x04  // 0000 0100
    
    int main(void)
    {
      DDRD = 0xff;  //1111 1111
      PORTD = 0xff; //1111 1111
      
      DDRB = 0x03;  //0000 0011
      PORTB = 0x03; //0000 0011
      
      DDRC  = 0x00; //0000 0000
      PORTC = 0x07; //0000 0111
      
      unsigned char  czas ;
      
      char tablica[] = {0x00,0x28,0xcd,06d,0x2b,0x67,0xe7,0x2c,0xef,0x6f,0xfe};
      
      
      while(1)
      {
    
    	if (bit_is_clear(PINC, SW_1) && czas < 10) 
        { 
        czas++; 
        PORTD = ~WYS_tablica[czas]; 
     
        }
        
    	
     
      }
    }


    dalej niemoge tego zakumać... :cry:
    wywala mi mase błędów
  • Pomocny post
    #8 8502731
    sulfur
    Poziom 24  
    Błędy są dwa. W zmiennej tablica jest 06d zamiast 0x6d. Po drugie nie ma takiej zmiennej WYS_tablica. Jest natomiast zmienna tablica. Aha i trzeci błąd, wypada zainicjować zmienna czas np wartością zero, żeby nie zaczynać od przypadkowej wartości.

    Tak ponad to, jednym naciśnięciem klawisza przejdziesz od razu do 10, jestem tego pewien. Nie eliminujesz drgania styków i nie czekasz na zwolnienie przycisku. Pętla wykonuje się jak najszybciej to możliwe, czyli w tym wypadku stanowczo za szybko.
  • #9 8502782
    pawelek1990
    Poziom 10  
    ...
    int main(void)
    {
      DDRD = 0xff;  //1111 1111
      PORTD = 0xff; //1111 1111
      
      DDRB = 0x03;  //0000 0011
      PORTB = 0x03; //0000 0011
      
      DDRC  = 0x00; //0000 0000
      PORTC = 0x07; //0000 0111
      
      unsigned char  czas ;
      
      char tablica[] = {0x00,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f,0xfe};
      
      
      while(1)
      {
        PORTB = TOPTOFF;
    	czas = 0;
    
    	if (bit_is_clear(PINC, SW_1) && czas < 10) 
        { 
        czas++; 
        PORTD = ~tablica[czas]; 
     
         _delay_ms(80);
         while(!(PINC & SW_1)) {}
         _delay_ms(80);
        }
        
    	
     
      }
    }


    poprawiłem tak jak kolega napisał ale cos dziwnego sie dzieje jak testuje sw_1 nie działa a po nacisniecie sw_2 wyswietla sie jeden kolejne nacisniecia nic niedają... najwyraźniej zowu musiałem cos pokręcić
  • #11 8502811
    pawelek1990
    Poziom 10  
    dziękuje działa tak jak powinno sądze że z resztą już dam rade :D

    PS
    Jak już wspomniałem umieszczam kod:
    #define F_CPU 11059200L 
    #include <avr/io.h>
    #include <util/delay.h>
    //1   0x28  - 0010 1000   <--WYŚWIETLACZ
    //2   0xcd  - 1100 1101
    //3   0x6d  - 0110 1101
    //4   0x2b  - 0010 1011
    //5   0x67  - 0110 0111
    //6   0xe7  - 1110 0111
    //7   0x2c  - 0010 1100
    //8   0xef  - 1110 1111
    //9   0x6f  - 0110 1111
    //10  0xfe  - 1111 1110
    #define BUZZ     0x01  // 0000 0001
    #define BUZZOFF  0x00  // 0000 0000
    #define TOPTON   0x02  // 0000 0010
    #define SW_1     0x01  // 0000 0001
    #define SW_2     0x02  // 0000 0010
    #define SW_3     0x04  // 0000 0100
    
    int main(void)
    {
      DDRD = 0xff;  //1111 1111
      PORTD = 0xff; //1111 1111
      
      DDRB = 0x03;  //0000 0011
      PORTB = 0x03; //0000 0011
      
      DDRC  = 0x00; //0000 0000
      PORTC = 0x07; //0000 0111
      
      unsigned int   czas;
      unsigned char  cyfra = 0 ;
      unsigned char  mniejsza = 0 ;
      unsigned char  wieksza = 0 ;
      
      char wyswietlacz[] = {0x00,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f,0xfe};
      char mniej[] = {0,2,3,4,5,6,7,8,9,10,11};
      char wiecej[] = {0,0,1,2,3,4,5,6,7,8,9};
      
      while(1)
      {
    	PORTB = BUZZOFF;
    	if (bit_is_clear(PINC, 0) && cyfra < 10) 
        { 
         cyfra++;
    	 mniejsza++;
    	 wieksza++;
         PORTD = ~wyswietlacz[cyfra]; 
    
         _delay_ms(50);
         while(!(PINC & SW_1)) {}
         _delay_ms(50);
        }
    	
    	if (bit_is_clear(PINC, 0)) 
    	{
    	 if (cyfra < 11 && cyfra > 9)
    	 {
    	  PORTB = BUZZ;
          _delay_ms(100);
          PORTB = BUZZOFF;
    	 }
    	 _delay_ms(50);
         while(!(PINC & SW_1)) {}
         _delay_ms(50);
    	}
    	
    	czas = 100 * cyfra;	
    	
        if (bit_is_clear(PINC, 1) && cyfra < 11 && cyfra > 0) 
        {  
        cyfra--;
    	mniejsza--;
    	wieksza--; 
        PORTD = ~wyswietlacz[cyfra];
         
    	_delay_ms(50);
        while(!(PINC & SW_2)) {}
        _delay_ms(50);
        }
    	
    	
        if (bit_is_clear(PINC, 2) && cyfra < 11 && cyfra > 0) 
        {   
         if (cyfra < mniej[mniejsza] && cyfra > wiecej[wieksza])
    	 {
    	  PORTB = TOPTON;
    	  _delay_ms(czas);
    	  PORTB &= ~TOPTON;
    	  
    	  PORTB = BUZZ;
          _delay_ms(90);
          PORTB = BUZZOFF;
          _delay_ms(70);
    	  PORTB = BUZZ;
          _delay_ms(90);
          PORTB = BUZZOFF;
    	 }
         
    	 _delay_ms(100);
         while(!(PINC & SW_3)) {}
         _delay_ms(100);
        }
    	
     
      }
    }


    Mam kolejny problem mianowicie czas załączenia diody na wyjsciu PB1 nie trwa tyle ile powinien.
    np:
    1000ms=1s a trwa około 4,5s (mierzone na stoperze)
    myslałem że to wina kwarcu zmieniłem na 11,059D (początkowo 4Mhz)
    ustawienia lfuse:0xff hfuse:0xc9

    i mam wrażenie że ta dioda jescze dłużej świeci tym razem nie mierzyłem czasu...
    czy koledzy wiedzą czego to może być wina :?:
    z góry dziękuje za pomoc :D
  • Pomocny post
    #12 8505193
    sulfur
    Poziom 24  
    Na początku pozwolę sobie na złośliwą uwagę w formie pytania czy kolega przymierza się do napisania książki jak nie należy pisać oprogramowania ?

    Przechodząc do sedna.
    PORTB = TOPTON; 
         _delay_ms(czas); 
         PORTB &= ~TOPTON;


    _delay_ms to w rezultacie makro preprocesora. Oznacza to, że jest rozwijane w trakcie kompilowania programu na (jakiś) konkretny kod. Nie wiem co prawda jak reaguje na taki kod kompilator, gdy nie jest w stanie określić wartości argumentu w trakcie kompilacji, a nie napisał kolega, czy czas świecenia jest różny dla różnych cyfr, czy taki sam niezależnie od ustawienia.

    Proponuję sprawdzić taki oto kod.
    PORTB = TOPTON; 
    char i;
    if (cyfra == 0) i = 10;
    else i = cyfra;
    for (; i ; i--) delay_ms(100);
    PORTB &= ~TOPTON;
  • #13 8505325
    pawelek1990
    Poziom 10  
    Nie zamierzam pisać w najbliższym czasie żadnej książki. :D te błędy sa wynikiem tego że jestem bardzo początkujący...
    Wstawiłem ten kod, efekt jest identyczy jak w tym co ja zastosowałem...
    Każdy program ma analogicznie dłuższy czas załączenia diody teraz jak i wczesniej...
  • #14 8506004
    sulfur
    Poziom 24  
    Ale czy czasy kiedy wyświetla się jeden i kiedy wyświetla się 9 są takie same czy różne ?

    EDIT: tak ponad to, polecam sprawdzić działanie programu na wewnętrznym taktowaniu, ustawić odpowiednio fuse na jakąś wartość i odpalić program. Może się okazać, że te kondensatory 33 pF są za duże. Ja osobiście jak do tej pory używałem tylko 22pF. Są to jedyne rzeczy, które przychodzą mi do głowy w tej chwili.
  • #15 8506226
    pawelek1990
    Poziom 10  
    Czasy są różne rosną analogicznie jak wczesniej tylko wartości są większe przyblizony czas programu '10' to 4,5 sekundu a powinno być 1 sekunda.

    PS
    Po zastosowaniu się do zaleceń stwierdzam że program działa idealnie na wewnętrznym kwarcu 1Mhz ustawienia:
    lfuse:0x61
    hfuse:0xD9
    dziękuje za pomoc :D
    temat do zamknięcia
REKLAMA