miccaldo napisał:
1.
void ReadEncoder();
#define GLUE(a, b) a##b
#define LEDPORT1(s) GLUE(PORT,s)
#define LEDPORT LEDPORT1(LED)
#define LEDDDR1(s) GLUE(DDR,s)
#define LEDDDR LEDDDR1(LED)
a) Co to jest? Coś jak podprogram? Ale dlaczego zakończony średnikiem?
Pierwsza linia to deklaracja funkcji, dalsze linie nie są z nią bezpośrednio związane. Dalej w programie jest definicja tej funkcji, czyli nagłówek i kod w klamrach. Deklaracja jest po to, żeby dana funkcja była widoczna nie tylko od miejsca definicji, ale w całym pliku.
Cytat: 2.
static uint8_t PROGMEM DIGITS[11]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF};
a) Ok, zmienna 'static' dlaczego tak a nie np. int czy char? Co daje static?
b) Ta tablica oznacza ledy wyświetlacza żeby dawały jakąś cyfrę tak?
c)Jeśli tak, to czy mogę usunąć tą tablicę? a zastąpić to makrodefinicjami do wyświetlacza jakie ustawiłem na początku programu?
a) Mylisz typ zmiennej ze słowem kluczowym modyfikującym jej zachowanie. Typem jest tutaj uint8_t, czyli 8-bitowa liczba bez znaku, a static w tym miejscu mówi kompilatorowi, że ta zmienna dostępna jest tylko i wyłącznie w tym pliku. Taka ochrona przed przypadkowym użyciem jej w zupełnie innym miejscu w programie.
b) Ta tablica to "szablony" dla kolejnych cyfr. Cyfra na wyświetlaczu 7-segmentowym składa się z segmentów, każdy segment to jeden bit i pin procesora. Jak zamienisz każdy element tablicy na liczbę binarną, to będziesz miał ciąg kolejnych segmentów, które mają być zapalone i zgaszone.
c) Jeśli bardzo chcesz, to możesz. Musisz tylko pamiętać o prawidłowym zastąpieniu tej metody we wszystkich miejscach w programie.
Cytat: 3.
static inline void ShowOnLED(uint8_t val)
{
uint8_t tmp=0xFF;
if((val & 0x7F)<11) tmp=pgm_read_byte(&DIGITS[val & 0x7F]);
if((val & DP)==1) tmp&=~(DP);
LEDPORT=tmp;
}
a) Jakiś skomplikowany podprogram, jeszcze trochę czasu minie zanim zacznę w taki sposób programować. Podprogram ma włączać wyświetlacz? Mogę go zastąpić czymś prostszym, żeby np. pokazywał część wyświetlacza "A"?
Ta funkcja wyświetla cyfrę na wyświetlaczu. Wartość tymczasowa ma wszystkie segmenty zgaszone, potem sprawdzanie zakresu w pierwszym ifie i odczyt wzorca dla odpowiedniej cyfry. Drugi if sprawdza, czy ma być zapalona kropka i modyfikuje zmienną tymczasową. Na koniec jest przenoszona na port, na którym jest wyświetlacz. Polecam szczegółową analizę, można się sporo dowiedzieć przy wyszukiwaniu informacji, co, jak i dlaczego.
Cytat: 4.
volatile uint8_t LEDDIGITS[LEDDISPNO];
ISR(TIMER0_OVF_vect)
{
static uint8_t LEDNO;
PORTB|=0x0F; //Wyłącz wszystkie wyświetlacze
LEDNO=(LEDNO+1)%LEDDISPNO;
ShowOnLED(LEDDIGITS[LEDNO]);
PORTB=(PORTB & 0xF0) | (~(1<<LEDNO) & 0x0F); //Wybierz kolejny wyświetlacz
ReadEncoder();
}
a) pierwsza linijka, znów coś z cyframi wyświetlacza, o co chodzi?
b)coś z timerem0, ale znów niezbyt rozumiem co tam się dzieje.
Jak na razie tyle... Niestety w tym programie są dołączone biblioteki o których nie słyszałem i pewnie dlatego nie wiem do czego służą poszczególne funkcje. Musiał bym wybrać z tego programu wszystko co niezbędne i napisać na podstawach, jedyne wyjście bo to póki co nie mój poziom programowania.
a) Słowo volatile na razie zignoruj, ma tam być, a wyjaśnienie łatwo znajdziesz w sieci. Ta linia to deklaracja tablicy dla czterech wyświetlaczy (cyfr).
b) To jest procedura obsługi przerwania, wywołuje się automatycznie za każdym razem, gdy timer się przepełni, tj. co określony czas zależny od częstotliwości zegara timera i wartości, po której ma się przepełniać. Po więcej informacji o timerach i przerwaniach zapraszam do jednego z wielu kursów, artykułów, poradników, książek i tak dalej.
Żadnych dziwnych bibliotek tam nie ma, obsługa przerwań (interrupt), obsługa zmiennych w pamięci Flash (pgmspace), którą nie musisz się przejmować i delay do zwykłych opóźnień. Ich użycie w samym kodzie jest minimalne. Ale trzeba niestety się podszkolić C i działania AVRów.