Файл: Учимся программировать микроконтроллеры Pic на языке PicBasicPro (В.В. Хилинский, 2007).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 17.06.2025
Просмотров: 1781
Скачиваний: 8
Рис. 29. Схема построения матричной клавиатуры.
При нажатии на одну из кнопок произойдет замыкание (соединение) определенного столбца с определенной строкой. Если строки и столбцы такой клавиатуры подключить к портам микроконтроллера и опрашивать эти порты в определенном порядке, то всегда можно определить, когда и какая кнопка была нажата. Например, если по порядку подавать на каждую цепь строки высокий логический уровень и при этом, опрашивая поочередно цепи столбцов, выяснить, где этот высокий уровень обнаружен, можно определить, какая кнопка была нажата. На рисунке 30 показана схема подключения к микроконтроллеру 12 кнопочной клавиатуры и ЖК монитора для вывода информации о нажатой клавише.
Рис. 30. Схема подключения 12-кнопочной клавиатуры.
Пример:
80
DEFINE LCD_DREG PORTD |
' Определяем порт, к которому подключены |
‘ цепи данных. |
|
DEFINE LCD_DBIT 0 |
' Определяем первый контакт порта, к |
‘ которому подключены цепи данных на LCD DB4. |
|
DEFINE LCD_RSREG PORTD |
' Определяем порт, к которому подключена |
‘ цепь RS . |
|
DEFINE LCD_RSBIT 7 |
' Определяем контакт, к которому |
‘ подключается цепь RS. |
|
DEFINE LCD_EREG PORTD |
' Определяем порт, к которому подключена |
‘ цепь E. |
|
DEFINE LCD_EBIT 6 |
' Определяем контакт, к которому |
‘ подключена цепь E. |
|
DEFINE LCD_BITS 4 |
' Определяем режим 4-разрядной шины. |
DEFINE LCD_LINES 2 |
' Определяем тип ЖК монитора. |
DEFINE LCD_COMMANDUS 1000 |
' Определяем задержку между посылками |
‘ команд на ЖК монитор. |
|
DEFINE LCD_DATAUS 50 |
' Определяем время задержки между |
‘ посланными данными.
' ——-[ Переменные ]———————————————————————————-
Flag |
Var |
Bit |
‘ Вводим переменную. |
Key |
Var |
Byte |
Bit ' Флаг показывающий нажатие клавиши. |
Debounce |
Var |
Var |
|
D_Flag |
Bit ' Флаг Debounce flag used by Inkeys. |
||
' ——-[ Начальная установка ]—————————————————————————
TRISB=%00000111
PortB=%11111111
flag=1
LCDOUT $fe, 1 ' Очистим экран ЖК монитора. LCDOUT $fe, 2 ' Установим курсор в начальную позицию.
' ——-[ Основная программа ]————————————————————————— ——-
Main:
GOSUB KeyScan
IF FLAG =0 THEN LCDOUT $FE,1:LCDOUT $FE,2
'***** Вывод на экран код клавиши ******
IF Flag=1 THEN LCDOUT key |
' Если клавиша нажата, вывести на экран |
‘ ЖК значение наж. клавиши. |
|
PAUSE 100 |
' Пауза в 100 мсек для осуществления |
‘ автоповтора. |
|
GOTO Main |
' Вернуться назад в начало программы, |
81 |
‘ чтобы начать цикл снова.
Keyscan:
' Эта подпрограмма сканирует 12-кнопочную клавиатуру и возвращает значение
‘нажатой кнопки в
‘переменную «KEY». Если никакая кнопка не нажималась, то возвращается
‘значение 128.
‘Она также возвращает переменную по имени " Debounce ", которая равна 1, ‘ если клавиша все еще нажата, и 0, если не нажата. Это является ‘ противодребезговой функцией для этой клавиатуры.
Debounce=1 |
' Установка начального значения для Debounce. |
||
Key=0 |
' Очищаем переменную KEY перед просмотром. |
||
TrisB=%11100000 |
' Устанавливаем 4 вывода PortB на выход. |
||
Option_Reg.7=0 |
' и 3 вывода PortB на вход. |
||
' Подключаем внутренние подтягивающие |
|||
‘ резисторы PortB. |
' Подать на строку D клавиатуры 0. |
||
PortB=%01111101 |
|||
GOSUB Col |
' Перейти на подпрограмму сканирования колонок. |
||
IF Flag=1 THEN GOTO Map |
' Если клавиша нажата, то перейти на |
||
‘ метку Map. |
' Подать на строку C клавиатуры 0. |
||
PortB=%11111011 |
|||
GOSUB Col |
' Перейти на подпрограмму сканирования колонок. |
||
IF Flag=1 THEN GOTO Map |
' Если клавиша нажата, то перейти на |
||
‘ метку Map. |
' Подать на строку B клавиатуры 0. |
||
PortB=%11110111 |
|||
GOSUB Col |
' Перейти на подпрограмму сканирования колонок. |
||
IF Flag=1 THEN GOTO Map |
' Если клавиша нажата, то перейти на |
||
‘ метку Map. |
' Подать на строку A клавиатуры 0. |
||
PortB=%11101111 |
|||
GOSUB Col |
' Перейти на подпрограмму сканирования колонок. |
||
IF Flag=1 THEN GOTO Map |
' Если клавиша нажата, то перейти на |
||
метку Map. |
' В противном случае (клавиша не нажата), сбросить |
||
D_Flag=0 |
|||
‘ флаг – debounce. |
|||
Debounce=0 |
|||
GOTO Exit |
' Выйти из подпрограммы. |
||
Map: |
|||
IF D_Flag=1 THEN Exit |
' Если уже было нажта клавиша то выход. |
||
D_Flag=1 |
' Установить флаг Debounce. |
||
Debounce=0 |
' Обнулить Debounce. |
||
Exit:
'Lookup Key,[1,2,3,4,5,6,7,8,9,10,0,11,128],Key
82
'таблица перевода значений ‘переменной Key в числовые значения.
'**Если необходимо преобразовать код нажатой клавиши в ascii код, то ‘ закомментируйте строку программы расположенную выше. Если этого ‘ делать не надо, то закомментируюйте строку программы ‘ расположенную ниже
LOOKUP
'Таблица ‘перевода значений переменной Key в значения ASCII кода.
KEY,["*","0","#","7","8","9","4","5","6","1","2","3",32],Key
'IF FLAG=1 THEN LCDOUT key |
' Отправить “Hello World” на ЖКИ |
|
'pause 500 |
||
RETURN |
' Выход из подпрограммы. |
|
'Это подпрограмма сканирования колонок клавиатуры. Если какая либо клавиша
'нажата, переменная Flag устанавливается в 1, и в 0, если никакая клавиша не
‘ нажата.
' Кроме того, если никакая клавиша не нажата, то переменной - KEY,
‘ возвращается значение 12. |
||
Col: |
' Устанавливаем переменную Flag в 1. |
|
Flag=1 |
||
IF PortB.5=0 THEN S_Exit |
' Если нажата клавиша в первом столбце, то |
|
‘ перейти пп. S_Exit(,) |
||
Key=Key+1 |
' Иначе инкремент переменой KEY и перейти к |
|
‘ следующему столбцу. |
||
IF PortB.6=0 THEN S_Exit |
' Если нажата клавиша во втором столбце, |
|
‘ то перейти на пп. S_Exit(,) |
||
Key=Key+1 |
' Иначе инкремент переменой KEY и перейти к |
|
‘ следующему столбцу. |
||
IF PortB.7=0 THEN S_Exit |
' Если нажата клавиша в третьем столбце, |
|
‘ то перейти на пп. S_Exit(,) |
||
Key=Key+1 |
' Иначе инкремент переменой KEY (она теперь |
|
‘ равняется 12). |
' Устанавливаем переменную flag в 0. |
|
Flag=0 |
||
S_Exit: |
‘ противодребезговая подпрограмма. |
|
PAUSEUS 100 |
||
RETURN |
' выйти из подпрограммы. |
|
В следующем примере мы с Вами поговорим о выводе звукового сигнала.
Пример № 11. Создание музыки.
Для того чтобы воспроизводить звуки с помощью микроконтроллера вполне достаточно подключить через конденсатор в 1 мкФ к выводу микроконтроллера,
83
маломощный динамик сопротивлением порядка 8 Ом либо пьезобуззер (пищалка).
Конечно, название этого примера звучит слишком громко. Нет, мы не будем здесь учиться писать симфонии и песни, мы просто сделаем простейший музыкальный инструмент, нажимая на кнопки которого будут воспроизводиться музыкальные ноты.
Для начала соберем схему представленную на рисунке 31, и запишем в микроконтроллер программу:
Рис. 31. Схема к примеру «Создание музыки»
Speaker |
VAR PORTA.0 |
' Псевдоним для динамика подключенного к PORTA.0 |
Notes VAR Word[9] |
' Определение массива частот для муз. нот |
|
Key VAR |
Byte |
'Код нажатой клавиши |
' Список массива частот
Notes[1] = 262 : Notes[2] = 294 : Notes[3] = 330 : Notes[4] = 349
Notes[5] = 392 : Notes[6] = 440 : Notes[7] = 494 : Notes[8] = 524
' Конфигурируем порты |
|
TRISB = %11111111 |
' PORTB весь на вход |
84
OPTION_REG.7 = 0 |
' Подключим подтягивающие резисторы в |
PORTB |
|
TRISA = 0 |
' PORTA на выход |
ADCON1 = %111 |
' Устанавливаем все выводы PORTA как цифровые |
‘ Основная программа |
|
Main: |
Key = PORTB ' Считываем PORTB и присваиваем его переменной Key
IF Key <> |
255 |
THEN |
' Если нажата любая клавиша |
||
key |
= |
~key |
‘ Инвертируем все биты переменной Key |
||
Key |
= |
NCD |
Key |
' Преобразуем значение переменной Key в код |
|
‘ вывода порта
FREQOUT Speaker,50,Notes[Key] ' Выдать ноту на динамик
ENDIF
GOTO Main |
' Вернуться в начало |
END |
' Конец программы |
В этой программе мы сталкиваемся сразу с несколькими новыми операторами. Во-первых, во второй и четвертой строках программы мы впервые вводим определение массива переменных. Мы указали, что массив Notes состоит из 9 членов. В четвертой строке мы указали все члены массива кроме нулевого члена. Это сделано потому, что нулевой член мы не используем по причине, которая будет разъяснена позже. Далее мы конфигурируем порты в соответствии с нашими задачами. Затем идет текст основной программы. В первой строке основной программы мы считываем регистр PORTB (состояние кнопок) и сохраняем его значение в переменной Key. Далее мы сталкиваемся с оператором условия, который говорит, что если не нажата ни одна из клавиш, программа перескакивает к предпоследней строке и затем возвращается в начало. Если же нажата любая из клавиш, т.е. значение переменной Key не равно 255 программа переходит на следующую строку стоящую после оператора IF...THEN. Здесь происходит побитное инвертирование всех разрядов переменной Key. Например, если была нажата четвертая клавиша то Key = %11110111. После побитного инвертирования эта переменная станет Key = %00001000. Далее идет строка с оператором NCD, который возвращает номер самого старшего разряда переменной равный 1. Это значит, что теперь переменная Key = 4. И, наконец, следует оператор, который подает на вывод Speaker в течение 50 мс частоту определяемую значением члена массива - Notes[Key]. Затем программа вновь возвращается в начало основного цикла. Так программа постоянно опрашивает клавиатуру и генерирует звуки (если нажата любая из клавиш).
В этой главе мы рассмотрели 11 примеров программ в которых микроконтроллер выполняет задачи, которые распространены в повседневной
85
практике. На основании этих примеров и тех примеров которые находятся в папке «SAMPLES» инсталлированного пакета Вы можете потихоньку начинать писать собственные программы. Для того чтобы Ваши программы были написаны грамотно в следующей главе приводятся описания команд языка PicBasicPro для компилятора версии 2.47.
Глава 4. Команды языка PicBasicPro.
Вначале хотелось бы привести полный список команд PicBasic Pro для компилятора версии 2.47:
@Вставить одну строку на ассемблере.
ADCIN |
Считать аналоговое значение на выводе и осуществить АЦП. |
|
ASM..ENDASM |
Вставить подпрограмму на ассемблере. |
|
BRANCH |
Переход на одну из меток определяемую индексом (еквивалент |
|
ON..GOTO). |
Команда BRANCH для многостраничной памяти (длинное |
|
BRANCHL |
||
BRANCH). |
||
BUTTON |
Производит обработку нажатия кнопки |
|
CALL |
Вызов подпрограммы ассемблера. |
|
CLEAR |
Обнуление всех переменных. |
|
CLEARWDT |
Обнуление Сторожевого таймера. |
|
COUNT |
Счет импульсов на определенном выводе. |
|
DATA |
Первоначальная запись констант в память ЕЕПРОМ |
|
микроконтроллера |
||
DEBUG |
Передача информации в стандартном асинхронном формате |
|
DEBUGIN |
Прием информации в стандартном асинхронном формате. |
|
DISABLE |
Отключение процесса отладки и обработок прерываний. |
|
DISABLE DEBUG |
Отключение процесса отладки. |
|
DISABLE INTERRUPT Отключение процесса обработки прерывания. |
||
DTMFOUT |
Генерирует на определенном выводе сигналы тонального набора |
|
номера |
||
EEPROM |
Запись во внутреннюю ЕЕПРОМ (аналог команды DATA). |
|
ENABLE |
Включить процесс обработки прерываний и работу отладчика. |
|
ENABLE DEBUG |
Включить процесс отладки. |
|
ENABLE INTERRUPT |
Включить процесс обработки прерываний. |
|
END |
Остановить выполнение программы и перейти в режим малого |
|
энергопотребления |
||
FOR..NEXT |
Многократно выполнить инструкции (один из операторов |
|
цикла) |
||
FREQOUT |
Генерирует одну или две частоты на определенном выводе |
|
GOSUB |
Вызвать подпрограмму на БЕЙСИКЕ по указанной метке |
|
GOTO |
Продолжить выполнение программы с указанной метки. |
|
86