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

atmega8 a pamietanie stanów

tomas1704 30 Sty 2009 17:46 1410 20
  • #1 6077630
    tomas1704
    Poziom 10  
    Witam od kilku godzin siedzę i rozmyślam jak miało by wyglądać zaprogramowanie przycisków tak aby wciśnięcie pierwszego odblokowało działanie 2 a dopiero wtedy 2 przycisk mógł by aktywować diodę zapalić/zamrugać nią to już mało istotne.
    Doszedłem do wniosku że można to zrobić na 2 sposoby:
    1. Miedzy procesorem a przyciskiem zapalającym diodę wstawić przełącznik SPST. W ten sposób wciskanie 1 przycisku nic nie da tak długo jak długo przełącznik będzie wyłączony.
    2. Można zaprogramować przyciski NOPB tak aby wciśniecie 1 było zapamiętywane dopiero wciśniecie 2 sprawdziło by w pamięci stan poprzedniego i w chwili gdy stan był by wysoki mógł by aktywować diodę.
    Jestem całkowicie zielony w tym i jest bardzo duże prawdopodobieństwo ze mój tok myślenia jest nie poprawny. Pisząc tego posta mam nadzieje ze znajdą się osoby które mogły by mi pomóc napisać owy kod za co był bym bardzo wdzięczny.
  • #2 6077993
    kretfr
    Poziom 12  
    Na wiele sposobów można to zrobić. W jakim języku programujesz?

    Tak na szybko, to zrobiłbym coś takiego:
    - tworzysz zmienną X, dajesz jej wartość 0
    - wciśnięcie przycisku 1 powoduje przypisanie do zmiennej X wartości 1
    - przyciski 2 ustawiasz tak (albo instrukcję wykonywaną przez wciśnięcie przycisku 2), aby zadziałał tylko wtedy, gdy X = 1
  • #3 6078034
    tomas1704
    Poziom 10  
    programuje w C środowisko avrstudio.
    Problem w tym ze nie mam pojęcia jak ma wyglądać kod a nie sama koncepcja.
  • #4 6078467
    Dr.Vee
    VIP Zasłużony dla elektroda
    W takim razie może zacznij od czegoś prostszego, np. 1 przycisk + 1 dioda, albo na razie tylko 1 dioda. Przykładów jest dużo w sieci.

    Pozdrawiam,
    Dr.Vee
  • #5 6079089
    tomas1704
    Poziom 10  
    Niestety nie mogę potrzebne mi jest właśnie ten przykład przysiedziałem kolejne kilka godzin sugerując się uwagami kolegi i doszedłem do takiego efektu:
    
    #include<avr/io.h>
    #include<compat/deprecated.h>
    
    int main(void)
    {
    unsigned int x=0;
    
    DDRD = _BV(0);
    PORTC = 0x00;
    
    while(1)
    {
        if(PINC = _BV(0))  //jesli wcisne przycisk warunek sie spelni x=1
        {
        x=1;
        else     // jesli nie x=0 i petla wraca na start bo nastepny warunek nie zostanie spelniony
       {
       x=0;
       }
    
       if(x=1)    // jesli wcisne przycisk x=1 i moge przejść do nastepnej operacji- wcisniecia 2 przycisku 
       {
             if(PINC= _BV(1))   // wcisniecie zapala diode i trzyma stan az nie puszcze przycisku
             {
             PORTD = _BV(0);
             loop_until_bit_is_set(PINC, PINC1); // i tu pytanie jak to ugryźć? 
             PORTD &= ~_BV(0);
             x=0;
             }
       }
    }
    
    }
    

    Ciesze się ze tak szybko reagujecie wiem ze strasznie "napieram" ale jest mi to potrzebne na jutro i każda pomoc sie przyda. To co stworzyłem jest prawdopodobnie niepoprawne ale o dziwo na sym. działa... prawie. kiedy zostanie spełniony warunek i 1 przycisk zostanie wciśnięty po przejściu do następnego ifa gaśnie zasadniczo to dobrze bo można ponownie go użyć. Wszystko cacy ale jest jeden mały szkopuł mianowicie czas- prawdopodobnie wciśniecie owego przycisku nada x wartość 1 ale o ile dobrze rozumiem czas wykonania tych wszystkich operacji i sprawdzenia warunków to jest zaledwie ułamek sekundy wiec pytanie:
    1. Jeśli wcisnę 1 przycisk i ustawie x= 1 to czy to mi sie nie skasuje po rozpoczęciu od nowa petli?
    2. Jak by wyście to zrobili bazując na tym bądź pisząc od podstaw?

    Jak juz wspominałem jestem totalnym laikiem w tych sprawach i dzisiaj właściwie postanowiłem to jakoś "ogarnąć" Jeszcze raz dzięki za pomoc i licze na kolejne posty.
  • #6 6079281
    Freddie Chopin
    Specjalista - Mikrokontrolery
    sorry, ale musisz poczytac jeszcze o podstawach C, a konkretnie o POROWNANIACH. twoj kod nie bedzie dzialac, poniewaz zawiera bardzo typowy blad poczatkukacego -> if(costam=ilestam); porownanie bedzie dopiero wtedy, gdy beda DWA znaki, jeden to przypisanie.

    nie mowiac juz o tym, ze gdzies ci zginela jedna klamra... moze warto pisac kod w avr stuido i na biezaco go kompilowac, a nie na forum?

    pozatym - jesli twoj kod ma robic to co mysle, to blad w zalozeniach... dioda zaswieci sie tylko wtedy gdy nacisniesz DWA przyciski jednoczesnie... wcale nie musi byc to sekwencyjnie, moze byc jednoczesnie... a taki warunek jest juz o wiele prostszy. no chyba ze napisales kod, ktory cos robi, ale nie to co bys chcial... niemniej jednak miej swiadomosc, ze jesli poprawisz bledy to tak wlasnie w skrocie bedzie dzialal ten kod.

    4\/3!!
  • #7 6079367
    tomas1704
    Poziom 10  
    faktycznie tu jest mala pomylka kod byl pisany w avr i dziala a z tym if(x=1) to przez szybkie przepisywanie sie machnąłem...
    Co do if(PINC = _BV(0)) ja to rozumiem tak: if/jesli->przycisk z portuC0 (jest wlaczony) to x=1; jesli nie to x=0;
    a jesli to nadal nie jest poprawnie to możne mógł byś znaleźć chwile i to poprawić?
  • #9 6079379
    tomas1704
    Poziom 10  
    Daj mi chwile ;]

    Dodano po 5 [minuty]:

    No więc wyciągając wnioski z tego co powiedziałeś i naniesieniu poprawek (na forum) wygląda to nastepująco:
    
    #include<avr/io.h>
    #include<compat/deprecated.h>
    
    int main(void)
    {
    unsigned int x=0;
    
    DDRD = _BV(0);
    DDRC = 0x00;
    while(1)
    {
    	if(PINC= _BV(0))
    	{
    	x=1;
    	}
    	else
    	{
    	x=0;
    	}
    
    	if(x==1);
    		{
    		if(PINC = _BV(1)); //czy to jest poprawnie? jesli przycisk aktywny to warunek?(czy skladnia powinna byc inna)
    			{	
    			PORTD = _BV(0);
    			loop_until_bit_is_set(PINC,PINC1);
    			PORTD &= ~_BV(0);
    			x=0;
    			}
    		}
    }
    
    }
    


    Mi to pod avr studio działa na sym. zapala sie doda i gasnie nie wiem czy wartosc x sie zmienia czy tez nie. Ponad to gdy daje step over po kazdym if'ie piny wybrane przechadza w odpowiednie stany. Moze sprawdz to u siebie to bedziesz widział jak to sie ma ze sobą
  • #10 6079534
    kretfr
    Poziom 12  
    
    #include <8051.h>
    
    void czekaj(unsigned char x){  // petla opozniajaca do eliminacji drgan przyciskow
    unsigned char a, b;
    for( ; x > 0; x--)
    for(a = 0; a < 10; ++a)
    for(b = 0; b < 25; ++b);}      
    
    void main(void){	// funkcja glowna
    P2 = 0;			// pomin to
    while(1){		// petla nieskonczona
    
    	char x = 0;		// inicjalizacja zmiennej x i nadanie jej wartosci 0
    	
    	if(P3_2 == 0) x = 1;	// warunek sprawdzajacy czy przycisk na P3_2 jest wcisniety, jesli tak, to x = 1
    
    	czekaj(100);		// petla opzniajaca
    
            while(x == 1)		// petla warunkowa, gdy x = 1, czyli po wcisnieciu przycisku na P3_2
            {
    
            	 if(P3_3 == 0)
                 {
                  // tutaj wstawiasz twoje instrukcje
                 }
    
                 
    
            }
    		
    		 
    
    }
    }
    


    Działający kod na '51, ale bez problemu po kilku modyfikacjach możesz przenieść to na swojego AVR'a.
  • #11 6079535
    Freddie Chopin
    Specjalista - Mikrokontrolery
    ej ten kod jest calkowicie zly... nie wiem jakim cudem dziala ci to w symulatorze, ale przypuszczalnie tylko przypadkiem...

    1. if(PINC= _BV(0)) - przed chwila byla rozmowa o roznicy miedzy porownaniem a przypisaniem

    2. if(x==1); -> srednik na koncu -> dla kompilatora ta linijka nie istnieje

    3. if(PINC = _BV(1)); -> polaczenie punktu 1 i 2.

    4. czekasz az przycisk bedzie wcisniety (domniemywam, ze wcisniety to 1), potem masz petle ktora czeka na 1... no to chyba logiczne, ze petla zakonczy sie natychmiast jak sie rozpocznie, skoro przycisk jest nacisniety

    5. najpierw PORTD ustawiasz przez przypisanie, potem kasujesz przez NAND... po co, skoro przed chwila i tak wywaliles cala jego zawartosc?

    caly twoj kod w tym momencie dziala tak jak juz pisalem - dioda zaswieci sie (a w zasadzie bedzie bardzo szybko migac) tylko wtedy gdy nacisniesz 2 przyciski na raz... nie wazne czy pierwszy bedzie ten na pinie 1 czy na pinie 0, czy zrobisz to jednoczesnie, czy nie. musza byc nacisniete obydwa... puscisz ktorykolwiek - dioda gasnie (przestaje bardzo szybko migac). chyba nie o to ci chodzilo... no chyba ze jednak o to...

    tak w ogole to nie licz na to, ze ja ci napisze ten kod [; po prostu uprzedzam za wczasu.

    4\/3!!
  • #12 6079542
    snow
    Poziom 31  
    No przełam się freddie :P Napisz kod, pokaż że masz dobre serce <lol>
  • #14 6079596
    Dr.Vee
    VIP Zasłużony dla elektroda
    tomas1704 napisał:
    Co do if(PINC = _BV(0)) ja to rozumiem tak: if/jesli->przycisk z portuC0 (jest wlaczony) ...

    Źle rozumiesz.

    PINC to stan na pinach całego portu, czyli 8 bitów.
    _BV(0) to konkretna wartość = 0x01.
    Pomijając błąd użycia operatora = zamiast ==, to porównujesz stan CAŁEGO portu z liczbą 1. Żeby mówić o poprawnym programie, to musisz sprawdzać stan jednego bitu w porcie C.

    Gdybyś włączył ostrzeżenia podczas kompilacji (-Wall) to byś zauważył, że kompilator ostrzega przed pomyłką polegającą na użyciu = zamist ==.

    Pozdrawiam,
    Dr.Vee
  • #15 6079615
    tomas1704
    Poziom 10  
    Freddie Chopin napisał:

    1. if(PINC= _BV(0)) - przed chwila byla rozmowa o roznicy miedzy porównaniem a przypisaniem

    właśnie to próbuje z Ciebie wydusić ;P Jaka jest składnia bo nie wiem...
    Dokładniej mówiąc/pisząc jak zrobic warunke w którym bedzie:

    if(przycisk == wcisniety/1) to wykonaj cos tam.

    Kolejna sprawa to interpretacja kompilatora owych warunków mianowicie:
    Ja to rozumiem następująco jesli (wcsine i puszcze) przycisk 1 to on w tej chwili przypisze mi x=1... Ale z 2 strony jesli go puszcze to 2 czesc warunku (else) zrobi z niego znow 0 zaraz po ponownym wykonaniu petli tak?
  • #16 6079635
    snow
    Poziom 31  
    if(bit_is_clear(PINC,PC0)) wykonaj cos tam

    pod warunkiem ze masz pullupa

    rozwiniecie bit_is_clear znajdziesz w ktorymś pliku .h - nie pamiętam już którym
  • #17 6079721
    Freddie Chopin
    Specjalista - Mikrokontrolery
    tomas1704 napisał:
    Kolejna sprawa to interpretacja kompilatora owych warunków mianowicie:
    Ja to rozumiem następująco jesli (wcsine i puszcze) przycisk 1 to on w tej chwili przypisze mi x=1... Ale z 2 strony jesli go puszcze to 2 czesc warunku (else) zrobi z niego znow 0 zaraz po ponownym wykonaniu petli tak?

    dokladnie tak, dlatego tez wywal druga czesc tego warunku... proste...

    4\/3!!
  • #18 6079773
    tomas1704
    Poziom 10  
    snow napisał:
    if(bit_is_clear(PINC,PC0)) wykonaj cos tam

    pod warunkiem ze masz pullupa

    rozwiniecie bit_is_clear znajdziesz w ktorymś pliku .h - nie pamiętam już którym


    jak rozumiec to "pullup"

    mam rozumiec ze wszedzie do swoich if z pinami mam dopisac bit_is_set/clera no wlasnie i teraz kolejne pytanie clear czy set i dlaczego
  • #19 6079832
    snow
    Poziom 31  
    Znajdz sobie jakiś kurs avrgcc
  • #20 6079878
    tomas1704
    Poziom 10  
    Nie mam na to juz czasu i tak wiele zrozumiałem w tak krótkim czasie za co bardzo wam dziękuje, wszelkie rady jakie tu uzyskałem doprowadziły do tego ze udało mi sie osiągnąć zamierzony efekt oto co powstało możne kiedyś się komuś przyda:
    
    #include<avr/io.h>
    #include<compat/deprecated.h>
    
    int main(void)
    {
    unsigned int x=0;  //zmienna x=0
    
    DDRD = _BV(0);  //przypisanie portom D wyjscia
    DDRC = 0x00;    // przypisanie portom C wejscia
    while(1)  //petla
    {
    	if(bit_is_set(PINC,PC0))  //jesli bit jest ustawiony ma 1 (if bit is set)
    	{
    	x=1;   //przypisanie x=1
    	}
    
    	if(x==1)  //jesli x=1 to wchodzi w 2 warunek
    		{
    		if(bit_is_set(PINC,PC1))   //jesli 2 przycis jest wcisniety wchodzi do 3 warunku
    			{	
    			PORTD |= _BV(0);   //ustaw dla pinuD0 wartosc 1
    			loop_until_bit_is_clear(PINC,PINC1);  //trzymaj stan portu D0 az nie puszcze przycisku
    			PORTD &= ~_BV(0);  // zgas diode
    			x=0;  //przypisz x wartosc 0 aby nie wszedl spowrotem do warunku po wcisnieciu 2 przycisku
    			}
    		}
    }
    
    }
    


    działa tak jak chciałem nie widze tu juz wiecej błędów jeśli są to proszę o komety ;]
REKLAMA