Skocz do zawartości

Wyświetlacz 7-segmentowe - multipleksowanie, widoczna kropka


maciekb

Pomocna odpowiedź

Ja mam takie bardzo podstawowe pytanie odnośnie wyświetlaczy 7 segmentowych. We wszystkich instrukcjach podłączenia takich wyświetlaczy stosuje się 8 rezystorów, po jednym na każdy segment. Czy nie można ich zastąpić jednym rezystorem podłączonym do wspólnej katody/anody? Wydawało mi się, że nie ma znaczenia 'po której stronie' diody zamontujemy rezystor 🤔

Link do komentarza
Share on other sites

@maciekb witam na forum 🙂 

6 godzin temu, maciekb napisał:

Czy nie można ich zastąpić jednym rezystorem

Można, gdybyś obiecał że będziesz używał tylko jeden segment w tym samym czasie. W sytuacji gdy użyjesz wszystkie segmenty to prąd zwiększy się 8krotnie, lecz przez rezystor dobrany dla 1 segmentu spowoduje to niedomiar i wszystkie segmenty będą świecić za ciemno.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

@Gieneq Dzięki za wyjaśnienia! Poczytałem trochę Tutaj i Tutaj, no i złożyłem swój projekt. Jest to wyświetlacz złożony z pięciu 7-segmentowych wyświetlaczy ze wspólną anodą (link). Wyświetlacz jest multipleksowany, sterowany Atmegą 88, każda cyfra zasilana jest przez tranzystor PNP. Wszystko jest złożone jak na załączonym schemacie (schemat.pdf).

Ogólnie to wyświetlacz działa, ale problem polega na tym, że przy małej liczbie zapalonych segmentów (0-2) zaczyna świecić kropka. Przy całkowicie zgaszonym wyświetlaczu świeci dość mocno. Podobnie, im mniej segmentów, tym pojedynczy segment mocniej świeci.

20210420_111745.thumb.jpg.197e46d33419eed985ef67ca2d65894e.jpg

Na powyższym zdjęciu są wyświetlone kolejno: cyfra osiem, litera A, cyfra 7, podkreślenie, całkiem zgaszony wyświetlacz. Wydać, że ostatni wyświetlacz który teoretycznie powinien być zgaszony wyświetla kropkę. Na przedostatnim widać że segment jest jaśniejszy niż na innych wyświetlaczach (i jest też kropka). Tutaj jest filmik na którym widać zachowanie wyświetlacza przy różnej ilości wyświetlanych segmentów. Byłbym bardzo wdzięczny gdyby ktoś był w stanie wyjaśnić przyczynę tego zjawiska 🙂

Ja na mój chłopski rozum myślę sobie tak:
Segmenty zapalam podając stan niski na pinach mikrokontrolera, gaszę podając stan wysoki. Prąd w wyświetlaczu płynie od wspólnej anody do katod poszczególnych segmentów i dalej przez rezystory do pinów. Zatem stan wysoki na pinie 'blokuje' przepływ prądu dzięki czemu segment gaśnie. Może w przypadku kropki stan wysoki ma zbyt niski potencjał żeby zablokować przepływ prądu 🤔 Czy to znaczy, że będę musiał użyć tranzystorów również przy wyprowadzeniach segmentów wyświetlaczy?

Link do komentarza
Share on other sites

@maciekb No ale ta kropka musi być gdzieś podłączona, sprawdź czy nie ma jakiegoś zwarcia, albo w kodzie jak to działa. Na pewno nie ma przepływu z innych lini bo po to są właśnie diody, żeby blokować prąd płynący w przeciwną stronę.

8 godzin temu, maciekb napisał:

wyświetlaczy ze wspólną anodą

Jedyna opcja, że masz na tej nóżce potencjał niższy niż na anodzie.

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

(edytowany)

@Gieneq Zmierzyłem następujące potencjały:

  • na wspólnej anodzie: 8.71V (tyle ile wychodzi z baterii)
  • na nóżkach segmentów: 5.03V (tyle ile wychodzi ze stabilizatora)
  • na nóżce kropki: 5.38V

