Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С — страница 39 из 70

Любая встраиваемая микропроцессорная система принимает данные из «внешнего мира», преобразует эти данные в управляющие воздействия, а затем «выдает» эти воздействия во внешний мир. Ни одна микропроцессорная система управления не обходится без механических переключателей, которые активируются пользователем, а также без различного рода устройств индикации, которые информируют пользователя о режимах работы самой системы и о состоянии объекта управления. В данном параграфе мы рассмотрим, как подключить к МК различные типы переключателей и простейшие светодиодные индикаторы. Несколько позже, в параграфе 5.6, мы подробно остановимся на вопросах сопряжения МК с жидкокристаллическим дисплеем (далее ЖК индикатор или ЖК дисплей).

5.2.1. Кнопки и переключатели

На рис. 5.4,а приведена схема подключения одиночного механического переключателя к МК. Механическая часть переключателя может быть выполнена таким образом, что его замкнутое состояние удерживается только тогда, когда человек нажимает на клавишу. Такой переключатель называют кнопкой. Другие переключатели обладают свойством удерживать замкнутое и разомкнутое состояние контактов при отсутствии внешнего воздействия. Последнее потребуется лишь для того, чтобы изменить состояние переключателя с разомкнутого на замкнутое и наоборот. Такие переключатели называются переключателями с фиксацией положения или тумблерами.

a) Подключение кнопки к МК НС12

б) Подключение группы из 8 DIP-переключателей

Рис. 5.4. Примеры схем подключения механических переключателей к МК


Возвратимся к нашей схеме (рис. 5.4,а). Когда клавиша отжата, переключатель находится в разомкнутом состоянии, и на входе МК формируется высокий логический уровень сигнала. Когда клавиша нажата, переключатель замыкает контакты, вывод МК подсоединяется к потенциалу общего провода системы GND, и на входе МК формируется логический 0. Резистор R = 10 кОм ограничивает силу тока в цепи переключателя.

Если бы переключатель был идеальным, то переход потенциала вывода МК из состояния 1 в состояние 0 при нажатии клавиши происходил бы мгновенно. На самом деле это не так. Переход механического переключателя из одного состояния в другое сопровождается механическим дребезгом контактов. Эффект механического дребезга состоит в том, что при смене состояния, например, с разомкнутого на замкнутое, контакты, прежде чем перейти из установившегося разомкнутого состояния в установившееся замкнутое, многократно замыкаются и размыкаются. Тогда, установив щуп осциллографа на вход МК, мы увидим сначала высокий уровень сигнала, затем многократное нерегулярное во времени переключение с 1 на 0, и, наконец, установится низкий уровень сигнала. Частота работы МК (от единиц до сотен МГц) чрезвычайно высока по сравнению с временами переключения механических контакторов (десятки–сотни мс). Поэтому механический дребезг контакта может быть воспринят управляющей программой как его многократное переключение. Существуют аппаратные и программные методы защиты от эффекта дребезга контактов. Один из программных методов заключается в том, что после обнаружения первого изменения логического уровня сигнала программа формирует задержку на 100-200 мс. В течение этого времени дребезг контактов прекращается, и переключатель переходит в новое устойчивое состояние. Мы рассмотрим аппаратные и программные методы противодребезгвой защиты в параграфе 5.5.

5.2.2. DIP переключатели

На рис. 5.4,б показана схема, в которой мы распространили идею подключения одного механического переключателя к МК сразу на восемь переключателей. Эти микропереключатели смонтированы на заводе-производителе в корпусе, который по размерам и расположению выводов совпадает с корпусом типа DIP (Dual In-line Package) для интегральных схем. Поэтому их называют DIP-переключатели.

Каждый переключатель из блока подсоединен к отдельному выводу порта МК. Так же, как и в предыдущем случае, ток цепи каждого переключателя ограничивается резистором. Для блока из восьми переключателей потребуется восемь резисторов. Для уменьшения габаритов печатной платы изделия целесообразно использовать сборку резисторов в одном корпусе. Однако возможно использование и одиночных резисторов.

В параграфе 5.8 мы рассмотрим пример использования подобной сборки DIP-переключателей для выбора режима работы микропроцессорной системы.

5.2.3. Клавиатуры

Во многих приложениях микропроцессорные системы требуют ввода цифровой и буквенной информации. Для таких случаев могут быть использованы блоки из нескольких кнопок, которые объединены конструктивно и соединены электрически по стандартной матричной схеме. Такие блоки называют клавиатурами. На рис. 5.5 показана клавиатура из 16 клавиш, которая позволяет вводить данные в микропроцессорную систему в шестнадцатеричном коде. Изучим представленную на рис. 5.5 схему соединения МК с клавиатурой подробно.


