Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 21 kwi 2026, o 15:12


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 62 ]  Przejdź na stronę 1, 2, 3  Następna strona
Autor Wiadomość
PostNapisane: 30 maja 2013, o 12:26 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Witam
Jak dla mnie jest trochę mało wyjaśnienia przy przykładach, dlatego o wszystko co nie rozumiem będę pytał tutaj.
Pierwszy przykład na miganie Diody
A więc tak, z tego co wyczytałem to DDRC to chodzi o kierunki portów in\out, a PORTC o stany na portach wysoki\niski
Zapis
bajt |= (1<<nr_bitu) ustawia bit
bajt &= ~(1<<nr_bitu) zeruje bit

#define LED_ON PORTC &= ~LED_PIN \\ dlaczego to włącza diody skoro jest zerowanie bitu
#define LED_OFF PORTC |= LED_PIN \\ dlaczego to wyłącza diody skoro jest ustawianie bitu

napisałem sobie taki programik żeby diody zapalały się od zewnątrz do środka ale dwie zewnętrzne czyli PC7 i PC0 wciąż się palą
są spięte tak że PC7 do 1, PC6 do 2 itd. a jest ich 8

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Teraz tak - nie wiem jak rozumieć to,
DDRC |= ( (1<<PC7)|(1<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0) )
ja to widze tak

PC 01234567
DDRC 00000000
1<<PC7 00000001
itd...
czyli będe miał DDRC same jedynki czyli wszędzie wyjście

następnie trzeba ustawiać PORTC na odpowiedni stan ale skąd mam wiedzieć ile one wynoszą na samym początku.
Przyjąłem że 0

moje makro i wywołanie
#define LED_ON(X, Y) ( PORTC &= ~( (1<<X) | (1<<Y) ) )
LED_ON(PC0, PC7);

czyli mamy
PC 01234567
PORTC 00000000

1<<PC0 10000000
1<<PC0 00000001
OR 10000001 otrzymam coś takiego
~ 01111110 otrzymam coś takiego
gdzie port C ma same zera
& 00000000

czyli wszędzie stan niski i nic nie powinno się palić

nie mogę tego zrozumieć
oraz co to za funkcja i skąd się wzięła _delay_ms(1000);

Proszę o pomoc

Kody umieszczamy w znacznikach syntax=c - Zielony J.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 12:41 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

rzeczywiście w książce zabrakło troszkę wyjaśnienia o kierunkach pinów itp, ale już od dawna uzupełnienie jest na moim blogu

http://mirekk36.blogspot.com/2012/01/av ... stawy.html

dlatego zapraszam do jego wertowania. Jeśli chodzi o pytania:

NOOB napisał(a):
#define LED_ON PORTC &= ~LED_PIN \\ dlaczego to włącza diody skoro jest zerowanie bitu


no to pomyśl sobie - to zależy jak podłączysz diodę LED do pinu, czy katodą (wtedy zerowanie portu będzie ją zapalać) czy anodą (wtedy zerowanie portu będzie ją gasić) ale masz na to przykłady na tym rysunku w artykule którego link podałem wyżej.

NOOB napisał(a):
Teraz tak - nie wiem jak rozumieć to,
DDRC |= ( (1<<PC7)|(1<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0) )
ja to widze tak

PC 01234567
DDRC 00000000
1<<PC7 00000001
itd...
czyli będe miał DDRC same jedynki czyli wszędzie wyjście


no i dobrze rozumiesz

Cytuj:
następnie trzeba ustawiać PORTC na odpowiedni stan ale skąd mam wiedzieć ile one wynoszą na samym początku.
Przyjąłem że 0


ale to nie trzeba przyjmować wystarczy zajrzeć do noty PDF procesora i spojrzeć ZAWSZE na Initial Values przy każdym rejestrze - w większości zawsze są zera
Obrazek

------------------------ [ Dodano po: 1 minucie ]

NOOB napisał(a):
nie mogę tego zrozumieć
oraz co to za funkcja i skąd się wzięła _delay_ms(1000);


spokojnie wszystko powoli ;) a to jest akurat wbudowana w AVR GCC funkcja do opóźnień i podajemy jej jako argument stałą która wyrażona jest w milisekundach, a jest jeszcze bliźniacza _delay_us() - jak się domyślasz w mikrosekundach ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 13:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