Moje rozumowanie:
Różnica potencjałów na segmentach to 8.71 - 5.03 = 3.68V co przy 4 diodach na segment jest zbyt niskim napięciem żeby przez segment popłynął prąd (napięcie diody: 1.9V). Różnica potencjałów na kropce to 8.71 - 5.38 = 3.33V, biorąc pod uwagę, że kropka to tylko dwie diody to to napięcie może już być wystarczające żeby prąd popłynął. Dlatego kropka świeci mimo że na nóżce mikrokontrolera jest stan wysoki. Dobrze rozumiem?

Edytowano przez maciekb
Link do komentarza
Share on other sites

Jeśli chodzi o zwarcie to sprawdziłem dokładnie ścieżki jeszcze raz i są ok. Program poniżej:


#define F_CPU 1000000L  

#include <avr/io.h>
#include <util/delay.h>      

#define FPS_RATE         5
#define MULTIPLEX_DELAY  1
#define DISPLAY_SIZE 	 5

#define LT_0   0b00111111
#define LT_1   0b00000110
#define LT_2   0b01011011
#define LT_3   0b01001111
#define LT_4   0b01100110
#define LT_5   0b01101101
#define LT_6   0b01111101
#define LT_7   0b00000111
#define LT_8   0b01111111
#define LT_9   0b01101111
#define LT_A   0b01110111
#define LT_b   0b01111100
#define LT_C   0b00111001
#define LT_d   0b01011110
#define LT_E   0b01111001
#define LT_F   0b01110001
#define LT_G   0b00111101
#define LT_H   0b01110110
#define LT_I   0b00110000
#define LT_J   0b00011110
#define LT_K   0b01110110
#define LT_L   0b00111000
#define LT_M   0b00000000
#define LT_N   0b00110111
#define LT_n   0b01010100
#define LT_O   0b00111111
#define LT_P   0b01110011
#define LT_q   0b01100111
#define LT_r   0b01010000
#define LT_S   0b01101101
#define LT_t   0b01111000
#define LT_U   0b00111110
#define LT_V   0b00111110
#define LT_W   0b00000000
#define LT_X   0b01110110
#define LT_y   0b01101110
#define LT_Z   0b01011011
#define LT_    0b00000000
#define LT_SPACE        0b00000000
#define LT_DASH         0b01000000
#define LT_DOT          0b10000000
#define LT_ASTERISK     0b01100011
#define LT_UNDERSCORE   0b00001000

#define LT_SEG_A   0b00000001
#define LT_SEG_AB  0b00000011
#define LT_SEG_BG  0b01000010
#define LT_SEG_G   0b01000000
#define LT_SEG_EG  0b01010000
#define LT_SEG_DE  0b00011000
#define LT_SEG_D   0b00001000
#define LT_SEG_CD  0b00001100
#define LT_SEG_CG  0b01000100
#define LT_SEG_FG  0b01100000
#define LT_SEG_AF  0b00100001

int TEST[][DISPLAY_SIZE] = {{LT_8, LT_A, LT_7, LT_UNDERSCORE, LT_ }};

int JANEK[][DISPLAY_SIZE] = {{LT_J, LT_A, LT_N, LT_E, LT_K}};

int JANEK_MOVE[][DISPLAY_SIZE] = {
									{LT_J, LT_A, LT_N, LT_E, LT_K},
									{LT_A, LT_N, LT_E, LT_K, LT_ },
									{LT_N, LT_E, LT_K, LT_ , LT_ },
									{LT_E, LT_K, LT_ , LT_ , LT_J},
									{LT_K, LT_ , LT_ , LT_J, LT_A},
									{LT_ , LT_ , LT_J, LT_A, LT_N},
									{LT_ , LT_J, LT_A, LT_N, LT_E},
								};

int SNAKE[][DISPLAY_SIZE] = 	{
									{LT_SEG_A, LT_SEG_A, LT_ , LT_ , LT_ },
									{LT_ , LT_SEG_A, LT_SEG_A, LT_ , LT_ },
									{LT_ , LT_ , LT_SEG_A, LT_SEG_A, LT_ },
									{LT_ , LT_ , LT_ , LT_SEG_A, LT_SEG_A},
									{LT_ , LT_ , LT_ , LT_ , LT_SEG_AB},
									{LT_ , LT_ , LT_ , LT_ , LT_SEG_BG},
									{LT_ , LT_ , LT_ , LT_SEG_G, LT_SEG_G},
									{LT_ , LT_ , LT_SEG_G, LT_SEG_G, LT_ },
									{LT_ , LT_SEG_G, LT_SEG_G, LT_ , LT_ },
									{LT_SEG_G, LT_SEG_G, LT_ , LT_ , LT_ },
									{LT_SEG_EG, LT_ , LT_ , LT_ , LT_ },
									{LT_SEG_DE, LT_ , LT_ , LT_ , LT_ },
									{LT_SEG_D, LT_SEG_D, LT_ , LT_ , LT_ },
									{LT_ , LT_SEG_D, LT_SEG_D, LT_ , LT_ },
									{LT_ , LT_ , LT_SEG_D, LT_SEG_D, LT_ },
									{LT_ , LT_ , LT_ , LT_SEG_D, LT_SEG_D},
									{LT_ , LT_ , LT_ , LT_ , LT_SEG_CD},
									{LT_ , LT_ , LT_ , LT_ , LT_SEG_CG},
									{LT_ , LT_ , LT_ , LT_SEG_G, LT_SEG_G},
									{LT_ , LT_ , LT_SEG_G, LT_SEG_G, LT_ },
									{LT_ , LT_SEG_G, LT_SEG_G, LT_ , LT_ },
									{LT_SEG_G, LT_SEG_G, LT_ , LT_ , LT_ },
									{LT_SEG_FG, LT_ , LT_ , LT_ , LT_ },
									{LT_SEG_AF, LT_ , LT_ , LT_ , LT_ },
								};



void runAnimation(int framesCount, int frames[][DISPLAY_SIZE]);

void showFrame(int frame[]);

void refreshDisplay(int letters[]);

void refreshLetter(int letterPos, int letter);

int mapSegments(int original);

int mapSegment(int original, int from, int to);

int main(void)
{
	DDRD = 0b11111111;
	DDRC = 0b11111111;
	
    while (1) 
    {
		runAnimation(1, TEST);
		//runAnimation(1, JANEK);
		//runAnimation(7, JANEK_MOVE);
		//runAnimation(24, SNAKE);
    }
}

void runAnimation(int framesCount, int frames[][DISPLAY_SIZE]){
	for(int i = 0; i < framesCount; ++i){
		showFrame(frames[i]);
	}
}

void showFrame(int frame[]){
	int numberOfRefreshes = 1000 / FPS_RATE / MULTIPLEX_DELAY / DISPLAY_SIZE;
	
	for(int i = 0; i < numberOfRefreshes; ++i)
		refreshDisplay(frame);
}

void refreshDisplay(int letters[]){
	for(int i = 0; i < DISPLAY_SIZE; ++i){
		refreshLetter(i, letters[i]);
	}
}

void refreshLetter(int letterPos, int letter){
	PORTD = mapSegments(letter);

	PORTC = 0b11111111;
	PORTC &=~_BV(DISPLAY_SIZE - 1 - letterPos);
	_delay_ms(MULTIPLEX_DELAY);
}

int mapSegments(int original){
	return  ~(
			mapSegment(original, 0, 1) |
			mapSegment(original, 1, 0) |
			mapSegment(original, 2, 7) |
			mapSegment(original, 3, 6) |
			mapSegment(original, 4, 5) |
			mapSegment(original, 5, 3) |
			mapSegment(original, 6, 4) |
			mapSegment(original, 7, 2)
			);
}

int mapSegment(int original, int from, int to){
    if(from <= to)
	    return  (_BV(from) & original) <<(to - from);
	else
	    return  (_BV(from) & original) >>(from - to);
}

Te funkcje mapSegments() i mapSegment() mogą wydawać się trochę dziwne. Generalnie mam podpięte segmenty wyświetlacza do pinów mikrokontrolera inaczej niż się to zwykle robi (zamiast A-G -> 0-6 mam kolejność taką jak w schemat.pdf). Kosztem innej kolejności mam dużo prostszy układ ścieżek na płytce PCB 🙂 Żeby jednocześnie mieć porządek w kodzie, wprowadziłem funkcję mapującą, która z standardowej kolejności bitów robi mi 'moją' kolejność. Dzięki temu mogłem użyć znalezionych gdzieś w internecie gotowych definicji znaków (LT_0 - LT_Z). Te definicje są pod wyświetlacz ze wspólną katodą więc dodatkowo jeszcze robię inwersję bitów w funkcji mapSegments(). To tyle jeśli chodzi o 'dziwne' rzeczy 🙂

Link do komentarza
Share on other sites

Dnia 21.04.2021 o 12:08, maciekb napisał:

Dlatego kropka świeci mimo że na nóżce mikrokontrolera jest stan wysoki. Dobrze rozumiem?

Edit: Long story short, kropka świeci dlatego, ze 9V (zasilania) - 5V (stanu wysokiego nóżki) - spadek na tranzystorze zostawia jeszcze wystarczajcie napięcie, żeby dioda kropki się zaświeciła. Znaczy masz pin w stanie wysokim, ale nie wystarczająco wysokim. 😉

Edytowano przez kaworu
  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dnia 2.04.2021 o 07:27, Gieneq napisał:

@maciekb witam na forum 🙂 

Można, gdybyś obiecał że będziesz używał tylko jeden segment w tym samym czasie. W sytuacji gdy użyjesz wszystkie segmenty to prąd zwiększy się 8krotnie, lecz przez rezystor dobrany dla 1 segmentu spowoduje to niedomiar i wszystkie segmenty będą świecić za ciemno.

Można prosić o dokładniejszy opis zjawisk jakie tam zachodzą i dlaczego tak się dzieje? Spróbowałem zasymulować układ online i zbudowałem dwa układy: Jeden z jednym rezystorem dla wspólnej anody a drugi z osobnymi rezystorami dla każdego segmentu. Przy osobnych rezystorach spadki napięć na diodach pozostają takie same oraz taki sam pozostaje prąd płynący przez diody bez względu na ilość zapalonych diod sumarycznie przez wspólną anodę płynie suma prądów ze wszystkich diod. Natomiast przy tylko jednym rezystorze na wspólnej anodzie suma prądów pozostaje taka sama (prąd wyliczony dla jednej diody), natomiast zapalanie kolejnych diod nie zmienia zbytnio prądu pobieranego przez cały układ a jedynie spadki napięć i natężeń prądu na pojedynczych diodach. 

1.png

2.png

3.png

Link do komentarza
Share on other sites

1 godzinę temu, CTKL_PL napisał:

Można prosić o dokładniejszy opis zjawisk jakie tam zachodzą i dlaczego tak się dzieje? Spróbowałem zasymulować układ online i zbudowałem dwa układy: Jeden z jednym rezystorem dla wspólnej anody a drugi z osobnymi rezystorami dla każdego segmentu. Przy osobnych rezystorach spadki napięć na diodach pozostają takie same oraz taki sam pozostaje prąd płynący przez diody bez względu na ilość zapalonych diod sumarycznie przez wspólną anodę płynie suma prądów ze wszystkich diod. Natomiast przy tylko jednym rezystorze na wspólnej anodzie suma prądów pozostaje taka sama (prąd wyliczony dla jednej diody), natomiast zapalanie kolejnych diod nie zmienia zbytnio prądu pobieranego przez cały układ a jedynie spadki napięć i natężeń prądu na pojedynczych diodach. 

Łączenie szeregowe i równoległe rezystorów. Diody można uprościć do rezystorów, ale w tym przypadku lepiej je potraktować jako zwarcie (by uprościć obliczenia). Woltomierz to rezystor o nieograniczonej rezystancji. Narysuj schemat zastępczy potem wylicz sobie rezystancje w poszczególnych punktach zgodnie z prawem Kirchoffa, a zrozumiesz 😉 

W skrócie: rezystancja zastępcza trzech rezystorów na zewnętrznych gałęziach będzie mniejsza niż pojedynczego rezystora na głównej gałęzi. Dodatkowo przełączniki rozwierają obwód, czyli gdy przełącznik jest otwarty daną gałąź można zignorować.

Edytowano przez H1M4W4R1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.