Код на выходах PORTx[3:0]Код на входах PORTx[7:4]
Нажатая клавиша32107654Код порта PORTx[7:0]
0111011100xEE
1111011010xDE
2111010110xBE
3111001110x7E
4110111100xED
5110111010xDD
6110110110xBD
7110101110x7D
8101111100xEB
9101111010xDB
A101110110xBB
B101101110x7B
C011111100xE7
D011111010xD7
E011110110xB7E
F011101110x77
Не нажатаXXXX11110xXF

Рис. 5.5. Схема подключения матричной клавиатуры к МК 68HC12


Кнопки клавиатуры собраны в матричную схему. Первый ряд составляют кнопки 0, 1, 2 и 3. Второй ряд — кнопки 4, 5, 6, и 7. Следующие восемь кнопок составляют ряд 3 и ряд 4. Выводы левых контактов кнопок одного ряда соединены между собой и подключены к одному из выводов порта PORTx (x — имя порта МК, например, PORTA, PORTB и т.д.). В нашем примере для обслуживания четырех линий клавиатуры использованы четыре линии порта PORTx[0]…..PORTx[3]. Все эти линии работают в режиме вывода.

Выводы правых контактов кнопок также соединены между собой. Но при этом объединены каждые четыре кнопки по вертикали, которые зрительно составляют единый столбец. Приведенное соединение называют матричным. Из рис. 5.5. можно видеть, что блок клавиатуры из 16 клавиш имеет всего восемь линий связи для подключения к МК. А если бы мы использовали ранее рассмотренные схемы соединения, то для подключения 16 кнопок портебовалось бы 16 линий связи. Четыре вывода столбцов подключаются ко входам порта PORTx[4]…PORTx[7]. Эти линии порта работают в режиме ввода. Каждая линии PORTx[4]…PORTx[7] снабжена подтягивающим к напряжению питания резистором R = 10 кОм.

Если все клавиши, принадлежащие к одной колонке, отжаты, то на соответствующем входе порта PORTx[4]…PORTx[7] формируется логическая 1. МК использует специальную программу опроса клавиатуры, чтобы обнаружить, какая клавиша в данный момент времени нажата. Эта программа сначала выставляет на линию PORTx[0] логический 0. Тогда все левые выводы клавиш первого ряда оказываются под потенциалом логического 0. Если одну из клавиш этого ряда нажать, то уровень сигнала на одном из входов PORTx[4]…PORTx[7] изменится с 0 на 1. Например, если нажали клавишу «0», то на входе PORTx[4] установится низкий логический уровень, а все остальные входы PORTx[5]…PORTx[7] останутся в 1. Или, если нажать клавишу «2», то в 0 установится вывод PORTx[6], а линии PORTx[4], PORTx[5] и PORTx[7] будут в 1. Таки образом, программа, прочитав состояние линий PORTx[4]…PORTx[7] и обнаружив 0 в каком-либо разряде, сможет установить, какая клавиша нажата.


Программа опроса клавиатуры последовательно анализирует состояние клавиш каждого ряда, последовательно выставляя логический 0 на выводы PORTx[0]…PORTx[3]. На рис. 5.5 приведена таблица, в которой показаны коды, которые будут на линиях порта при нажатии каждой из клавиш. Эти коды должны быть использованы программой опроса для приведения кода нажатой клавиши к одному из стандартных представлений, например к коду ACSII.

Рассмотренная нами клавиатура может иметь иные символы на кнопках, в соответствие с функциональным назначением кнопки в устройстве. Например, подобная клавиатура используется для управления насосом бензоколонки. Тогда клавиши могут задавать тип отпускаемого бензина, форму приема платежа и т.д. Микроконтроллер должен распознать, какая клавиша нажата, и перейти к соответствующей подпрограмме.

Рис. 5.6. Блок-схема алгоритма опроса матричной клавиатуры


На рис. 5.6 приведена блок-схема алгоритма опроса матричной клавиатуры из 16 клавиш. Этот алгоритм состоит из четырех одинаковых блоков, в которых сначала устанавливается в 0 одна из линий PORTx[0]…PORTx[3], а затем контролируется состояние линий PORTx[4]…PORTx[7]. Если на входах линий PORTx[4]…PORTx[7] логические 1, то ни одна кнопка активизированного ряда не нажата, и следует перейти к опросу следующего ряда. Если на какой-либо из линий PORTx[4]…PORTx[7] обнаружен потенциал логического 0, то по номеру линии и по номеру активизированного ряда программа должна восстановить код нажатой клавиши. Для этого удобно использовать таблицу рис. 5.5. Мы привели лишь общую структуру алгоритма. Детальное ее рассмотрение последует после примера программного кода, и описания ЖК дисплея.

