Практическая работа №04 (опрос кнопок) / Valentin Gubarev

Для выполнения практической работы потребуется отладочная плата 1986EvBrd_48_Rev3.

В этой практической работе дан пример реализации опроса кнопок находящихся на отладочной плате. При нажатии на кнопки курсора по экрану в соответствующих направлениях будет перемещаться точка. А также в верхней части экрана организована бегущая строка.

Проект аналогичен тому, что использовался в практической работе №03. Изменился файл main.c и добавились файлы: driver_keyboard.c и driver_keyboard.h.

Файл main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*--------------------------------------------------*/
/* Практическая работа 04 (опрос кнопок)            */
/*--------------------------------------------------*/

#include "structs.h"
#include "driver_lcd.h"
#include "graphics.h"
#include "driver_keyboard.h"

void PortOut(struct_ports * port){
    port->OE      = 0xFF;       /* Выход                */
    port->FUNC    = 0x0000;     /* Порт                 */
    port->DIGITAL = 0xFF;       /* Цифровые             */
    port->PULL    = 0x00000000; /* Подтяжка отключена   */
    port->PD      = 0x00000000; /* Управляемый драйвер  */
    port->PWR     = 0xFFFF;     /* Фронт ~10 нс         */
    port->GFEN    = 0x0000;     /* Фильтрация отключена */
}

static void Delay(unsigned count){
    while(count--);
}

int main (void) {
    /* Включение тактирования порта F */
    *(unsigned *)(0x4002001C) |= (1<<29);
    PortOut(F);
    
    /* Включение тактирования порта D */
    *(unsigned *)(0x4002001C) |= (1<<24);
    PortOut(D);
    
    /* Включение тактирования порта A */
    *(unsigned *)(0x4002001C) |= (1<<21);
    PortOut(A);  
    
    LcdInit();
    LcdDispOn();
    ClearScreen();

    char str[] = "Жмите кнопки - управляйте точкой. Жмите кнопки - управляйте точкой.";
    unsigned pos = 0;
    unsigned cnt = 15;

    unsigned x_cur = 63, y_cur = 31;
    unsigned x_new = 63, y_new = 31;
    PointOn(x_cur,y_cur);
    ScreenUpdate();
   
    KeyboardInit();
    KeyboardPoll();

    while(!ButtonIsPressed(KEY_SELECT)){
        if (ButtonIsPressed(KEY_RIGHT)){
            ++x_new;
        }
        if (ButtonIsPressed(KEY_LEFT )){
            --x_new;
        }
        if (ButtonIsPressed(KEY_UP   )){
            --y_new;
        }
        if (ButtonIsPressed(KEY_DOWN )){
            ++y_new;
        }

        PointOff(x_cur,y_cur);
        x_cur = x_new;
        y_cur = y_new;
        PointOn(x_cur,y_cur);

        if (--cnt == 0) {
            cnt = 15;
            if (str[pos] == 'Ж') pos = 0;
            Print(0,0,str + pos++);
        }

        ScreenUpdate();

        Delay(80000);
        KeyboardPoll();
    }

    Print(7,0,"Жмите кнопку RESET");
    ScreenUpdate();

    return 0;
}

Файл driver_keyboard.h

1
2
3
4
5
6
7
#include "structs.h"

enum key {KEY_SELECT, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT};

void KeyboardInit(void);
void KeyboardPoll(void);
unsigned ButtonIsPressed(enum key k);

Файл driver_keyboard.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "driver_keyboard.h"

static unsigned status_keys[5]; /* Состояние кнопок после последнего опроса */

static void PortIn(struct_ports * port, unsigned mask){
		port->OE     &= ~mask;      /* Вход                 */
		port->FUNC    = 0x0000;     /* Порт                 */
		port->DIGITAL = 0xFF;       /* Цифровые             */
		port->PULL    = 0x00000000; /* Подтяжка отключена   */
		port->PD      = 0x00000000; /* Управляемый драйвер  */
		port->PWR     = 0xFFFF;     /* Фронт ~10 нс         */
		port->GFEN    = 0x0000;     /* Фильтрация отключена */
}

void KeyboardInit(void){
    /* Включение тактирования порта C */
    *(unsigned *)(0x4002001C) |= (1<<23);
    PortIn(C,(1<<1));

    /* Включение тактирования порта D */
    *(unsigned *)(0x4002001C) |= (1<<24);
    PortIn(D,(1<<0) | (1<<1));

    /* Включение тактирования порта E */
    *(unsigned *)(0x4002001C) |= (1<<25);
    PortIn(E,(1<<3) | (1<<6));
}

void KeyboardPoll(void){
    status_keys [KEY_SELECT] = !(C->RXTX & (1<<0)); /* KEY_SELECT - PC0 */
    status_keys [KEY_UP    ] = !(D->RXTX & (1<<0)); /* KEY_UP     - PD0 */
    status_keys [KEY_DOWN  ] = !(D->RXTX & (1<<1)); /* KEY_DOWN   - PD1 */
    status_keys [KEY_LEFT  ] = !(E->RXTX & (1<<3)); /* KEY_LEFT   - PE3 */
    status_keys [KEY_RIGHT ] = !(E->RXTX & (1<<6)); /* KEY_RIGHT  - PE6 */
}

unsigned ButtonIsPressed(enum key k){
    return status_keys[k];
}

Задания для самостоятельного выполнения

  1. Измените код программы так, чтобы при нажатиях на кнопки перемещался квадрат 4 на 4 пикселя с шагом 4 пикселя.
  2. Допишите программу так, чтобы квадрат нельзя было переместить за пределы экрана.
  3. Измените программу так, чтобы квадрат при перемещении его за пределы экрана тут же появлялся с противоположной стороны.
  4. Измените программу так, чтобы пользователь используя курсор управлял местом размещения бегущей строкой и её направлением движения.
  5. Нарисуйте окружность с центром в середине экрана и радиусом в 20 пикселей. Напишите программу так, чтобы пользователь, перемещая точку не мог выйти за предела круга, ограниченного окружностью.
  6. Организуйте меню с 3-мя пунктами: 1. Нарисовать треугольник. 2. Нарисовать круг. 3. Нарисовать прямоугольник. При выборе пункта (нажатие центральной кнопки курсора) на экране должна появиться соответствующуя геометрическая фигура.
Лицензия Creative Commons
Code More Team - GitHub