unsigned int svn_seg[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
определяет массив из десяти байтов, содержащих коды управления 7-сегментным индикатором, приведенные на Рис. 6.8 (стр. 183).
Эти десять значений от svn_seg [0] до svn_seg [9] будут размещены в десяти последовательно расположенных регистрах. Большинство микроконтроллеров PIC имеют достаточно ограниченный размер памяти данных, и в таком случае, когда значения не изменяются в дальнейшем, имеет смысл разместить эти десять констант в ПЗУ программ в виде набора команд retlw <константа>, подобно тому, как это было показано в Программе 6.6 на стр. 184. Для этого достаточно к объявлению массива добавить ключевое слово const:
unsigned int const svn_seg[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
Используя описанные способы, напишите программу, реализующую электронный аналог игральной кости с семью светодиодами, подключенными к старшим семи выводам порта В, как показано на Рис. 9.4, а. Основная программа будет просто инкрементировать глобальную переменную целого типа с максимально возможной скоростью. При нажатии на кнопку, подключенную к выводу INT/RB0, программа будет переходить к обработке прерывания (см. Пример 9.5). Процедура обработки прерывания отобразит одну из шести комбинаций светодиодов, а после 10 с выключит светодиоды, чтобы сэкономить энергию батареи. Использование часового кварца частотой 32 768 Гц также уменьшит потребление схемы, как можно увидеть на Рис. 10.3 (стр. 306).
Решение
Коды управления СИД задаются в Программе 9.7 в виде глобального массива из шести констант в соответствии с Рис. 9.4,
Рис. 9.4.
Основная программа просто инкрементирует однобайтную переменную throw и сбрасывает ее в ноль, когда она становится больше пяти. Таким образом, реализуется программный счетчик по модулю 6, т. е. 0, 1, 2, 3, 4, 5, 0….
Компилятор CCS версии 3.18 генерирует функцию main(), состоящую из восьми команд, включая несколько команд перехода и пропуска. В результате при указанной тактовой частоте инкрементирование переменной происходит около 1000 раз в секунду. Такая частота обеспечивает практически случайный выбор одного из шести значений по нажатию кнопки, подключенной к выводу INT.
#include <16f84.h>
#use delay (clock=32768)
#byte PORTB = 6
void die(void);
unsigned int const array(6] = (0x7e, 0xec, 0x6c, 0xc8, 0x48, 0x80};
unsigned int throw;
void main(void)
{
set_tris_b(0x01);
enable_interrupts(INT_EXT); /* Устанавливаем INTE в 1 */
enable_interrupts(GLOBAL); */ Устанавливаем GIE в 1 */
while(1) /* Бесконечный цикл */
{
PORTB = 0; /* Выключаем светодиоды */
if(++throw > 5) /* Инкрементируем (по модулю б) */
throw=0;
}
}
#int_ext /* Обработчик внешнего прерывания */
void die(void)
{
PORTB = array[throw]; /* Отображаем n-ю комбинацию точек */
delay_ms(10000); /* в течение 10000 мс */
}
Функция обработчика прерывания die () копирует
9.1. Для управления светодиодами игральной кости из Примера 9.6 требуется семь линий параллельного порта, а для некоторой электронной игры требуется две такие кости. Посмотрите внимательно на Рис. 9.4 — можно ли уменьшить количество линий, используемых для управления одной костью, до четырех?