w szkole miałem tak że dioda przewodzi tylko w jednym kierunku, założenie jej na odwrót powodowało że nie będzie się zapalać.
a jeśli chodzi o to opóźnienie to mieliśmy sami realizować, poprzez pustą pętle która wykonywała się 2000000 razy albo i więcej



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 14:23 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

NOOB napisał(a):
w szkole miałem tak że dioda przewodzi tylko w jednym kierunku, założenie jej na odwrót powodowało że nie będzie się zapalać.


Taka jest prawda o diodach , ale w przypadku mikrokontrolera zmienia się sposób patrzenia na diodę:
gdyż sterować możesz z pinu zarówno poziomem LOW jak i HI co w skrócie oznacza tylko tyle,że
albo wystawiasz GND albo VCC więc dioda może być podłączona w tym momencie do woli:

Anodą do VCC - wystawiając LOW na pin zapalasz , a HI gasisz diodę ,
Katoda do GND - wystawiając HI na pin zapalasz , a LO gasisz diodę .

W przypadku ATB diodę zapala stan NISKI (LOW) czyli są podłączone Anodami do VCC



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 19:08 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

A teraz jak mamy drugi przykład

wklejam kod
Kod:
// dioda LED
#define LED_PIN (1<<PC7)         // definicja pinu do którego podłączona jest dioda
#define LED_TOG PORTC ^= LED_PIN   // makrodefinicja – zmiana stanu diody

// klawisz K1
#define KEY_PIN (1<<PC6)
#define KEY_DOWN !(PINC & KEY_PIN)

uint8_t klawisz_wcisniety(void);   // deklaracja funkcji

// *************************************************** pętla główna main()
int main(void)
{
   // ****** inicjalizacja *********
   DDRC |= LED_PIN;      // kierunek pinu PC7 – wyjściowy
   PORTC |= LED_PIN;      // wyłączenie diody LED
   DDRC &= ~KEY_PIN;      // kierunek pinu PC6 - wejściowy
   PORTC |= KEY_PIN;      // podciągnięcie pinu do VCC

   // ****** pętla główna programu  *********
   while(1)
   {
      if(  klawisz_wcisniety()  )     // jeśli klawisz wciśnięty
      {
          LED_TOG;      // zmień stan diody na przeciwny
         _delay_ms(200);   // pauza 200ms
      }
   }
}
//******************************************************** koniec main()

// definicja funkcji
uint8_t klawisz_wcisniety(void)
{
   if( KEY_DOWN )               // klawisz wciśnięty ?
   {
      _delay_ms(80);            // czas drgań styków
      if( KEY_DOWN ) return 1;      // jeśli wciśnięty?  zakończ funkcję - rezultat = 1
   }

   return 0;   // jeśli nie wciśnięty klawisz, zakończ funkcję, rezultat = 0
}


jak działa ten warunek if( KEY_DOWN )

!(PINC & (1<<PC6))

PINC ustawione jest na 00000000
1<<PC6 ustawia pin 6 na 1 czyli 00000010
PINC & (1<<PC6) daje nam 00000000
potem ! negacja 11111111

Czyi co tam tak naprawę jest w tym warunku i co to wyszło wciśnięty czy nie?? Nie widzę tu żadnej zmiennej która dawała by jakąś konkretna wartość.

oraz na blogu jest napisane
PORTx - rejestr wyjściowy
PINx - rejestr wejściowy

ale jeśli chodzi o zadanie z diodami to PORTx odpowiada za stan na pinie wysoki lub niski, więc o co z tym chodzi??



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 19:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 mar 2013
Posty: 236
Lokalizacja: Warszawa
Pomógł: 5

no bo skoro jest to rejestr wyjsciowy, wiec ustawiajac go mozesz wystawic na nozce odpowiedni stan: niski lub wysoki. Dla mnie ogromnie wsparło to co kardaś napisał na swoim blogu, w sumie napisał wszystko, styknie to przeanalizowac. Podał tobie linka

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 19:40 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
!(PINC & (1<<PC6))

PINC ustawione jest na 00000000
1<<PC6 ustawia pin 6 na 1 czyli 00000010


teraz przekombinowałeś, nic tu nie ustawia pinu 6 na 1

