Алгоритм
/*
* Copyright (C) 2005 Serge Vakulenko, <vak@cronyx.ru>
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You can redistribute this file and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software Foundation;
* either version 2 of the License, or (at your discretion) any later version.
* See the accompanying file "COPYING" for more details.
*/
#include "io.h"
#include "io2313.h"
/* Была ли нажата кнопка. */
unsigned char button_pressed;
unsigned char button_disabled;
/* Массив указателей на картинки - в отдельном файле. */
extern unsigned char *pic_table [];
/*
* Микросекундная задержка - для кварца 4 MHz.
*/
void usleep (unsigned char usec)
{
do {
/* Нужно четыре такта на цикл.
* Три такта уходит на декремент и переход,
* плюс одна холостая команда. */
asm volatile ("nop");
} while (--usec);
}
/*
* Миллисекундная задержка.
*/
void msleep (unsigned char msec)
{
do {
usleep (250);
usleep (250);
usleep (250);
usleep (250);
} while (--msec);
}
/*
* Отображение одного рисунка в течении нескольких миллисекунд.
*/
void frame (unsigned char *data, int msec)
{
unsigned char i;
/* Горят только те светодиоды, для которых
* в строке 0 и в столбце 1 (PORTB=0, PORTD=1). */
while (msec > 0) {
for (i=0; i<7; ++i) {
/* Выдаем строку номер i в течение 1 миллисекунды. */
outb (~(1 << i), PORTB);
outb (readb (data + i), PORTD);
msleep (1);
}
msec -= 7;
/* Опрос кнопки переключения узоров - вход B7. */
if (testb (7, PINB)) {
/* Кнопка не нажата. */
if (button_disabled)
button_disabled = 0;
} else {
/* Кнопка нажата. */
if (! button_disabled) {
button_pressed = 1;
return;
}
}
}
}
/*
* Отображение последовательности рисунков.
*/
void show (unsigned char *data)
{
while (readb (data) != 0xff) {
/* Каждый кадр отображается 125 миллисекунд. */
frame (data, 125);
if (button_pressed)
return;
data += 7;
}
}
int main ()
{
/* Номер рисунка. */
int n = 0;
/*
* Устанавливаем направление портов ввода-вывода:
* D0-D6 - выход - столбцы 1-7.
* B0-B6 - выход - строки 7-1.
* B7 - вход - кнопка переключения узоров.
*/
outb (0x7f, DDRB);
outb (0x7f, DDRD);
for (;;) {
show (pic_table [n]);
/* Если была нажата кнопка - меняем рисунок. */
if (button_pressed) {
++n;
if (! pic_table [n])
n = 0;
/* После переключения запрещаем реакцию на кнопку,
* пока она не будет отжата. Чтобы не было
* двойного срабатывания. */
button_disabled = 1;
button_pressed = 0;
}
}
}