Для выполнения практической работы потребуется отладочная плата 1986EvBrd_48_Rev3.
В этой практической работе дан пример реализации вывода на дисплей графических примитивов: точка, прямоугольник, окружность.
Проект аналогичен тому, что использовался в практической работе №02. Изменились файлы: graphics.h, graphics.c, main.c.
1
2
3
4
5
6
7
8
9
10
#include "structs.h"
#include "driver_lcd.h"
#include "font_ansi_5x8.h"
void Print(unsigned row, unsigned col, char * byte);
void PointOn (int x, int y);
void PointOff(int x, int y);
void RectangleOn(int x1, int y1, int x2, int y2);
void ClearScreen(void);
void ScreenUpdate(void);
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
/*-------------------------------------------------------*/
/* Практическая работа 03 (вывод графических примитивов) */
/*-------------------------------------------------------*/
#include "structs.h"
#include "driver_lcd.h"
#include "graphics.h"
#include "math.h" /* Для применения функции sqrt - корень квадратный */
/* Позже будет реализация без вычисления квадратного корня */
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();
PointOn(15,22);
PointOn(10,30);
PointOn(20,30);
RectangleOn(40,10,115,40);
RectangleOn(45,15,110,35);
/* Пример реализации окружности */
int radius = 24;
int x_center = 50;
int y_center = 30;
PointOn(x_center,y_center);
for(int delta_1 = 0; delta_1 <= sqrt(radius*radius - delta_1*delta_1); ++delta_1){
int delta_2 = sqrt(radius*radius - delta_1*delta_1);
PointOn(x_center+delta_1,y_center+delta_2);
PointOn(x_center+delta_2,y_center+delta_1);
PointOn(x_center-delta_1,y_center+delta_2);
PointOn(x_center-delta_2,y_center+delta_1);
PointOn(x_center+delta_1,y_center-delta_2);
PointOn(x_center+delta_2,y_center-delta_1);
PointOn(x_center-delta_1,y_center-delta_2);
PointOn(x_center-delta_2,y_center-delta_1);
}
ScreenUpdate();
return 0;
}
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
#include "graphics.h"
/* Флаг, есть ли что выводить на экран */
static unsigned char grafic_out = 1;
/* Буфер для хранения графической информации */
/* Доступ к памяти дисплея намного медленнее */
static unsigned char screen[8][128];
/* Очистка буфера экрана */
void ClearScreen(void){
grafic_out = 1;
for(unsigned i = 0; i < sizeof(screen); ++i)
screen[0][i] = 0x00;
}
/* Печать нуль терминированной строки в позицию (row, col) */
void Print(unsigned row, unsigned col, char * byte){
grafic_out = 1;
if (row > 7) return;
while(*byte){
for(unsigned i = 0; i < 5 && col < 128; ++i)
screen[row][col++] = ansi[*byte][i];
if (col < 128)
screen[row][col++] = 0x00;
++byte;
}
}
/* Изображение точки в буфере */
void PointOn(int x, int y){
if (x >= 0 && x < 128 && y >= 0 && y < 64)
screen[y>>3][x] |= (1<<(y&0x7));
}
/* Стирание точки в буфере */
void PointOff(int x, int y){
if (x >= 0 && x < 128 && y >= 0 && y < 64)
screen[y>>3][x] &= ~(1<<(y&0x7));
}
/* Изображение прямоугольника, заданного координатами его противоположных вершин */
void RectangleOn(int x1, int y1, int x2, int y2){
int x_start = x1<x2? x1:x2;
int y_start = y1<y2? y1:y2;
int x_finish = x1>x2? x1:x2;
int y_finish = y1>y2? y1:y2;
for(int x_current = x_start; x_current <= x_finish; ++x_current){
PointOn(x_current,y_start);
PointOn(x_current,y_finish);
}
for(int y_current = y_start; y_current <= y_finish; ++y_current){
PointOn(x_start,y_current);
PointOn(x_finish,y_current);
}
}
/* Вывод изображения, если были изменения */
void ScreenUpdate(void){
if (grafic_out){
grafic_out = 0;
LcdScreen(screen);
}
}