Witam. Przerabiam kurs z Edw Pana Koppel-a i mam pytanie do osób lepiej znających ode mnie C. Nie wiem dlaczego wewnątrz pierwszego elementu tablicy w funkcji WyswietlHex:
znajduje się w [] nawiasach var>>(3*4) - jest to przesunięcie o 12 miejsc w prawo? Skoro tak to dlaczego akurat o 12, skoro jest 16 cyfr do wyświetlenia, a mimo wszystko program działa prawidłowo. Parametrem funkcji jest 16 bitowa zmienna g_Licznik.
Dlaczego kolejne wyrazy tablicy mają odpowiednio w [] nawiasach 2*4, 1*4 oraz czemu indexy 1,2,3 dodatkowo są porównywane z 0xf.
Oto cały kod (autorstwa Pana Koppela) do obsługi wyświetlacza LED - wypisywanie na kolejnych wyświetlaczach liczb szesnastkowych.
g_DaneWyswietlacza[0] = pgm_read_byte(&g_WzorCyfr[var>>(3*4)])znajduje się w [] nawiasach var>>(3*4) - jest to przesunięcie o 12 miejsc w prawo? Skoro tak to dlaczego akurat o 12, skoro jest 16 cyfr do wyświetlenia, a mimo wszystko program działa prawidłowo. Parametrem funkcji jest 16 bitowa zmienna g_Licznik.
Dlaczego kolejne wyrazy tablicy mają odpowiednio w [] nawiasach 2*4, 1*4 oraz czemu indexy 1,2,3 dodatkowo są porównywane z 0xf.
Oto cały kod (autorstwa Pana Koppela) do obsługi wyświetlacza LED - wypisywanie na kolejnych wyświetlaczach liczb szesnastkowych.
#define LED_A 0
#define LED_B 1
#define LED_C 2
#define LED_D 3
#define LED_E 4
#define LED_F 5
#define LED_G 6
#define LED_DP 7
#define LEDPORT PORTB
#define LEDDDR DDRB
#define COM1 6
#define COM2 5
#define COM3 4
#define COM4 3
#define COMPORT PORTD
#define COMDDR DDRD
uint8_t g_AktWyswietlacz = 0;
uint8_t g_DaneWyswietlacza[4];
prog_uint8_t g_DaneCom[4] =
{~(1<<COM1), ~(1<<COM2), ~(1<<COM3), ~(1<<COM4)};
prog_uint8_t g_WzorCyfr[16] =
{
~(1<<LED_A | 1<<LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_F), // 0
~(1<<LED_B | 1<<LED_C), // 1
~(1<<LED_A | 1<<LED_B | 1<<LED_G | 1<<LED_E | 1<<LED_D), // 2
~(1<<LED_A | 1<<LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_G), // 3
~(1<<LED_B | 1<<LED_C | 1<<LED_G | 1<<LED_F), // 4
~(1<<LED_A | 1<<LED_F | 1<<LED_G | 1<<LED_C | 1<<LED_D), // 5
~(1<<LED_A | 1<<LED_F | 1<<LED_E | 1<<LED_D | 1<<LED_C |1<< LED_G), // 6
~(1<<LED_A | 1<<LED_B | 1<<LED_C), // 7
~(1<<LED_A | 1<<LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_F | 1<<LED_G), // 8
~(1<<LED_G | 1<<LED_F | 1<<LED_A | 1<<LED_B | 1<<LED_C | 1<<LED_D), // 9
~(1<<LED_A | 1<<LED_B | 1<<LED_C | 1<<LED_E | 1<<LED_F | 1<<LED_G), // A
~(1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_F | 1<<LED_G), // B
~(1<<LED_A | 1<<LED_D | 1<<LED_E | 1<<LED_F), // C
~(1<<LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_G), // D
~(1<<LED_A | 1<<LED_D | 1<<LED_E | 1<<LED_F | 1<<LED_G), // E
~(1<<LED_A | 1<<LED_E | 1<<LED_F | 1<<LED_G) // F
};
uint16_t g_Licznik = 0;
// Funkcja wyświetla w kodzie heksadecymalnym podaną liczbę
void WyswietlHex(uint16_t var)
{
[b] g_DaneWyswietlacza[0] = pgm_read_byte(&g_WzorCyfr[var>>(3*4)]);
g_DaneWyswietlacza[1] = pgm_read_byte(&g_WzorCyfr[(var>>(2*4))&0xf]);
g_DaneWyswietlacza[2] = pgm_read_byte(&g_WzorCyfr[(var>>(1*4))&0xf]);
g_DaneWyswietlacza[3] = pgm_read_byte(&g_WzorCyfr[var&0xf]);
}
// Start
int main(void)
{
/////////////////////////////
// inicjacja
LEDDDR = 0xff;
COMDDR = 1<<COM1 | 1<<COM2 | 1<<COM3 | 1<<COM4;
// Timer0
TCCR0 = 1<<CS01|1<<CS00;
TIMSK = 1<<TOIE0;
// Globalne zezwolenie na przerwania
sei();
// koniec inicjacji
/////////////////////////////
for(;;)
{
WyswietlHex(g_Licznik);
_delay_loop_2(0xffff);
g_Licznik++;
}
return 0;
}
//_________________________________________________________________________________
// Obsługa przerwań
SIGNAL(SIG_OVERFLOW0)
{
// Wpisanie do licznika początkowej wartości
TCNT0 = 128;
// Wygaszenie wyświetlaczy
COMPORT |= 1<<COM1 | 1<<COM2 | 1<<COM3 | 1<<COM4;
// Wysłanie odpowiedniej danej
LEDPORT = g_DaneWyswietlacza[g_AktWyswietlacz];
// Włączenie odpowiedniego wyświetlacza
COMPORT &= pgm_read_byte(&g_DaneCom[g_AktWyswietlacz]);
// Zwiększenie stanu zmiennej wskazującej na obsługiwany wyświetlacz
++g_AktWyswietlacz;
if(g_AktWyswietlacz > 3)
g_AktWyswietlacz = 0;
}