jeszcze raz przeczytaj ten artykuł na blogu bo może zbyt pobieżnie go przeczytałeś a tam jest WYRAŹNIE już napisane co to jest rejestr PINC przede wszystkim. Przypomnę jednak - jest to rejestr WEjściowy - zapamiętaj to .... czyli jeśli wcześniej ustawisz sobie w DDRC kierunek PC6 na wejście (wpisując zero) .... to potem możesz odczytywać cały rejestr PINC a w nim każdy bit odpowiada jednemu WEjściu procka. W tym przykładzie jest to warunek

if( !(PINC & (1<<PC6) )

więc tu nie ma ŻADNEGO USTAWIANIA tylko maskowanie, czytaj to tak:

załóżmy że w PINC jest 0b00000000

więc masz operację jak wyżej:

0b00000000
0b01000000 AND (to się dzieje w warunku)
--------------------
0b00000000 ----> tyle wynosi wartość wyrażenia (PINC & (1<<PC6)) i teraz ją negujesz wykrzyknikiem !

więc warunek jest spełniony bo po negacji masz 0b11111111

i teraz UWAGA zastanów się - co to oznacza że założyliśmy iż PINC = 0b00000000 .... to oznacza że założyłeś że na pinie PC6 wcisnąłeś klawisz i bit nr 6 ma tu wartość ZERO, bo jeśli PUŚCISZ klawisz to wartość PINC będzie wynosić:

0bx1xxxxxx

rozumiesz ? te x-y oznaczają że nie ważne są stany na innych pinach mogą być zero albo jeden - nie ważne

ale dzięki operacji maskowania sprawdzasz wybrany pin - czy jest zwarty do GND

chcesz inny pin ? proszę

if( !( PINC & (1<<PC2) ) .... i już pięknie to samo sprawdzasz na PC2

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 19:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Czyli IF odczytuje wartość tylko na pinie 6??
if( !( PINC & (1<<PC2) ) a tutaj tylko na drugim??

00000000
00000100 AND
---------------------
00000000 !
----------------
11111111

Warunek spełniony PIN 2 ma jeden, dobrze to zrobiłem??



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 20:04 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
Czyli IF odczytuje wartość tylko na pinie 6??


tak

NOOB napisał(a):
if( !( PINC & (1<<PC2) ) a tutaj tylko na drugim??


oczywiście

dobrze rozpisałeś operacje bitowe ale to oznacza że klawisz jest ZWARTY do GND (czyli na PC2 masz stan NISKI).... teraz te same operacje rozpisz sobie gdybyś miał w PINC 0b00000100 ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 20:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

czyli 0 oznacza zwarty z GND czyli nacisnąłem, a 1 że puściłem tak??

a to rozpisanie to

00000100
00000100 AND
-------------
00000100 !
-------------
11111011

pin2 ma zero czyli wciśnięty

Ale uruchamiając program pierwszy raz to ile wynosi PINC 00000000 czy 11111111
no bo pisałeś że 0 oznacza wciśnięty, a uruchamiając powinno być na odwrót.

Wisze to to tak, naciskam robi się 0 w PINC warunek zwróci 1 a jak puszczam robi się 1 warunek zwróci 0.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 21:22 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

Cytuj:
Ale uruchamiając program pierwszy raz to ile wynosi PINC 00000000 czy 11111111


jeszcze raz powtórzę - wystarczy zaglądać do noty PDF na "Initial values" ale oczywiście domyślnie jest zero tyle że:

przecież tu działa elektronika - przecież linię podciągasz rezystorem wewn. do VCC

PORTC |= (1<<PC2)

więc już po tym w rejestrze PIN po odczycie zawsze będzie JEDEN - dokąd nie wciśniesz klawisza

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 21:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

czyli domyślnie mam zera W PINC
ale PORTC |= (1<<PC2) powoduje ustawienie 1, czyli przycisk nie wciśnięty
a wciśniecie go zwiera z masą i daję zero, tak??

A PORTC to przecież wyjście, więc dlaczego nie zrobić PINC |= (1<<PC2)
PINC odpowiada za stany wyjściu
----------------------------------------------------------

Nie rozumiem tego.
mógłbyś mi rozpisać ten przykład dokładniej, nieważne jak próbuje to to nie dociera to do mnie.
tak jak w książce szkoła programowania C, gdzie gość daje przykład i konkretne wytłumaczenie do tego.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 21:47 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

mam wrażenie - że wcale nie przeczytałeś tego artykułu

http://mirekk36.blogspot.com/2012/01/av ... stawy.html

:( sorki .... i wcale nie przeanalizowałeś tego rysunku który tam pokazałem

Cytuj:
ale PORTC |= (1<<PC2) powoduje ustawienie 1,


NIGDY w życiu ! ..... jeśli PC2 jest WEJŚCIEM, to wystawienie jedynki na PC2 do rejestru WYJŚCIOWEGO załącza wewnętrzny rezystor podciągający linię do VCC żeby wymusić stan wysoki (zamiast np rezystora zewnętrznego) ...

I TYLKO dlatego gdy odczytujesz PINC a klawisz nie jest wciśnięty (zwarty do GND) to dlatego odczytasz z rejestru PINC że bit nr.2 ma wartość JEDEN - bo PINC sprawdza stan WEJŚCIA - WEJŚCIA rozumiesz ? a jak to wejście KLAWISZEM zewrzesz do GND do odczytasz z bitu nr.2 ZERO ....

gdybyś zaś nie ustalił stanu wysokiego za pomocą PORTC |= (1<<PC2) - to na wejściu miałbyś stan nieustalony w związku z czym gdybyś w pętli odczytywał PINC to bit nr.2 przyjmowałby różne wartości czasem 1 czasem 0 itp

Pomyśl sobie gdy PIN jest WEJŚCIEM to można powiedzieć że rejestr WYjściowy PORTC jest do niczego nie potrzebny - prawda ? Dlatego producent procka wymyślił że wykorzysta jego bity w tym czasie do załączania wewn. rezystorów podciągających - ale obejrzyj pan ten rysunek dokładnie i poczytaj ten artykuł ok?

------------------------ [ Dodano po: 2 minutach ]

NOOB napisał(a):
Nie rozumiem tego.
mógłbyś mi rozpisać ten przykład dokładniej, nieważne jak próbuje to to nie dociera to do mnie.
tak jak w książce szkoła programowania C, gdzie gość daje przykład i konkretne wytłumaczenie do tego.


tylko że tu łączy się jeszcze z programowaniem elektronika - a ja nie opiszę WSZYSTKIEGO w książce - czyli podstaw elektroniki. Wiesz co to są stany nieustalone ? na czym polega podciąganie linii do VCC ? dlaczego to robimy i często za pomocą zewnętrznych rezystorów ???

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 22:02 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Czytałem artykuł, ale elektronika to ciężki dla mnie temat, i sam się tego nie nauczę.
i dalej nie rozumiem poco na PC6 ustawiać stan wysoki na wyjściu skoro on jest odpowiedzialny za wejście.

Chyba muszę się tego nauczyć na pamięć, i tyle



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 22:06 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 mar 2013
Posty: 739
Lokalizacja: Poznań
Pomógł: 84

Witam
Ja to rozumiem trochę inaczej a więc:
jeśli mam w DDRC ustawione że pin PC2 jest wejściem (DDRC pin PC2 = 0)
i do portu wyjściowego PORTC na pozycji PC2 wpiszę 1 (ustawię na nim stan wysoki)
to podciągam w porcie wejściowym PINC pin PC2 wewnętrznym rezystorem do VCC
czyli przy odczycie z tego pinu (PORTC pin PC2) będę miał 1
a po wciśnięciu przycisku podłączonego z jednej strony do tego wejścia (PINC pin PC2)
a z drugiej do masy (GND) wymuszę na porcie wejściowym (PINC pin PC2) stan niski (0)

takie jest moje rozumowanie ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 22:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Cytuj:
jeśli mam w DDRC ustawione że pin PC2 jest wejściem (DDRC pin PC2 = 0)
i do portu wyjściowego PORTC na pozycji PC2 wpiszę 1 (ustawię na nim stan wysoki)
to podciągam w porcie wejściowym PINC pin PC2 wewnętrznym rezystorem do VCC


dotąd jest to nawet jasne, ale w warunku jest tylko PINC, więc kiedy jest odczytywany PORTC a kiedy PINC

i tam jeszcze było powiedziane że PINC odczytuje wejście, dlaczego skoro to rejestr wyjściowy.


01000000 - PORTC
01000000 - (1<<6)
to potem ma takie coś 01000000 & 01000000 = 0100000000
zaprzeczenie 10111111 czyli przycisk wciśnięty, a ma wychodzić 1 że jest newciśnięty



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 maja 2013, o 23:41 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
dotąd jest to nawet jasne, ale w warunku jest tylko PINC, więc kiedy jest odczytywany PORTC a kiedy PINC


a po co miałby być odczytywany PORTC ??? no toż w przypadku wejścia (jeszcze raz powtórzę za kolegą i za sobą) służy on TYLKO do włączania tych rezystorów - żeby wymusić WYRAŹNY - JASNY i przejrzysty stan wysoki na wejściu PC2 gdy nie jest wciśnięty klawisz - bo inaczej napięcie by pływało i procek odczytując w tym warunku IF rejestr PINC miałby przypadkowe wartości o lub 1 na bicie nr.2

więc przy starcie programu RAZ podciągasz wejście do VCC

a potem gdzieś w pętli gdzie sprawdzasz czy klawisz wciśnięty odczytujesz wciąż wejście PC2 poprzez odczyt rejestru PINC i tylko ten odczytujesz bo TYLKO TEN pokazuje co jest na wejściu PC2 w naszym przykładzie

------------------------ [ Dodano po: 4 minutach ]

NOOB napisał(a):
i tam jeszcze było powiedziane że PINC odczytuje wejście, dlaczego skoro to rejestr wyjściowy.


teraz to ja już zbaraniałem - toż nie wiem już za bardzo ile razy powtarzać, i w tym artykule masz - że PINC to rejestr WEJŚCIOWY - panie kochany WEJŚCIOWY - a ty masz - znowu po swojemu że niby wyjściowy :(

kurczę aż tu jeszcze raz wrzucę zrzut ekranu ci z artykułu z bloga - bo piszesz że czytałeś a za chwilę powtarzasz coś odwrotnego

Obrazek

więc gdzieś ty widział że niby PINC to rejestr wyjściowy

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 08:50 

Pomógł: 0

Mam wrażenie, że kolega powinien się przyjrzeć opisowi portów IO

Obrazek

Reszta jak wyżej, już opisał Mirek.
Czyli wystawiając 1 na DDRD ustawiasz na wyjście, następnie PORTD to jest stan pinu
A w przypadku DDRD = 0 (dla całego portu, albo konkretnego pinu) port jest wejściowy,
następnie jeżeli w tym trybie wystawisz na PORTD = 1 no to włączysz ten wewnętrzny tranzystor,
czyli podłączysz wewnętrzny rezystor do +Vcc, czyli (on ma ok 47kom) masz jak by na wejściu podciągnięte tym rezystorem napięcie z +Vcc, teraz jak zewrzesz wyjście do MASY (GND), to przeca na tym rezystorze "odłoży" się pełne napięcie Vcc, przez co na wejściu czyli rejestrze PIND zostanie odczytane zero, jeżeli tego "umasienia" ;) nie będzie no to przez ten rezystor będziesz miał na PIND "1", ale nie jedynkę na wejściu tylko jak by "1" podciągniętą.
Zresztą to łatwo zmierzyć miernikiem, jak wystawisz w trybie wejściowym na PORTD =1 to na tym pinie pojawi ci się Vcc ;).

Stosujemy to po to, by po pierwsze nie było stanów nie ustalonych, czyli mówiąc obrazowo, wejście układu ma wielką rezystancje rzędu setek megaomów. To jak z multimetrem (włącz sobie multimetr - miernik, na AC i zakres 200mV, dotkniesz paluchem jednej z sond i będziesz miał śmieci) Tu jest podobnie, bez tego podciągania, wejście będzie sobie "pływać" przez co może "procesor" czyli rejest PINx "pokazywać" raz zero, raz jeden.
Dzięki temu wystarczy tylko Switch podłączyć między portem a masą (GND) nie trzeba stosować żadnych elementów dodatkowych.
Trzeba pamiętać jeszcze o jednej rzeczy, że rezystor podciągający włącza się z pewnym opóźnieniem (ale to już całkiem inna historia)



Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 10:28 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Dalej nie rozumiem dlaczego w PORTC muszę ustawić stan wysoki skoro to rejestr wyjściowy, ale przyjmę że tak jest i tyle, żeby nie było tego pływającego napięcia.
Ale jeszcze raz jeśli chodzi o rozpisanie tego warunku if( !(PINC & (1<<PC6) )
Cytuj:
i teraz UWAGA zastanów się - co to oznacza że założyliśmy iż PINC = 0b00000000 .... to oznacza że założyłeś że na pinie PC6 wcisnąłeś klawisz i bit nr 6 ma tu wartość ZERO, bo jeśli PUŚCISZ klawisz to wartość PINC będzie wynosić:
0bx1xxxxxx


76543210 PC

00000000 PINC - 0 oznacza że przycisk jest wciśnięty, mimo że nie jest, a od warunku wychodzi jednak że niejest
01000000 1<<PC6
00000000 &
11111111 ~
to jest pierwsze sprawdzenie warunku, czyli przycisk nie wciśnięty

A jak naciskam przycisk to co się dzieje

PINC zmieni stany na przeciwne??

czyli będzie

11111111 PINC
01000000 1<<6
01000000 &
10111111 ~

wyszło zero na PC6 czyli wcisnięty

tak to będzie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 10:50 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
Dalej nie rozumiem dlaczego w PORTC muszę ustawić stan wysoki skoro to rejestr wyjściowy, ale przyjmę że tak jest i tyle, żeby nie było tego pływającego napięcia.


Wcale nie musisz ;) czy trudno zrobić sobie doświadczenie ? .... weź nie ustaw tego bitu w PORTC (czyli nie podłączysz podciągania linii do VCC) i wtedy zaobserwuj jak działa ci klawisz ;) zdziwisz się okropnie że wariuje - albo że nawet jeśli go nie wciskasz to procek sam czasem uznaje że jest wciśnięty

idąc dalej - zamiast ustawiać ten pit 2 w PORTC - weź i podłącz fizycznie do tego pinu rezystor 10K a drugi koniec do VCC - tak jak to robisz przy RESECIE - chyba wiesz o czy mówię ? ... i nagle się okaże że klawisz znowu dobrze działa - bo znowu na wejściu nie ma stanu HiZ (nieustalonego) tylko stan wysoki gdy klawisz nie wciśnięty.

No to teraz chyba już zrozumiesz, że producenci procków wykorzystali niepotrzebny rejestr PORTC (w tym sensie niepotrzebny, że w czasie gdy pin jest wejściem to do niczego by się nie przydał) ... i wykorzystali jego bity to załączania takiego samego rezystora tylko że wewnątrz SCALAKA (procesora) ... dzięki temu upraszcza ci się układ na płytce - rozumiesz ?

Niestety bez podstaw elektroniki będzie ciężko .... trzeba tego też zacząć się uczyć równolegle

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 10:52 

Pomógł: 0

Oj, no Rejestr wyjściowy dla trybu wyjściowego!!!!!!!
A rejestr rezystorów podciągających dla trybu WEJŚCIOWEGO!!!!! i tyle, czego tu nie rozumieć?

Tu jak już Mirek opisał, rejestr PORTx w trybie wejściowym pełni dodatkową funkcję, włączania wewnętrznych rezystorów podciągających.

Wejścia wysokiej impedancji (czyt. analogie z miernikiem) mają to do siebie, że jak wiszą bez podciągania to stany na nich są nie ustalone.
Równie dobrze mógłbyś zastosować zewnętrzny rezystor między portem, a Vcc, a wtedy nie musiał byś ustawiać bitów w rejestrze PORTx (w trybie wejściowym) by mieć podciąganie.
Kumasz?, wiem, że najlepiej było by to obrazowo pokazać, ale zobacz sobie "przeanalizuj" ten wycinek PDF co wrzuciłem, tam jest tranzystor bezpośrednio na porcie, on właśnie jest włączany (jako podciaganie) w trybie wejściowym gdy ustawisz na PORTx jedynkę


No i Mirek mnie ubiegł ;).

PS. Zobacz sobie "Mikroprocesorowa Ośla Łączka" kurs w EdW numer Styczeń 2003 źółta Ramka Technikalia, tam jest dosyć łopatologicznie to wyjaśnione.

zajawka
Obrazek



Ostatnio edytowano 31 maja 2013, o 11:00 przez rezasurmar, łącznie edytowano 2 razy

Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 10:53 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
00000000 PINC - 0 oznacza że przycisk jest wciśnięty, mimo że nie jest, a od warunku wychodzi jednak że niejest


No tutaj to już jakąś fantasmagorię dopisujesz - skoro masz 0 na PC2 w rejestrze PINC to znaczy że właśnie zwarłeś klawisz do GND ! więc co ty za wnioski wyciągasz? Patrz

PINC - 0b00000000 - klawisz na PC2 WCIŚNIĘTY

PINC - 0b00000100 - klawisz na PC2 zwolniony - i panuje na nim stan WYSOKI bo linia podciągnięta jest do VCC

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 11:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Dobra już rozumiem do podciąganie rezystora.

A jeśli chodzi o te bity, jak włączam ta płytkę i nic nie robię to, PINC jaki ma stan 00000000 czy 11111111, (przycisk jest niewciśnięty), W PDF pisze initial value N/A.
Skoro jest niewciśnięty to ma 1 tak?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 11:15 

Pomógł: 0

Tak, no bo masz włączone podciąganie. A jak wcisniesz czyli zewrzesz do masy, to będziesz miał zero.



Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 11:33 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
A jeśli chodzi o te bity, jak włączam ta płytkę i nic nie robię to, PINC jaki ma stan 00000000 czy 11111111


ale zobacz ty pytasz tak jakbyś podłączył całe stado przycisków do każdego z 8 pinów .....

jeśli mówimy o przypadku jednego bitu tego np PC2 to

PINC - 0bxxxxxZxx (x-nas nie interesują te bity , Z - tu będzie stan NIEUSTALONY jeśli nie masz podciągania wewn albo zewn) więc nie wiadomo co się odczyta czy 0 czy 1.

Ale jeśli masz PODCIĄGANIE do VCC czy to zewn. rezystorem czy programowo to:

PINC - 0bxxxxx0xx (x-nas nie interesują te bity) ... ale widać że klawisz został wciśnięty i zwarłeś PC2 do GND

PINC - 0bxxxxx1xx (x-nas nie interesują te bity) ... ale widać że klawisz jest zwolniony i na PC2 panuje stan wysoki od podciągania

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 maja 2013, o 11:36 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Chyba już rozumiem



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 cze 2013, o 14:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Mam małe pytanko dotyczące przerwań

mam coś takiego

Kod:
TCCR0 |= (1<<WGM01); // załączam trym CTC timera
TCCR0 |= (1<<CS02)|(1<<CS00); // ustawiamy dzielnik taktowanie na 1024
OCR0 = 39; // dodatkowy dzielnik dzięki któremu uzyskamy taktowanie około 200 hz
TIMSK |= (1<< OCIE0); // zezwolenie na wykonywanie przerwań w trybie CTC


wiem że przerwanie się wywołuje kiedy timer zliczy ileś tam impulsów z preskalera(dzielnika taktowanie)
ilość tych impulsów to obstawiam że to jest to OCR0 = 39
ale dalej nie wiem kiedy to się wywołuje co 1s, 1ms?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 cze 2013, o 15:54 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 mar 2013
Posty: 739
Lokalizacja: Poznań
Pomógł: 84

Czas zależy od taktowania procesora
np.
F_CPU = 8 000 000 Hz
wtedy preskaler 1024 podzieli takty co 7812,5 hz i z taką częstotliwością będzie zliczał timer
a dodatkowo w OCR0 masz 39 gdzie timer porównuje tą wartość ze swoim licznikiem i kiedy się
zrównają wygeneruje przerwanie.
Czyli podliczając 8 000 000 / 1024 / 39 = około 200 Hz a to 1 sekunda / 200 = 0,005 sekundy

W trybie CTC timera i przy zezwoleniu na przerwanie od timera.
A Ty musisz tylko napisać procedurę i podstawić pod wektor przerwania od porównania timera
i będzie ona wywoływana co 0,005 sekundy

Ps.
Umieszczaj swoje kody w znacznikach "syntax C" lepiej się czyta
Też się uczę i mogłem coś pokiełbasić :D


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 cze 2013, o 16:56 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27456
Lokalizacja: Szczecin
Pomógł: 1045

NOOB napisał(a):
ale dalej nie wiem kiedy to się wywołuje co 1s, 1ms?


przeczytaj dokładnie rozdział o multipleksowaniu wyświetlaczy LED, tam masz to bardzo szeroko opisane jak się konfiguruje timery itp

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 cze 2013, o 17:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 maja 2013
Posty: 56
Pomógł: 0

Co ja tu robię źle że mi to nie działa??
Sterowanie wyświetlaczem 7-seg.
Mi to wygląda że się przerwanie nie włącza

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 62 ]  Przejdź na stronę 1, 2, 3  Następna strona

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO