Загрузка данных
Третье задание — это кульминация лабораторной работы. Здесь микроконтроллер превращается в полноценное устройство ввода, как кодовый замок или калькулятор.
Чтобы реализовать этот пункт, нам нужно решить 3 главные проблемы:
1. **Отсечка удержания (Detekcja zmiany stanu):** Таймер опрашивает клавиатуру сотни раз в секунду. Если ты нажмешь «5», за долю секунды программа может подумать, что ты нажал «5» сто раз, и заполнит весь экран. Нам нужно реагировать только на *новое* нажатие.
2. **Значение кнопок (Wartość liczbowa):** Массив key_codes хранит картинки для экрана (сегменты). Нам нужен новый массив key_values, который будет хранить реальные математические числа (0-9), чтобы собрать из них число.
3. **Светодиод D4 (Dioda D4):** Светодиоды D1-D8 управляются пином P3.5 (DISP5). Нам нужно расширить наш мультиплексор с 5 до 6 позиций, чтобы он мог зажигать еще и обычные светодиоды.
Вот пошаговая инструкция, что и где поменять в коде.
### 1. Глобальные переменные (Zmienne globalne)
Добавляем массив математических значений кнопок, счетчик цифр и переменную для сохранения итогового числа. Массив экрана расширяем до 6 элементов.
```c
// Zwiększamy tablicę do 6 elementów (pozycja [5] to diody LED na linii P3.5)
unsigned char led_display[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Zmienne do obsługi wprowadzania liczby (Zadanie 3)
unsigned char digit_count = 0; // Ile cyfr już wprowadzono (0-4)
unsigned int current_number = 0; // Aktualnie budowana liczba
unsigned int saved_number = 0; // Zapisana liczba (po wciśnięciu D/Enter)
// Zmienne do wykrywania NOWEGO wciśnięcia (Edge detection)
unsigned char last_active_r = 0xFF;
unsigned char last_active_c = 0xFF;
// Tablica Wartości matematycznych przycisków (nie kodów 7-segmentowych!)
// Wartości powyżej 9 to klawisze funkcyjne: A=10, B=11, C=12, D(Enter)=13, E=14, F=15
unsigned char code key_values[4][4] = {
{7, 8, 9, 15},
{4, 5, 6, 14},
{1, 2, 3, 13},
{0, 10, 11, 12}
};
```
### 2. Мультиплексор в TIMER3_ISR (Rozszerzenie do 6 pozycji)
Нужно изменить условие сброса current_digit, чтобы мультиплексор доходил до пина P3.5, который включает цветные светодиоды.
```c
SI_INTERRUPT(TIMER3_ISR, TIMER3_IRQn)
{
unsigned char old_SFRPAGE = SFRPAGE;
SFRPAGE = LEGACY_PAGE;
TMR3CN &= 0x7F;
SFRPAGE = CONFIG_PAGE;
LED_DISPLAY_PORT = 0xFF;
LatchDataBusValue(0x00);
LED_DISPLAY_PORT = DisplayPortValue;
// Pobiera dane z tablicy (teraz ma 6 elementów)
LatchDataBusValue(led_display[current_digit]);
DisplayPortValue = (DisplayPortValue << 1) | (DisplayPortValue >> 7);
current_digit++;
// ZMIANA: Mamy 5 wyświetlaczy + 1 pozycję na diody LED (P3.5). Razem 6 pozycji.
if (current_digit >= 6) {
current_digit = 0;
DisplayPortValue = 0xFE;
}
SFRPAGE = old_SFRPAGE;
return;
}
```
### 3. Обработка кнопок в TIMER0_ISR (Логика ввода числа)
Заменяем блок 4. WYNIK в твоем сканере на этот умный алгоритм:
```c
// 4. WYNIK: Wprowadzanie liczby (Zadanie 3)
if (active_r != 0xFF) {
// Reagujemy TYLKO na NOWE wciśnięcie (pomijamy ciągłe trzymanie klawisza)
if (active_r != last_active_r || active_c != last_active_c) {
unsigned char val = key_values[active_r][active_c]; // Pobieramy wartość (0-15)
// Jeśli wciśnięto cyfrę (0-9)
if (val <= 9) {
// Jeśli ekran jest pełny (4 cyfry), czyścimy go przed nowym wpisem
if (digit_count >= 4) {
digit_count = 0;
current_number = 0;
led_display[0] = led_display[1] = led_display[2] = led_display[3] = led_display[4] = 0x00;
led_display[5] = 0x00; // Zgaszenie diody D4
}
// Wyświetl znak na kolejnej pozycji (od lewej)
led_display[digit_count] = key_codes[active_r][active_c];
// Matematyczne budowanie liczby (np. było 1, wciskamy 2 -> 1 * 10 + 2 = 12)
current_number = current_number * 10 + val;
digit_count++; // Przesuwamy wskaźnik na następny wyświetlacz
}
// Jeśli wciśnięto D/Enter (wartość 13)
else if (val == 13) {
saved_number = current_number; // Zapis liczby do pamięci!
// Zapalenie diody D4 (na płytce D4 to zwykle 4. bit, czyli 0x08)
led_display[5] = 0x08;
// Ustawienie digit_count na 4 wymusi czyszczenie przy kolejnej cyfrze
digit_count = 4;
}
// Klawisze A, B, C, E, F (wartości 10-12, 14-15) są ignorowane - nic nie robimy
}
}
// Zapisanie aktualnego stanu, aby w następnym przerwaniu wiedzieć,
// czy to ten sam klawisz, czy nowy
last_active_r = active_r;
last_active_c = active_c;
```
### Как защитить это задание (Словарь и объяснения на польском)
Когда преподаватель будет проверять, покажи ему код и объясни три главных механизма:
1. **Detekcja zbocza (Отсечка удержания):**
> „Zastosowałem zmienne last_active_r i last_active_c do zapamiętywania ostatnio wciśniętego klawisza. Dzięki temu program reaguje tylko na moment wciśnięcia (tzw. detekcja zbocza). Eliminuje to problem wielokrotnego wpisywania tej samej cyfry podczas dłuższego przytrzymania przycisku.”
>
2. **Budowanie liczby dziesiętnej (Сборка числа):**
> „Utworzyłem drugą tablicę key_values, która mapuje współrzędne matrycy na rzeczywiste wartości matematyczne. Algorytm budowania liczby polega na pomnożeniu dotychczasowej wartości przez 10 i dodaniu nowej cyfry (current_number = current_number * 10 + val).”
>
3. **Obsługa Enter (Klawisz D) i Diody LED:**
> „Zgodnie z poleceniem ignoruję klawisze A, B, C, E, F. Po wciśnięciu klawisza **D (Enter)**, aktualna liczba jest przepisywana do zmiennej saved_number. Aby zasygnalizować to zapaleniem diody D4, rozszerzyłem obsługę multipleksowania na 6 pozycji (dodałem wiersz dla P3.5) i wpisuję odpowiedni bit do tablicy led_display[5].”
>