Skocz do zawartości

Miganie diodami za pomoca UART


Krawi92

Pomocna odpowiedź

Hej, bawię się teraz odbiorem danych, wrzuciłem funkcje odbierania pojedynczego znaku i za pomocą prostych instrukcji np: steruje stanem na pinach. Pomyślałem, że jak wcisne 1 to mam zgasić diode(bo domyslnie po wystartowaniu świeci) a jak wcisnę 2 to ma migać za pomocą operacji XOR. Problem teraz jest taki, że gdy właśnie ona miga cały czas, to program juz nie reaguje na inne dane. Widać, że konwenter pracuje, dane dopływają, jednak instrukcje się nie wykonują. Próbowałem coś zrobić za pomocą polecenia break; ale lipa. Juz probowalem kilka wariantów, ale ciągle utykam w pętli. Ktoś poradzi co robię źle ? Dodam, że działanie tego programu po prostu sobie sam wymyśliłem,ale nie sadziłem, że stworzy to taki problem dla mnie 😄 

 

#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include<avr/interrupt.h>
#include<avr/pgmspace.h>
#include "UART/uart.h"

typedef uint16_t u16; // Zmiana nazwy typu zmiennych
typedef uint8_t u8;

char dane; // Zmienna przechowywujaca dane odbioru

int main (){

	DDRB |= (1<<PB6);	// PB6 jako wyjscie
	PORTB |= (1<<PB6); // Stan wysoki na PB6
  
 //               inicjalizacja USART           //
	USART_Start(UBRR_Value); //wartosc UBRR
  while(1) {
	
	dane = USART_Receive(); // Dane odbioru do "dane"

	if (dane == '1') { // Jesli znak to 1
		PORTB &=~(1<<PB6);  // Zgas diode

		}else if (dane == '2') { // Jesli znak to 2
			while(dane == '2') { // wykonuj petle dopoki znak to 2
				PORTB ^= (1<<PB6); // migaj dioda co 250ms
				_delay_ms(250);
				if (!(dane == '2')) break; // Jesli znak bedzie inny opusc petle
	    }
		}


}
}

 

Link do komentarza
Share on other sites

Masz coś takiego: while (dane == '2').

Czy jest jakaś szansa na to, aby zmienna "dane" zmieniła wartość wewnątrz tej pętli? Jeśli uważasz że tak, to napisz w jaki sposób.

Edytowano przez ethanak
Link do komentarza
Share on other sites

Wyobraź sobie taką sytuację.

Jesteś operatorem wyłącznika. Podchodzisz do szefa, szef ci daje karteczkę. Na karteczce jest napisane "włącz". Podchodzisz do wyłącznika i właczasz, a potem znowu idziesz do szefa po kartkę.

Teraz dostałeś kartkę "migaj". Podchodzisz do wyłącznika, przełączasz, czekasz chwilę, sprawdzasz jaką masz kartkę. Oczywiście "migaj". Przełączasz, odczekujesz, sprawdzasz... no dalej masz "migaj", bo przecież cały czas masz tę samą kartkę... i tak w kółko.

A szef sam nie przyjdzie żeby dać ci w łeb i zabrać kartkę...

Rozumiesz?

Fajnie że masz linijkę typu "dane = cośtam", ale przecież ta linijka sama z siebie się nie wykona. Tak samo jak kartka sama się magicznie nie zmieni na inną.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Wyobraź sobie dalej operatora wyłącznika.

Dostał kartkę "migaj". Poszedł, przełaczył, odczekał i wraca do szefa.

- Masz pan coś dla mnie?

- Nie.

- To idę jeszcze raz mignę.

W którymś momencie szef powie "tak" - i wtedy wykonuje następne polecenie.

Może być?

Bo przerwanie to takie wymaganie od szefa, żeby podlazł i kartkę podmienił...

Zastanów się przede wszystkim, czy pętla while jest tam w ogóle potrzebna.

 

Link do komentarza
Share on other sites

Zapętliłem, bo chciałem uzyskać efekt migania, dopóki nie zmieni się znak odbioru, dlatego wykorzystałem pętle. Nie przychodzi mi na razie inny pomysł do głowy jak wykonywać jakieś polecenie bez przerwy dopóki nie zmieni sie znak

Link do komentarza
Share on other sites

Ale przecież masz jedną pętlę while(1) - po co ta druga?

Porównaj dwa moje posty o operatorze wyłącznika - czy w drugim jest jakaś wewnętrzna pętla do machania wyłącznikiem?

Poza tym - nie obraź się, ale robisz podstawowy błąd: chcesz programować "na rejestrach", ale nie masz pojęcia o programowaniu. Moja rada: wróć do Arduino IDE, na tym się naucz, a potem - jeśli będziesz chciał - będziesz mógł zostać specjalistą od jednego przestarzałego mikrokontrolera. 

Bo na razie chcesz ustawić zawory w Syrence nie mając prawa jazdy i nie wiedząc jak się skręca na skrzyżowaniu. I nawet nie wiedząc, że dwusuw nie ma zaworów 😉

Link do komentarza
Share on other sites

To nie jest żadne poddawanie się. Nie zostaniesz kierowcą F1 mając kartę rowerową - trzeba przejść przez kilka etapów.

Może myślisz, że Arduino IDE to dla cieniasów jest, a prawdziwi twardziele piszą hexy z palca? Mam jakieś 40 lat doświadczenia w programowaniu, od zupełnego cieniasa do profesjonalisty, a jakoś Arduino IDE używam z powodzeniem (chociaż przyznam, że nie jest to co najbardziej lubię).

Przemyśl to sobie.

Aha, etap pisania hexów z palca mam już za sobą (Spectrum i inne takie na Z80 czy 6502). Tyle że wtedy nie było innej możliwości...

Edytowano przez ethanak
  • Lubię! 2
Link do komentarza
Share on other sites

 

1 godzinę temu, Krawi92 napisał:

Hmmm jak to teraz rozwiązać ? Przerwaniem sprzętowym od odebrania danych ?

Tak można, moduł USART generuje odpowiednie przerwanie, ale póki co, zastanów się jak można rozwiązać problem inaczej, tak jak sugerował @ethanak ten drugi while nie jest potrzebny. Zapoznaj się z jego artykułem nt maszyny stanów, możesz też spróbować jakoś schematycznie rozrysować przepływ programu.

Poza tym rozpisanie warunków: w tym wypadku zamiast

if (!(dane == '2')) break; // Jesli znak bedzie inny opusc petle

lepiej wygląda

if (dane != '2') break; // Jesli znak bedzie inny opusc petle

 

Edytowano przez _LM_
  • Lubię! 1
Link do komentarza
Share on other sites

4 godziny temu, Krawi92 napisał:

Przecież zmienna dane to:

 dane = USART_Receive();

Tak..ale zeby zmienic zawartosc tej zmiennej musisz wykonac ta linijke...w przeciwnym razie juz na zawsze utkwisz w while bo nie masz wewnatrz tej petli modyfikacji tej zmiennej, czyli dane zawsze bedzie sie rownac juz '2'...inaczej by sprawa wygladala gdyby modyfikowanie tej zmiennej zachodzilo w przerwaniu...

 

4 godziny temu, Krawi92 napisał:

Nie przychodzi mi na razie inny pomysł do głowy jak wykonywać jakieś polecenie bez przerwy dopóki nie zmieni sie znak

Maszyna stanow lub jeden warunek if wiecej...czyli wywalasz while...w drugim if sprawdzasz czy dane=='2'...jesli tak to ustawiasz jakas "flage" na true...i robisz trzeci if z warunkiem (flaga == true) i w nim umieszczasz swoje miganie...oczywiscie musisz ustawic ta flage na false jesli inny znak przylazl...(to tak tylko dla przykladu)

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.