Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт
Шрифт:
Интервал:
Закладка:
Рис. 7.37. Блок-диаграмма микропроцессорной системы для игры в «15»
7.7.4. Схемное решение, структура программы и блок-схема алгоритма
На рис. 7.38 показана структура микроконтроллерной системы для игры в «15». Встроенные порты отладочной платы 68HC912B32EVB используются, чтобы получать и послать данные от вспомогательной клавиатуры и модуля ЖК-дисплея. Принципиальная схема этой системы с расширением памяти приведена на рис. 7.39.
Рис. 7.38. Структура микропроцессорной системы для игры в «15»
Рис. 7.39. Принципиальная схема системы для игры в «15»
На рис. 7.40 показана структура программы для игры в «15», в которой главная программа обращается к шести субмодулям. На рисунке показан также ряд функций, выполняемых каждым субмодулем. Соответствующая блок схема алгоритма приведена на рис. 7.41.
Рис. 7.40. Структура программы для игры в «15»
Рис. 7.41. Блок схема алгоритма программы для игры в «15»
7.7.5. О компонентах системы
Интеллектуальный точечный графический дисплей AND 1391 — это полная точечная матрица ЖКД со встроенным модулем контроллера дисплея и ОЗУ буфера экрана. Он может выводить 21 символ на каждой из 18 строк дисплея. Вы можете прочесть об этом дисплее и функциях его обеспечения в главе 5.
7.7.6. Программный код
//Имя файла: sliding.с
//Программа: Игра в "15"
//Авторы: Scott Lewis, Daniel Pack,
//Дата создания: Начата 27 апреля 2004
//окончена 7 Мая 2004
// Описание: Эта программа реализует игру в "15". Цель игры
// заключается в том, чтобы выстроить фишки по по ряду номеров. Вы
// можете только перемещать на пустое место любую соседнюю фишку.
// Программа постоянно находится в памяти системы по адресу
// $2000. Программа отображает исходное состояние фишек, затем
// показывает состояние к которому необходимо прийти в
// результате. Программа размещает все фишки в случайном
// порядке, и затем позволяет пользователю начать игру
// Конфигурация системы
// Программа: 0x2000
// Данные: 0x3500
// Стек: 0x4000
//
// PDLC0: /WR PP0 Data 0 PS0: Не используется
// PDLC1: /RD PP1 Data 1 PS1: Не используется
// PDLC2: /CE PP2 Data 2 PS2: Кнопка "Влево"
// PDLC3: C/D PP3 Data 3 PS3: Кнопка "Выбор"
// PDLC4: /Reset PP4 Data 4 PS4: Кнопка "Вниз"
// PDLC5: NC PP5 Data 5 PS5: Кнопка "Вправо"
// PDLC6: NC PP6 Data 6 PS6: Кнопка "Вверх"
// PDLC1: NC PP7 Data 7 PS7: Не используется
//
// Выводы ЖКД
// GND - 2 1 - GND
// -14V - 3 4 - +5V
// /WR - 5 6 - /RD
// /CE - 7 8 - C/D
// NC - 9 10 - /Reset
// DO - 11 12 - D1
// D2 - 13 14 - D3
// D4 - 15 16 - D5
// D6 - 17 18 - D7
// GND - 19 20 - NC
//******************************************************
#include <912b32.h> // описание портов - header file
// приведен в приложении
//********************************************************************
// Постоянные
//********************************************************************
#define ARRAY_MAX 15
#define ZERO 0x00
#define L_BUTTON 0x04 // сигналы кнопок
#define R_BUTTON 0x20
#define U_BUTTON 0x40
#define D_BUTTON 0x10
#define S BUTTON 0x08
#define LEFT 1 // выбор направления
#define RIGHT 2
#define UP 3
#define DOWN 4
#define SELECT 5
#define SIZE 4 // Размер строки/колонки
//********************************************************************
// Используемые функции
//********************************************************************
int check_win(int array[ARRAY_MAX+1]);
void convert_multi_single(int A[SIZE][SIZE], int В[SIZE][SIZE]);
void convert_single_multi(int A[ARRAY_MAX+1], int В[SIZE][SIZE]);
void display_board(int A[SIZE][SIZE], int row, int col, int direction);
void display_board2(int board_array[ARRAY_MAX+1]);
void display_error(int n);
void display_intro(void);
void display_win(void);
void get_move(int *direction, int *row, int *col, int *select);
void randomize_board(int board_array[]);
void swap(int row, int col, int new_row, int new_col, int array[SIZE][SIZE]);
void swap2(int from, int to, int array[ARRAY_MAX+1]);
void try_move(int move, int row, int col, int array[SIZE][SIZE]);
unsigned char mode(unsigned char num, int modulus);
void LCD_output(char s[]);
void int2char(int i);
void pause(void);
void delay(int usec);
void enable(void);
void initialize_LCD(void);
void command(unsigned char n);
void data(unsigned char n);
void write(void);
void read(void);
void status_wait(void);
void LCD_char(unsigned char n);
void Clearscreen(void);
void newline(void);
void Reset_cursor(void);
//*****************************************************************
//Переменные
//*****************************************************************
#pragma abs_address 0x3600
static int win_array[ARRAY_MAX+1]
= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
#pragma end_abs_address
#pragma abs_address 0x3500
int board_array_single [ARRAY_MAX+1];
int board_array_multi[SIZE][SIZE];
int win; //использовать как булевы переменные
int direction; //направление движения
int row; //выделить ряд
int col; //выделить колонку
int select; //если кнопка нажата
int i; //текущая переменная
#pragma end_abs_address
//*****************************************************************
// Основная программа
//*****************************************************************
void main() {
win = 0; //инициализировать все переменные
direction = 0;
row = 1;
col = 1;
select = 0;
i = 0;
DDRDLC = 0x1F; //конфигурировать порт DDRDLC как выходной
DDRP = 0xFF; // конфигурировать линии порта P как выходные
DDRS = 0x00; // конфигурировать линии порта S как входные
TSCR = 0x80; //включить таймер
initialize_LCD(); //инициализировать ЖКД
Clearscreen();
Reset_cursor();
display_intro();
for (i=0; i < ARRAY_MAX+1; i++) board_array_single[i] = win_array[i];
convert_single_multi(board_array_single, board_array_multi);
display_board(board_array_multi, row, col, direction);
pause(); // ожидание, пока пользователь не нажмет кнопку X
LCD_output("Now the board is"); // вывод сообщения
LCD_output("randomized. You ");
LCD_output("may begin by ");
LCD_output("choosing a piece");
LCD_output("to move, and its");
LCD_output("direction. ");
newline();
pause();
randomize_board(board_array_single); // Случайный выбор исходного
// положения фишек
convert_single_multi(board_array_single, board_array_multi);
display_board(board_array_multi, row, col, direction);
while(win == 0){ //цикл повторяется до успешного окончания игры
while (select == 0) {
//если была нажата кнопка x, то задается направ-
// ление движения ряд и колонка выделенной фишки
get_move(&direction, &row, &col, &select);
Reset_cursor(); // установить курсор в верхнее положение
if (select == 0)
display_board(board_array_multi, row, col, direction);
}
//проверить корректность движения, повторить его, если
// оно некорректно, или вывести сообщение об ошибке
try_move(direction, row-1, col-1, board_array_multi);
select = 0;
convert_multi_single(board_array_multi, board_array_single);
win = check_win(board_array_single);
Clearscreen();
// показать текущее состояние игры
display_board(board_array_multi, row, col, direction);
}
display_win(); // вывести сообщение об успешном окончании игры
}
//*****************************************************************
// display_intro: DISPLAY INTRO MESSAGE
//*****************************************************************
void display_intro {
newline();
LCD_output(" WELCOME ");
LCD_output(" TO ");
LCD_output(" SLIDING PUZZLE ");
new_line();
pause();
LCD_output("The object of ");
LCD_output("this game is to ");
LCD_output("move each #'ed ");
LCD_output("puzzle piece so ");
LCD_output("that you end up ");
LCD_output("in the order ");
LCD_output("seen below. The ");
LCD_output("star shows the ");
LCD_output("current piece ");
LCD_output("selected. You ");
LCD_output("can choose a ");
LCD_output("different piece ");
LCD_output(" by using the ");
LCD_output(" arrow buttons ");