/*-----------------------------------------------------------*/

/* filename: keypad.c                                        */

/* МAIN PROGRAМ: Эта программа производит анализ             */

/*состояния матричной клавиатуры из 16 клавиш                */

/*Для подключения клавиатуры использован PORTB               */

/*Разряды PORTB[0]…PORTB[3] активизируют линии рядов         */

/*разряды PORTB[4]…PORTB[7]используются для считывания кодов */

/*колонок                                                    */

/*-----------------------------------------------------------*/

/*подключаемые файлы*/

#include <912b32.h>

#include 

#include 


/*используемые функции*/

char keypad(unsigned char keypress, unsigned char row);

char which_key(unsigned char keypress); /*Function to select key*/


void main{void) {

 unsigned char keypress;

 /*задание кодов активизации рядов клавиатуры*/

 unsigned char first = 0xFE; /*код активизации первого ряда*/

 unsigned char second = 0xFD; /*код активизации второго ряда*/

 unsigned char third = 0xFB; /*код активизации третьего ряда*/

 unsigned char fourth = 0xF7; /*код активизации четвертого ряда*/

 DDRB = 0x0f; /*линии 0…3 на вывод, линии 4…7 на ввод*/

 while(1) {

  PORTB = 0xFE;

  keypress = PORTB;

  key = keypad(keypress, first);

  PORTB = 0xFD;

  keypress = PORTB;

  key = keypad(keypress, second);

  PORTB = 0xFB;

  keypress = PORTB;

  key = keypad(keypress, third);

  PORTB = 0xF7;

  keypress = PORTB;

  key = keypad(keypress, fourth);

 }

}


/*------------------------------------------------------------------------*/

/*Функция keypad определяет, была ли нажата какая-либо клавиша.           */

/*Функция сравнивает прочитанное значение порта PORTB с тем значением,    */

/*которое было выдано на порт PORTB. Если они равны, то ни одна клавиша в */

/*ряду не нажата                                                          */

/*------------------------------------------------------------------------*/

char keypad(unsigned char keypress, unsigned char row) {

 char key1;

 if (keypress != row) { /*какая-то клавиша нажата*/

  key1 = which_key(keypress); /*определить клавишу*/

  putchars(key1); /*передать символ на дисплей*/

 } else if(keypress == row) { /*ни одна из клавиш не нажата*/

  key1 = 'Z';

 }

 return (key1);

}


/*------------------------------------------------------------------------*/

/* Функция char which_key определяет код нажатой клавиши методом перебора */

/*табличных значений                                                      */

/*------------------------------------------------------------------------*/

char witch_key(unsigned char keypress) {

 char key;

 switch(keypress) /*распознавание кода клавиши*/

 {

 case 0xEE:

  key = '0'; /*нажата клавиша "0"*/

  break;

 case 0xDE:

  key = '1'; /*нажата клавиша "1"*/

  break;

 case 0xBE:

  key = '2'; /*нажата клавиша "2"*/

  break;

 case 0x7E:

  key = '3'; /*нажата клавиша "3"*/

  break;

 case 0xED:

  key = '4'; /*нажата клавиша "4"*/

  break;

 case 0xDD:

  key = '5'; /*нажата клавиша "5"*/

  break;

 case 0xBD:

  key = '6'; /*нажата клавиша "6"*/

  break;

 case 0x7D:

  key = '7'; /*нажата клавиша "7"*/

  break;

 case 0xEB:

  key = '8'; /*нажата клавиша "8"*/

  break;

 case 0xDB:

  key = '9'; /*нажата клавиша "9"*/

  break;

 case 0xBB:

  key = 'A'; /*нажата клавиша "A"*/

  break;

 case 0x7B:

  key = 'B'; /*нажата клавиша "B"*/

  break;

 case 0xE7:

  key = 'C'; /*нажата клавиша "C"*/

  break;

 case 0xD7:

  key = 'D'; /*нажата клавиша "D"*/

  break;

 case 0xB7:

  key = 'E'; /*нажата клавиша "E"*/

  break;

 case 0x77:

  key = 'F'; /*нажата клавиша "F"*/

  break;

 default:

  key = 'Z';

 } /*конец распознавание кода клавиши*/

 return(key);

}

/*----------------------------------------------------------*/

Представленный программный код не является полностью завершенной рабочей программой, поскольку в нем отсутствуют элементы защиты от дребезга контактов, отсутствует текст функции вывода символов на ЖК дисплей. Мы исправим эти недостатки несколько позже, в разделе 5.6.

5.3. Устройства индикации: светодиоды, семисегментные индикаторы, индикаторы логического выхода с тремя состояниями