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 ");
newline();
pause();
LCD_output("and select the ");
LCD_output("piece you want ");
LCD_output("to move by ");
LCD_output("pressing the X ");
// кнопка "Выбор"
LCD_output("button. Choose ");
LCD_output("the direction to ");
LCD_output("move that piece ");
LCD_output("with the arrows. ");
new_line();
LCD_output("WINDING ");
LCD_output("CONFIGURATION: ");
newline();
}
//*****************************************************************
// display_win: ВЫВОД СООБЩЕНИЯ О ПОБЕДЕ
//*****************************************************************
void display_win() {
LCD_output(" YOU WIN!!! ");
LCD_output("CONGRATULATIONS ");
}
//********************************************************************
// get_move: ДВИЖЕНИЕ ФИШКИ: задается позиция фишки, выбранной игро-
// ком и направление ее движения
//********************************************************************
void get_move(int* direction, int *row, int *col, int* select) {
int n = 0;
int button = 0;
unsigned char temp = ZERO;
newline();
LCD_output("Choose move or ");
LCD_output("select piece: ");
while (button == 0) {
// цикл выполняется, пока нажата кнопка
temp = PORTS;
temp = temp & 0x7С
switch (temp) //какая кнопка нажата?
{
case L_BUTTON:
button = LEFT;
break;
case R_BUTTON:
button = RIGHT;
break;
case U_BUTTON:
button = UP;
break;
case D_BUTTON:
button = DOWN;
break;
case S_BUTTON:
button = SELECT;
break;
} // конец цикла switch
}//конец цикла while
n = 0;
switch (button) //реакция на нажатие кнопки
{
case UP:
if (*row > 1) *row -= 1;
else display_error(UP);
break;
case DOWN:
if (*row < SIZE) *row += 1;
else display_error(DOWN);
break;
case LEFT:
if (*col > 1) *col -= 1;
else display_error(LEFT);
break;
case RIGHT:
if (*col < SIZE) *col += 1
else display_error(RIGHT);
break;
case SELECT:
*select = 1;
LCD_output("Pick a direction");
*direction = 0;
while (*direction == 0) {
temp = PORTS;
temp = temp & 0x7C;
switch (temp) {
case L_BUTTON:
*direction = LEFT;
break;
case R_BUTTON:
*direction = RIGHT;
break;
case U_BUTTON:
*direction = UP;
break;
case D_BUTTON:
*direction = DOWN;
break;
}
}
break;
}
}
//********************************************************************
// randomize_board: ВЫБОР СЛУЧАЙНОГО ИСХОДНОГО СОСТОЯНИЯ ФИШЕК
//********************************************************************
void randomize_board(int board_array[]) {
int temp = 0;
int i;
unsigned char temp2 = 0x00;
for (i=0; i<ARRAY_MAX+1; i++) {
temp2 = TCNTL;
temp = mod(temp2,15); //случайное значение using the TCNT counter
swap2(i,temp, board_array);
}
}
//********************************************************************
// MOD: МАТЕМАТИЧЕСКАЯ ФУНКЦИЯ
//********************************************************************
unsigned char mod(unsigned char num, int modulus) {
while ((num - modulus) > 0) num = num - modulus;
return num;
}
//********************************************************************
// display_board2: Выводит табло, как одну колонку значений
//********************************************************************
void display_board2(int board_array[ARRAY_MAX+1]) {
int = 0;
int n;
for (i=0; i<ARRAY_MAX+1; i++) {
n = board_array[i];
int2char(n);
}
LCD_output("\n");
}
//********************************************************************
// display_board: Выводит табло как массив 4×4
//********************************************************************
void display_board(int A[SIZE][SIZE], int row, int col, int direction) {
#pragma abs_address 0x0800
int i;
int j;
int num;
#pragma end_abs_address
newline();
LCD_output("| Column ");
LCD_output("| 1 2 3 4 ");
LCD_output("-------------------");
for (i=0; i < SIZE; i++) {
j=0;
switch(i) {
case 0:
LCD_output("R 1 |");
break;
case 1:
LCD_output("o 2 |");
break;
case 2:
LCD_output("w 3 |");
break;
case 3:
LCD_output(" 4 |");
break;
}
for (j=0; j < SIZE; j++) {
num = A[i][j];
if (num == 0) LCD_output(" ");
else int2char(num);
if ((i+1 == row) && (j+1) == col))
LCD_output("*");
else LCD_output(" ");
}
}
newline();
LCD_output("You are at (R,C)");
LCD_output(" (");
int2char(row);
LCD_output(",");
int2char(col);
LCD_output(") =");
int2char(A[row-1];
LCD_output(" ");
newline();
}
//********************************************************************
// INT2CHAR: задается как integer и выводится на ЖКД в виде
// двух символов
//********************************************************************
void int2char(int i) {
if (i > 9) {
LCD_output("I");
i -= 10;
} else {
LCD_output('; ");
}
switch(i) {
case 0:
LCD_output("0");
break;
case 1:
LCD_output("1");
break;
case 2:
LCD_output("2");
break;
case 3:
LCD_output("3");
break;
case 4:
LCD_output("4");
break;
case 5:
LCD_output("5");
break;
case 6:
LCD_output("6");
break;
case 7:
LCD_output("7");
break;
case 8:
LCD_output("8");
break;
case 9:
LCD_output("9");
break;
}
}
//********************************************************************
//Check_Win: Эта функция проверяет соответствие текущего положения ситуации
// победы при победе win - 1, в остальных случаях - 0
//********************************************************************
int check_win(int array[ARRAY_MAX+1]) {
int i;
int win = 1;
for (i=0; i<ARRAY_MAX+1; i++) {
if (array[i] != win_array[i]) win = 0;
}
return win;
}
//********************************************************************
//Convert_multi_single: Эта функция преобразует двухмерный массив
//в одномерный
//********************************************************************
int convert_multi_single(int A[SIZE][SIZE], int В[ARRAY_MAX+1]) {
int n = 0;
int i = 0;
int j = 0;
for (i=0; i<SIZE; i++) {
for (j=0; j<SIZE; j++) {
B[n] = A[i][j] ;
n++;
}
}
}
//****************************************************************
//Convert_single_multi: Эта функция преобразует одномерный массив
//в двухмерный
//****************************************************************
void convert_single_multitint A[ARRAY_MAX+1], int В[SIZE][SIZE]) {
B[0][0] = A[0];
B[0][1] = A[1];
B[0][2] = A[2];
B[0][3] = A[3];
B[1][0] = A[4];
B[1][1] = A[5];
B[1][2] = A[6];
B[1][3] = A[7];
B[2][0] = A[8];
B[2][1] = A[9];
B[2][2] = A[10];
B[2][3] = A[11];
B[3][0] = A[13];
B[3][2] = A[14];
B[3][3] = A[15];
}
//********************************************************************
// Try_move: Эта функция позволяет игроку определить некорректность
// своего хода. Если он корректен, то движение выполняется,
// если же некорректен, то выводится соответствующее сообщение
//********************************************************************
void try_move(int move, int row, int col, int array[SIZE][SIZE]) {
switch(move) {
case UP:
if ((row-1 >=0) && (array[row-1][col] == 0))
swap(row, col, row-1, col, array);
else display_error(UP);
break;
case DOWN:
if ((row+1 <= SIZE) && (array[row+1][col] == 0))
swap(row, col, row+1, col, array);
else display_error(DOWN);
break;
case LEFT:
if ((col-1 >=0) && (array[row][col-1] == 0))
swap(row, col, row, col-1, array);
else display_error(LEFT);
break;
case RIGHT:
if ((col+1 < = SIZE) && (array[row][col+1] == 0))
swap(row, col, row, col+1, array);
else display_error(RIGHT);
break;
}
}
//********************************************************************
//********************************************************************
//Swap: Эта функция заменяет два значения двухмерным массивом.
//********************************************************************
void swap(int row, int col, int new_row, int new_col, int array[SIZE][SIZE]) {
int temp;
temp = array[row][col];
array[row][col] = array[new_row][new_col];
array[new_row][new_col] = temp;
}
//********************************************************************
//Swap2: Эта функция заменяет два значения одномерным массивом.
//********************************************************************
void swap2(int from, int to, int array[ARRAY_MAX+1]) {
int temp = array[from];
array[from] = array[to];
array[to] - temp;
}
//********************************************************************
//ERROR: Эта функция выводит сообщения об ошибке
//********************************************************************
void display_error(int n) {
LCD_Output("ERROR: ");
switch(n) {
case LEFT:
LCD_output("no move L");
break;
case RIGHT:
LCD_output("no move R");
break;
case UP:
LCD_output("no move U");
break;
case DOWN:
LCD_output("no move D");
break;
}
pause();
}
//********************************************************************
//********************************************************************
//LCD_output: Эта функция выводит на дисплей строку
//********************************************************************
void LCD_output(char s[]) {
int n = 0;
while (s[n] != '\0') {
LCD_char(s[n]);
++n;
}
}
//********************************************************************
//Pause: Функция реализует ожидание, пока игрок не нажмет кнопку
// "Выбор"
//********************************************************************
void pause() {
unsigned char с = ZERO;
LCD_output("(Please press X)");
while (c != S_BUTTON) {
c = PORTS;
с = c & 0x7C;
}
Clearscreen();
Reset_cursor();
}
//********************************************************************
//Delay: Эта функция вводит задержку на n мкс, если входная
// величина равна n
//********************************************************************
void delay(int usec) {
int i,j;
for (i=0;i<usec; i++) {
for (j=0; j < 7; j++) {}
}
}
//********************************************************************
//Initialize_LCD: Функция инициализирует ЖКД
//********************************************************************
void initialize_LCD(void) {
char temp = 0x00;
PORTDLC = 0xFF;
PORTDLC = PORTDLC & 0xEF; // сброс экрана (RESET = 0)
delay(2000); // задержка в 2 мс
PORTDLC = 0x7F; // выключение сброса
write(); //включение записи
command(0x80);
//установка текстового режима
data(0x0); //проверка установки слова
data(0x10);
command(0x40);
data(0x10); // устанавливается размер области текста (1E)
data(0x00); // - 0x1000
command(0x41);
//включается дисплей текста, курсор, выключается мигание
command(0x94);
command(0xA7); //курсор 8×8 точек
}
//********************************************************************
//Enable: Функция разрешает работу ИС
//********************************************************************
void enable(void) {
PORTDLC = PORTDLC | 0x04; // Установить 1 на линии enable
PORTDLC = PORTDLC & 0xFB; // Установить 0 на линии enable
}
//********************************************************************
//Disable: Функция запрещает работу ИС
//********************************************************************
void disable(void) {
PORTDLC = PORTDLC | 0x04;
}
//********************************************************************
//Command: Функция посылает команду отключения на ЖКД
//********************************************************************
void command(unsigned char n) {
status_wait();
PORTP = n;
PORTDLC = 0xFF;
PORTDLC = PORTDLC & 0xFE; // сброс записи
enable(); // сброс флага CE
delay(10); // задержка не менее 80 нс
disable(); // включение флага CE
}
//********************************************************************
//Data: Функция пересылает данные на ЖКД
//********************************************************************
void data(unsigned char n) {
status_wait();
PORTP = n;
PORTDLC = 0xFF;
PORTDLC = PORTDLC & 0xF7; // перевести C/D на низкий уровень
PORTDLC = PORTDLC & 0xFE; // перевести WR на низкий уровень
PORTDLC = PORTDLC & 0xFB;
delay(10);
disable();
}
//********************************************************************
//Write: Функция конфигурирует порт P как выходной
//********************************************************************
void write() {
DDRP = 0xFF;
}
//********************************************************************
//Read: Функция конфигурирует порт P как входной
//********************************************************************
void read() {
DDRP = 0x00;
}
//********************************************************************
//Status_wait: Создает соответствующие задержки между командами ЖКД
//********************************************************************
void status_wait() {
char temp = 0x00;
DDRP = 0x00;
PORTDLC = PORTDLC | 0x0F; // сбросить все
PORTDLC = PORTDLC & 0xFD; // сброс флага RD
enable();
delay(10);
while ((temp & 0x03) != 0x03) {
temp = PORTP;
}
disable();
DDRP = 0xFF;
}
//********************************************************************
//LCD_char: Функция выводит ASCII код на экран ЖКД
//********************************************************************
void LCD_char(unsigned char n) {
data(n-0x20);
command(0xC0);
}
//********************************************************************
//Clearscreen: Функция очищает экран ЖКД
//********************************************************************
void Clearscreen() {
int i,j;
Reset_cursor();
for (i=0; i < 16; i++) for (j=0; j<16; j++) LCD_char(' ');
Reset_cursor();
}
//********************************************************************
//Newline: Функция выводит пустую строку на экран ЖКД
//********************************************************************
void newline() {
int i;
for (i=0; i < 16; i++)
LCD_char(' ');
}
//********************************************************************
//Reset_cursor: Функция возвращает курсор ЖКД в начальную позицию
//********************************************************************
void Reset_cursor() {
data(0x00);
data(0x10);
command(0x24);
}
//********************************************************************
- Встраиваемые системы Проектирование приложений на микроконтроллерах семейства 68hc12/hcs12 с применением языка с с. Ф. Баррет
- Предисловие
- Структура книги
- Учебные системы
- Целевая аудитория
- Благодарности
- Глава 1 первое знакомство со встраиваемыми системами
- 1.1. Что такое встраиваемая система?
- 1.2. Особенности встраиваемых систем
- 1.2.1. Работа в реальном времени
- 1.2.2. Миниатюризация размеров и процесс тестирования
- 1.2.3. Минимизация энергии потребления
- 1.2.4. Интерфейс пользователя и интерфейс сопряжения с объектом
- 1.2.5. Многозадачность
- 1.2.6. Минимизация стоимости
- 1.2.7. Ограничение объема памяти
- 1.2.8. Программно–аппаратный дуализм
- 1.3. Введение в микроконтроллеры семейства 68hc12 и hcs12
- 1.4 Микроконтроллеры hcs12
- 1.4.1. Семейство hcs12
- 1.4.2. Обозначения мк
- 1.4.3. Модельный ряд hcs12
- 1.5. Заключение по главе 1
- 1.6. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 2 программирование встраиваемых систем и структурное проектирование
- 2.1. Почему мы программируем микроконтроллеры на Си?
- 2.2. Преимущества программирования на языке ассемблер
- 2.3. Преимущества языков высокого уровня
- 2.3.1. Выбираем язык высокого уровня для программирования встраиваемых систем
- 2.3.2. Краткая история языка Си
- 2.4. Оптимальная стратегия — программирование на Си и на ассемблере
- 2.5. Структурное проектирование
- 2.5.1. Основные положения метода структурного проектирования
- 2.5.2. Документирование программ
- 2.5.3. Как язык Си соотносится со структурным проектированием
- 2.6. Рабочие тетради
- 2.6.1. Порядок ведения записей
- 2.6.2. Содержание записей
- 2.7. Блок схемы алгоритмов
- 2.8. Пример применения
- 2.9. Заключение по главе 2
- 2.10 Что еще почитать?
- 2.11 Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 3 основы программирования микроконтроллеров на си
- 3.1. Введение в программирование на Си
- 3.1.1. Глобальные и локальные переменные
- 3.2. Типы данных в Си
- 3.3. Операторы языка Си
- 3.4. Функции
- 3.4.1. Что такое функция?
- 3.4.2. Основная программа
- 3.4.3. Прототипы функций
- 3.4.4. Описание функций
- 3.4.5. Вызов функций, передача параметров, возврат полученных значений
- 3.5. Файлы заголовков
- 3.6. Директивы компилятора
- 3.6.1. Директивы условной компиляции
- 3.7. Конструкции программирования
- 3.8. Операторы для организации программных циклов
- 3.8.1. Оператор for
- 3.8.2. Оператор while
- 3.8.3. Оператор do-while
- 3.9. Операторы принятия решения
- 3.9.1. Оператор if
- 3.9.2. Оператор if-else
- 3.9.3. Оператор if-else if-else
- 3.9.4. Оператор switch
- 3.10. Массивы
- 3.11. Указатели
- 3.12. Структуры
- 3.13. Процесс программирования и отладки микропроцессорной системы
- 3.13.1. Технология создания программного кода
- 3.13.2. Режим отладки bdm
- 3.13.3. Аппаратные и программные средства отладчика p&e от компании pemicro
- 3.13.4. Эмуляторы
- 3.13.5. Логические анализаторы
- 3.14. Особенности компилятора и ассемблера
- 3.15. Заключение по главе 3
- 3.16. Что еще почитать?
- 3.17. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 4 микроконтроллеры 68hc12 и hcs12: архитектура и программирование
- 4.1. Аппаратные средства микроконтроллеров семейства 68hc12
- 4.2. Аппаратные средства мк семейства hcs12
- 4.3. Режимы работы мк семейства 68hc12/hcs12
- 4.3.1. Рабочие режимы
- 4.3.2. Режимы работы отладочной платы m68evb912b32
- 4.4. Назначение выводов мк
- 4.5. Регистры специальных функций мк
- 4.5.1. Виртуальный адрес блока регистров
- 4.6. Порты ввода/вывода
- 4.6.1. Спецификация портов ввода/вывода
- Регистры управления портами
- Вопросы для самопроверки
- Пример применения
- 4.7. Подсистема памяти мк b32
- Пример применения
- 4.7.1. Карта памяти мк b32
- 4.7.2. Изменение адресов в карте памяти мк
- 4.8. Подсистема памяти мк dp256
- Вопросы для самопроверки
- 4.9. Состояния сброса и прерывания мк
- 4.9.1. Реакция мк на внешние события
- 4.10. Состояния сброса и прерывания в мк 68hc12
- 4.10.1. Состояние сброса мк
- Регистры сторожевого таймера и монитора тактирования
- 4.10.2. Прерывания
- Немаскируемые прерывания
- Маскируемые прерывания
- Вопросы для самопроверки
- 3. Каково различие между прерываниями по входам
- 4. Как организовать подсистему прерывания с несколькими внешними запросами для мк семейства 68hc12/hcs12, используя лишь один вход внешнего прерывания
- 4.10.3. Вектора исключений
- 4.10.4. Система приоритетов для исключений
- 1. Внешний сброс по входу
- 5. Немаскируемое прерывание по входу
- Вопросы для самопроверки
- 4. Какие действия должен предпринять программист, чтобы после начального запуска мк присвоить входу
- 4.10.5. Регистры подсистемы прерывания
- 4.11. Процесс перехода к подпрограмме прерывания
- Вопросы для самопроверки
- 4.12. Оформление подпрограммы прерывания на Си
- 4.13. Система тактирования
- 4.13.1.Система тактирования отладочной платы mc68hc912b32evb
- 4.14. Подсистема реального времени — модуль таймера
- 4.14.1. Структура модуля таймера
- 4.14.2. Счетчик временной базы
- Особенности счетчика временной базы
- Флаг переполнения счетчика
- Определение длительности временных интервалов
- Сброс счетчика временной базы
- Вопросы для самопроверки
- 4.14.3. Регистры для управления счетчиком временной базы
- Регистр управления модулем таймера
- Регистр счетчика временной базы
- Регистр масок таймера 2
- 4.14.4. Каналы захвата/сравнения
- Режим входного захвата
- Вопросы для самопроверки
- Режим выходного сравнения
- Канал 7 в режиме выходного сравнения
- Регистры для управления каналами захвата/сравнения
- Регистры управления таймером 3 и 4
- Регистр масок таймера 1
- Регистр масок таймера 2
- Регистр флагов таймера 1
- Регистр флагов таймера 2
- Регистры данных каналов захвата/сравнения
- Вопросы для самопроверки
- Примеры работы с таймером
- Измерение частоты и периода логического сигнала
- Генерация импульсной последовательности
- Генерация импульсной последовательности с использованием прерывания
- 4.14.5. Счетчик событий
- Режимы работы счетчика
- Регистры управления счетчиком событий
- Регистр управления счетчиком событий
- Регистр флагов счетчика событий
- Регистр текущего состояния счетчика событий
- Пример использования счетчика событий
- 4.15. Модуль меток реального времени
- Пример использования модуля меток реального времени
- 4.16. Модуль таймера ect в составе мк мc68hc12be32 и hcs12
- 4.16.1. Небуферированные каналы входного захвата
- 4.16.2. Буферированные каналы входного захвата
- 4.16.3. Особенности счетчиков событий
- 4.16.4. Регистры управления модуля est
- Регистр управления порядком перезаписи
- Регистр управления режимом входного захвата
- Регистр управления счетчиком задержки
- Регистр управления 16-разрядным вычитающим счетчиком
- Регистр коэффициента счета вычитающего счетчика
- Регистр флагов вычитающего счетчика
- 4.17. Обмен информацией в последовательном коде: многофункциональный последовательный интерфейс
- 4.17.1. Термины последовательного обмена
- Вопросы для самопроверки
- 4.18. Контроллер асинхронного обмена sci
- Вопросы для самопроверки
- 4.18.1. Передатчик контроллера sci
- 4.18.2. Приемник контроллера sci
- 4.18.3. Регистры контроллера sci
- Регистры скорости обмена sCxBdh и sCxBdl
- Регистры управления sCxCr1 и sCxCr2
- Регистры состояния sCxSr1 и sCxSr2
- Регистры данных sCxDrh и sCxDrl
- Вопросы для самопроверки
- 4.18.4. Алгоритмы программного обслуживания контроллера sci
- 4.18.5. Пример программирования контроллера sci
- 4.19. Синхронный последовательный интерфейс spi
- 4.19.1 Концепция интерфейса spiФункциональная схема обмена между двумя контроллерами spi
- 4.19.2. Алгоритмы работы контроллера spi
- Вопросы для самопроверки
- 4.19.3. Регистры контроллера spi
- Регистр скорости обмена sPxBr
- Регистры управления sPxCr1 и sPxCr2
- Регистр данных spCxDr
- Регистр данных порта s
- Регистр направления передачи порта s
- Вопросы для самопроверки
- 4.19.4. Алгоритмы программного обслуживания контроллера spi
- 4.19.5 Периферийные ис с интерфейсом spi
- 4.20. Введение в теорию аналого-цифрового преобразования
- 4.20.1. Частота дискретизации сигнала
- 4.20.2. Представление аналоговой величины в цифровом коде
- 4.20.3.Квантование по уровню и разрешающая способность
- 4.20.4 Скорость потока данных оцифровки
- Вопросы для самопроверки
- 4.21. Принцип действия ацп
- 4.21.1. Ацп последовательного приближения
- Вопросы для самопроверки
- 4.22. Подсистема аналого-цифрового преобразования мк 68hc12
- 4.22.1 Структура и порядок функционирования
- 4.22.2. Регистры управления модуля atd
- Группа регистров управления
- Регистры управления atdctl0 и atdctl1
- Регистр управления atdctl2
- Регистр управления atdctl3
- Регистр управления atdctl4Формат регистра atdctl4
- Регистр управления atdctl5
- Вопросы для самопроверки
- Регистр состояния atdstat
- Регистр данных порта portad
- Регистры результата adr0h…adr7h
- Вопросы для самопроверки
- Тестовый регистр atdtest
- 4.22.3. Пример программирования модуля atd
- Цифровой вольтметр
- 4.22.4. Обслуживание прерываний от модуля atd
- 4.23. Особенности модуля atd в составе мк семейства hcs12
- 4.23.1. Выбор разрядности ацп
- 4.23.2. Представление результата измерения
- 4.23.3. Запуск измерительной последовательности от внешнего сигнала
- 4.23.4. Программируемое число преобразований в измерительной последовательности
- 4.23.5. Увеличение числа аналоговых входов
- 4.23.6. Регистры модуля atd hcs12
- Регистр состояния atdstat0
- Регистр состояния atdstat1
- Регистр разрешения цифрового входа порта atddien
- 4.24. Подсистема широтно-импульсной модуляции
- 4.24.1. Структура модуля pwm
- 4.24.2. Режимы центрированной и фронтовой шим
- 4.24.3. Система тактирования
- 4.24.4. Регистры модуля pwm
- Регистр конфигурации pwclk
- Регистр конфигурации pwpol
- Регистр разрешения работы каналов pwen
- Регистр дополнительного делителя pwpres
- Регистры делителей pwscnt0/pwscnt1 и pwscal0/pwscal0
- Регистры счетчика каналов pwcnTx
- Регистры периода каналов pwpeRx
- Регистры коэффициента заполнения каналов pwdtYxФормат регистров коэффициента заполнения pwdtYx
- Регистры коэффициента заполнения каналов pwdtYx
- Регистр управления pwctl
- Регистр специальных режимов pwtst
- Регистры работы с портом p
- 4.24.5. Примеры программирования модуля pwm
- Инициализация модуля pwm, пример 1
- Инициализация модуля pwm, пример 2
- 4.25. Ограничение энергии потребления
- 4.25.1. Как остановить мк 68hc12
- 4.25.2. Как вывести мк 68hc12 из состояния пониженного энергопотребления
- 4.26. Советы по использованию платы отладки mc68evb912b32
- 4.27. Заключение по главе 4
- 4.28. Что еще почитать?
- 4.29. Вопросы и задания Основные
- Исследовательские
- Глава 5 основы сопряжения мк с устройствами ввода/вывода
- 5.1. Электрические характеристики мк 68hc12
- 5.1.1. Нагрузочные характеристики
- 5.1.2. Что произойдет, если Вы должным образом не учтете электрические характеристики периферийных ис?
- 5.1.3. Входные и выходные характеристики логических элементов
- 5.2. Устройства дискретного ввода: кнопки, переключатели, клавиатуры
- 5.2.1. Кнопки и переключатели
- 5.2.2. Dip переключатели
- 5.2.3. Клавиатуры
- 5.3. Устройства индикации: светодиоды, семисегментные индикаторы, индикаторы логического выхода с тремя состояниями
- 5.3.1. Светодиоды
- 5.3.2. Семисегментные индикаторы
- 5.3.3. Индикаторы для логического выхода с тремя состояниями
- 5.4. Программное обслуживание дискретных входов и выходов
- 5.5. Подавление механического дребезга контактов переключателей
- 5.5.1. Аппаратная защита от механического дребезга контактов
- 5.5.2. Программная защита от механического дребезга контактов
- 5.5.3. Пример программной защиты
- 5.6. Жидкокристаллические индикаторы
- 5.6.1. Краткие сведения о жидкокристаллических индикаторах
- 5.6.2. Сопряжение мк с символьным жк индикатором
- 5.6.3 Сопряжение мк с графическим жк дисплеем
- 5.7. Управление электрическим двигателем
- 5.7.1. Силовые полупроводниковые ключи
- 5.7.2. Оптоэлектронная потенциальная развязка
- 5.7.3. Инвертор напряжения
- 5.8. Кодовый замок
- 5.8.1. Схема подключения периферийных устройств
- 5.8.2. Программа управления
- 5.9. Интерфейс мк с аналоговыми датчиками
- 5.10. Интерфейс rs-232
- 5.11. Заключение по главе 5
- 5.12. Что еще почитать?
- 5.13. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 6 добро пожаловать в реальный мир!
- 6.1. Ужасные истории об ошибках проектирования
- 6.1.1. Случай квадратичного генератора
- 6.1.2. Случай таймера для лазерного излучения
- 6.2. Правила обращения с микросхемой 68нс12 и рекомендации по проектированию
- 6.2.1. Рекомендации по обращению со cmos
- 6.2.2. Рекомендации по проектированию на cmos
- 6.3. Исследование помех
- 6.3.1. Что такое помехи
- 6.3.2. Электромагнитная совместимость
- 6.3.3. Спецификации системы помех — не будем крепки задним умом!
- 6.3.4. Методы снижения помех
- 6.4. Защитное программирование
- 6.5. Методики испытаний на наличие помех
- 6.5.1. Обнаружение помех
- 6.5.2. Испытание на чувствительность к помехам
- 6.5.3. Испытания на электромагнитную совместимость
- 6.6. Управление энергопотреблением
- 6.6.1. Параметры потребляемой мощности для микроконтроллера 68hc12
- 6.6.2. Типы батарей
- 6.6.3. Емкость батарей
- 6.6.4. Стабилизация напряжения
- 6.6.5. Схемы супервизора для микропроцессора
- 6.6.6. Меры энергосбережения
- 6.7. Заключение по главе 6
- 6.8. Что еще прочитать?
- 6.9. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 7 примеры встроенных систем управления
- 7.1. Система привода робота, движущегося вдоль стенок лабиринта
- 7.1.1. Описание проекта
- 7.1.2. Подсистемы 68hc12, используемые в проекте
- 7.1.3. Компоненты системы
- 7.1.4. Структура программы и блок-схема алгоритма
- 7.1.5. Программный код
- 7.2. Лазерный проектор
- 7.2.1. Описание проекта
- 7.2.2. Подсистемы 68hc12 используемые в проекте
- 7.2.3. Описание некоторых компонентов системы
- 7.2.4. Аппаратные средства
- 7.2.5. Структура программы и блок-схема алгоритма
- 7.2.6. Программный код
- 7.2.7. Испытания устройства
- 7.2.8. Заключительные испытания системы управления
- 7.3. Цифровой вольтметр
- 7.3.1. Описание проекта
- 7.3.2. Системы 68hc12 используемые в проекте
- 7.3.3. Расчет интерфейса модуля atd
- 7.3.4. Структура программы и блок-схема алгоритма
- 7.3.5. Программа управления
- 7.3.6. Измерение неэлектрических величин
- 7.4. Стабилизация скорости вращения двигателя с использованием оптического тахометра
- 7.4.1. Описание проекта
- 7.4.2. Немного теории
- 7.4.3. Анализ
- 7.4.4. Структура программы и блок-схема алгоритма
- 7.4.5. Программный код
- 7.4.6. Испытания
- 7.5. Парящий робот
- 7.5.1. Описание проекта
- 7.5.2. Системы hcs12 используемые в проекте
- 7.5.3. Теоретическое обсуждение
- 7.5.4. Структура программы и блок-схема алгоритма
- 7.5.5. Программный код
- 7.5.6. Некоторые комментарии
- 7.6. Система защиты компьютера, основанная на нечеткой логике
- 7.6.1. Описание проекта
- 7.6.2. Использование системы hcs12
- 7.6.3. Основы теории
- 7.6.4. Структура программы и блок-схема алгоритма
- 7.6.5. Описание системы
- 7.6.6. Обсуждение проекта
- 7.6.7. Программный код
- 7.6.8. Некоторые комментарии
- 7.7. Электронная версия игры в «15»
- 7.7.1. Описание проекта
- 7.7.2. Системы hcs12 используемые в проекте
- 7.7.3. Основы теории
- 7.7.4. Схемное решение, структура программы и блок-схема алгоритма
- 7.7.5. О компонентах системы
- 7.7.6. Программный код
- 7.7.7. Некоторые комментарии
- 7.8. Программирование резидентного Flash пзу микроконтроллера b32 в составе платы отладки mc68hc912b32evb
- 7.9. Заключение по главе 7
- 7.10. Что еще прочитать?
- 7.11. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 8 операционные системы реального времени
- 8.1. Рассказ: официант — «живая» операционная система реального времени
- 8.2. Что является целью осрв?
- Вопросы для самопроверки
- 8.3. Обзор концепций
- 8.3.1. Требования к динамическому распределению ram
- Вопросы для самопроверки
- 8.3.2. Динамическое распределение памяти
- 8.3.3. Структуры данных
- 8.4. Основные понятия
- 8.4.1. Что такое задача?
- 8.4.2. Управление задачами
- 8.4.3. Компоненты многозадачных систем
- 8.5. Типы операционных систем реального времени
- 8.5.1. Системы с циклическим опросом
- 8.5.2. Циклический опрос с прерываниями
- 8.5.3. Карусельные системы
- 8.5.4. Смешанные системы
- 8.5.5. Системы с управлением по прерыванию
- 8.5.6. Кооперативная многозадачность
- 8.5.7. Многозадачные системы с преимущественным приоритетом
- 8.6. Проблемы осрв
- 8.6.1. Конкуренция Другой рассказ
- 8.6.2. Повторная входимость
- 8.6.3. Межзадачные связи
- 8.6.4. Безопасность, проверка и безотказная работа
- 8.6.5. Главный вопрос
- 8.7. Выполнение операционной системы реального времени
- 8.8. Пример применения: осрв циклического опроса
- 8.8.1. Краткий обзор проекта
- 8.8.2. Пример кода
- 8.8.3. Испытание контроллера усилителя
- 8.9. Другая прикладная программа: цикл опроса с прерываниями
- 8.10. Сложное прикладное устройство: имитатор осрв
- 8.10.1. Краткий обзор проекта
- 8.10.2. Типовой код
- 8.11.Заключение по главе 8
- 8.12. Что еще почитать?
- 8.13. Вопросы и задания Основные
- Более сложные
- Исследовательские
- Глава 9 распределенные сети с интерфейсом msCan
- 9.1. Компьютерные сети
- 9.2. Промышленные сети
- 9.3. Сети с протоколом can
- 9.3.1. Протокол can
- 9.3.2. Модуль контроллера последовательного обмена msCan12
- Подсистема прерывания контроллера msCan12.
- 9.3.3. Проблемы синхронизации
- 9.3.4. Конфигурирование модуля msCan12 для работы в сети
- 9.4. Различия между контроллерами msCan в составе 68hc12 и hcs12
- 9.5. Пример программирования контроллера msCan Схема включения аппаратных средств для двух отладочных плат Axiom
- 9.6. Контроллер последовательного обмена bdlc
- 9.7. Заключение по главе 9
- 9.8. Что еще почитать?
- 9.9. Вопросы и задания Основные
- Более сложные
- Исследовательские