Справочник по программированию «Bascom-AVR» (М.Л. Кулиш). Справочник по программированию Bascomavr Создание микропроцессорной системы Теория
Скачать 1.18 Mb.
|
'--------------------- Dim Buf_kl As Byte 'код нажатой кнопки Dim Buf_pkl As Byte 'предварительный код нажатой кнопки Dim R_ckl As Byte 'счетчик удержания клавиатуры '--------------------- Dim Buf_dis(4) As Byte 'буфер индикации (копия сегментов) Dim Cnt_dis As Byte 'счетчик индикации '--------------------- Dim Bufr As String * 20 'текстовая строка '------------------------------------------ Настройка прерываний Объявление используемых прерываний и имен программ обработки прерываний (векторов). Задание типа прерываний и приоритетов. Применение опции Nosave обеспечивает отключение режима сохранение всех регистров общего назначения (R0…R31 и Sreg) ' назначение векторов прерывания. On Timer0 Timer0_int Nosave 'вектор прерывания от таймера 0 On Timer2 Timer2_int Nosave 'вектор прерывания от таймера 2 '------------------------------------------ Настройка периферии Объявление частоты тактового генератора, скорости и последовательного интерфейса, режима счетчиков, портов. Если, что-то из необходимых параметров конфигурации не будет объявлено, то компилятор использует значения, установленные в окнах меню Options $crystal = 1000000 'генератор 1 МГц '--------------------- Mcucr = &B10000000 'режим IDLE – разрешить ' ТАЙМЕРЫ Tccr0 = &B00000011 'режим таймера 0: Fкв/64 - часы реального времени '--------------------- Tccr1a = &B01000000 'режим таймера 1: генератор звука 2 кГц с выходом на PB1 (OC1A) Tccr1b = &B00001000 'делитель Fкв / 1 и с выходам Oc1a Ocr1ah = 0 : Ocr1al = 250 'и коэффициетном Fкв/250*2 '--------------------- 'режим таймера 2: генератор секундных импульсов Assr.3 = 1 : Wait 1 'включить НЧ-генератор AS2 и подождать стабилизации амплитуды Tcnt2 = 0 : Waitms 10 'очистить счетчик и подождать 'пока значение перепишется из временного буфера Ocr2 = 128 : Waitms 10 'установить значение сравнения 'установить коэффициент деления прескалера К=128 Tccr2 = &B00010101 'и выход секундных импульсов на PB3 (OC2) '--------------------- ' ПОРТЫ Ddrb = &B00001010 'направление линий порта B: 1 - на вывод Portb = &B11111111 'исходное состояние линий B: hhhh1h1h ============================================================================= 5 ===================================== Справочник по программированию «Bascom-AVR» == '--------------------- Ddrc = &B00001111 'направление линий порта C: 1 - на вывод Portc = &B11111111 'исходное состояние линий C: hhhh1111 '--------------------- Ddrd = &B00000000 'направление линий порта D: 1 - на вывод Portd = &B11111111 'исходное состояние линий D: hhhhhhhh '* h - высокий уровень, подтянутый через резистор '--------------------- Разрешение прерываний Разрешение отдельных типов прерываний и общее разрешение. Выполняется после инициали- зации периферии ' Прерывания Timsk = &B010000001 'разрешить прерывание от переполнения таймера 0 и таймера 2 ‘Enable Timer0 'допускаемая, но не рекомендуемая форма ‘Enable Timer2 Enable Interrupts 'разрешить прерывания. '--------------------- Основная программа Главная программа и ее ветви. Описывается построение главного цикла программы, в котором происходит ожидание событий, и ветви отработки поступающих Чтобы придать главной про- грамме компактный вид, повторяющиеся и функционально законченные модули оформляются в виде подпрограмм. 'ГЛАВНЫЙ ЦИКЛ Mc: Idle Goto Mc '---------------------------------------------------------------------------------- Подпрограм- мы обработки прерываний Обычно небольшие по объему модули для быстрой реакции на события, и поэтому критичные к времени исполнения и количеству используемых ресурсов. Программы обработки прерыва- ний, в первую очередь, пишутся на ассемблере. Данные из программ прерывания передаются главной программе через общие регистры. 'обработка прерывания таймера 0 'используется как часы реального времени с частотой 244 Гц (4 мс) 'для этого нужно организовать схему деления 1 МГц/64/64 = 0,000244140625 МГц Timer0_int: $asm Push R31 'сохраним регистры In R31 , Sreg Push R31 Push R30 '----- Ldi R31 , 192 'переустановим счетчик Out Tcnt0 , R31 '--------------------- Rcall Led_out 'вывод в индикатор Rcall In_kl 'опрос клавиатуры '--------------------- 'обработка счетчика времени звонка Intt2_1: Lds R31 , {r_btim} 'считаем счетчик времени звонка And R31 , R31 Breq Intt2_2 'если он равен 0 - переход Dec R31 'уменьшить Sts {r_btim} , R31 Ldi R31 , &B00001001 'и разрешить пищать Rjmp Intt2_3 Intt2_2: Ldi R31 , &B00001000 'запретить пищать Intt2_3: Out Tccr2 , R31 'в регистр управления таймером 2 '----- Pop R30 'восстановим регистры Pop R31 Out Sreg , R31 Pop R31 Reti 'дополнительная команда завершения прерывания 'в конце процедуры его обработки. Рекомендуется применять перед каждой командой Return, которая 'должна скомпилироваться как Reti, однако по какой-то причине может быть пропущена и 'скомпилирована как Ret. Подобное может происходить, когда в программе обработки прерывания 'применено несколько команд завершения, а компилятор автоматически заменяет Ret на Reti только 'один раз – только первую команду Return после метки, обозначающей начало программу прерывания. ============================================================================= 6 ===================================== Справочник по программированию «Bascom-AVR» == $end Asm Return '---------------------------------------------- 'обработка прерывания таймера 2. Происходит 1 раз в секунду Timer2_int: $asm Push R31 'сохраним регистры '----- Ldi R31 , 255 Sts {ndat} , R31 '----- Pop R31 'восстановим регистры $end Asm Return '---------------------------------------------------------------------------------- Драйверы устройств (под- программы обслуживания периферии ввода вывода) Экономичные, небольшие и быстро работающий модули. Также критичные к вре- мени исполнения и используемым ресурсам. Используются при обработке преры- ваний. Также пишутся на ассемблере. ' ВВОД ДАННЫХ С КЛАВИАТУРЫ ' клавиатура опрашивается при выводе очередного знакоместа на индикатор ' код кнопки совпадает с номером знакоместа. Осуществляется подавление дребезга ' срабатывание фиксируется при удержании более 6 циклов опроса In_kl: $asm Lds R31 ,{Buf_kl} 'пока буфер клавиатуры не опустеет And R31 , R31 Breq Inkl 'сканирование не проводится Ret '--------- ' НАЧИНАЕМ Inkl: Lds R31 , {r_ckl} 'подготовим счетчика нажатий к обработке Sbic Pinc , 4 'считать состояние линии опроса кнопки Rjmp N_st 'нет нажатия - переход '--------- ' НАЖАТИЯ ЕСТЬ Y_st: Cpi R31 , 6 'если равен 6 - нажатие уже было зафиксировано Breq Y_st1 'на выход без запоминания. Inc R31 'иначе нужен инкремент Sts {r_ckl} , R31 'и сохранить Cpi R31 , 6 Brne y_st1 'меньше 6 - тоже выход без действий '--------- ' НАЖАТИЕ ЗАФИКСИРОВАТЬ Ldi R31 , 3 'звонить 60 мс Sts {r_btim} , R31 Lds R31 , {Cnt_dis} 'преобразуем код знакоместа (от 0 до 3) Inc R31 'в код кнопки (от 1 до 4) Sts {Buf_kl} , R31 Y_st1: Ret '--------- ' НАЖАТИЯ НЕТ N_st: And R31 , R31 'проверим счетчик "удержания" Breq N_st1 'не равен нулю Dec R31 'декремент Sts {r_ckl} , R31 'и сохранить N_st1: Ret $end Asm '---------------------------------------------------------------------------------- Const N_scn = &B11110000 ' МАСКА СКАНИРОВАНИЯ ДЛЯ ОА Const N_sc1 = &B11111110 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА Const N_sc2 = &B01111101 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА Const N_sc3 = &B11111011 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА Const N_sc4 = &B11110111 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА '----------------------------- 'обслуживание светодиодного 7-сегментного индикатора Led_out: $asm Lds R31 , {Cnt_dis} 'считать значение счетчика сканирования Inc R31 Andi R31 , 3 Sts {Cnt_dis} , R31 'и сохранить ============================================================================= 7 ===================================== Справочник по программированию «Bascom-AVR» == '--------- Cpi R31 , 1 Breq Led_1 '--------- Cpi R31 , 2 Breq Led_2 '--------- Cpi R31 , 3 Breq Led_3 Led_0: '--------- Lds R30 , {buf_dis} Ldi R31 , N_sc1 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА Rjmp Led_e '--------- Led_1: Lds R30 , {buf_dis+1} Ldi R31 , N_sc2 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА Rjmp Led_e '--------- Led_2: Lds R30 , {buf_dis+2} Ldi R31 , N_sc3 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА Rjmp Led_e '--------- Led_3: Lds R30 , {buf_dis+3} Ldi R31 , N_sc4 ' ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА Led_e: Out Portd , R30 In R30 , Portc Ori R30 , N_scn ' МАСКА СКАНИРОВАНИЯ And R30 , R31 Out Portc , R30 Ret $end Asm '---------------------------------------------------------------------------------- Скелет готов. Еще раз о результатах проделанной работы. Приведенная выше программа является полно- стью работоспособной, но при этом не совершает никаких внешних действий. С ее помощью оживлена и функ- ционирует вся периферия, однако со стороны основной программы это будет незаметно, так как все устройства будут обслуживаться в фоновом режиме. Во-вторых, почти все написано на ассемблере и это сделано для полного контроля используемых ресурсов и обеспечения максимальной производительности, что является немаловажным при низкой тактовой частоте. В-третьих, практически аппаратная реализация счетчика прошедшего времени, зву- кового тонального генератора и мультиплексного индикатора обеспечивает хорошие потребительские свойства изделия за счет исключения «паразитных» эффектов, свойственных программной реализации этих функций, таких как погрешность хода, «грязный» (модулированный) звук, низкочастотное мерцание отдельных знакомест (за счет неравномерности и неодинаковости времени свечения). В-четвертых, система готова работать и для выполнения многих других задач и обеспечивает необходимую возможность расширения Этап 3. «Построение главного цикла программы». Задача этапа – создание базовой структуры програм- мы и определение номенклатуры базовых программных модулей. Структура программы с ГЛАВНЫМ ЦИКЛОМ (ГЦ) является базовой для продолжительно работающих программ с многократно повторяющимся алгоритмом обработки данных. С другой стороны, ГЦ является средст- вом выравнивания скорости работы более быстрого процессора и медленного процесса генерации исходных дан- ных. Как правило, в ГЦ осуществляется последовательная проверка необходимости выполнения некоторого набо- ра задач. Малое время исполнения опроса обеспечивает быстрое реагирования на события. В ГЦ включается опе- рация перевода ядра микроконтроллера в спящий режим, способствующий снижения потребления энергии во время ожидания заданий. Выход из спящего режима происходит только по прерыванию и это не вызывает затруд- нений, так как и появление новых задач обычно обусловлено прошедшим прерыванием. По крайней мере, про- грамма строится так, чтобы наиболее важные события сами вызывали прерывания или возникали вследствие пре- рываний. Для нашего примера в ГЦ будет осуществляться проверка всего трех задач: - окончания очередной секунды, по появлению ненулевого значения переменной “Ndat” ; - нажатие кнопки, по появлению ненулевого значения переменной “Buf_kl” ; - обновления индикатора, по появлению ненулевого значения переменной “ Ddat ” . ============================================================================= 8 ===================================== Справочник по программированию «Bascom-AVR» == ПРОГРАММА 2 Главный цикл Состоит из операций проверки появления одной из задач, вызова программы обработки задачи и очистки признака наличия задачи. Причем для клавиатуры очистка производится после обработки, так как сам признак является носителем информации о номере кнопки. Проверяемые задачи рас- полагаются в порядке приоритета, а после обработки одно задачи производится переход на начало ГЦ. '---------------------------------------------------------------------------------- 'ГЛАВНЫЙ ЦИКЛ Mc: If Ndat <> 0 Then Ndat = 0 'очистить "обновить данные" Gosub New_data 'обработать данные Goto Mc End If If Ddat <> 0 Then Ddat = 0 'очистить "обновить индикатор" Gosub New_led 'обновить индикатор Goto Mc End If If Buf_kl <> 0 Then Gosub W_klb 'обработать нажатие, только потом Buf_kl = 0 'очистить уже обработанное нажатие Goto Mc End If Idle Goto Mc '---------------------------------------------------------------------------------- Заготовки для программ обработки событий ГЦ Создаются одновременно с оформлением структуры ГЦ, чтобы не потерять все имеющиеся метки (имена подпрограмм) 'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА '--------------------- 'обработать данные времени по истечении секунды New_data: Return '---------------------------------------------------------------------------------- 'обновить индикатор по завершению одной из операций в соответствии с текущим состоянием New_led: Return '---------------------------------------------------------------------------------- 'обработать нажатие кнопки в соответствии с текущим режимом W_klb: Return '---------------------------------------------------------------------------------- После добавления конструкции ГЦ программа работоспособна и пригодна к дальнейшему расширению пу- тем добавления новых к списку задач. Этап 4. «Создание программ главного цикла». Задача этапа – создание исполнительных программных мо- дулей. Данный этап позволяет создать первую версию рабочей программы, в соответствие с задачами, решаемыми программами ГЦ. При этом происходит описание действий, производимой программой. ПРОГРАММА 3 Рабочие программы Содержать три программных модуля по числу обрабатываемых задач '---------------------------------------------------------------------------------- 'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА '--------------------- 'обработать данные времени по истечении секунды New_data: Incr Rsec 'плюс секунда If Rsec > 59 Then 'при необходимости Rsec = 0 : Goto Ndata1 'скорректировать счетчик секунд End If Goto Ndata3 Ndata1: Incr Rmin 'плюс минута ============================================================================= 9 ===================================== Справочник по программированию «Bascom-AVR» == If Rmin > 59 Then 'при необходимости Rmin = 0 : Goto Ndata2 'скорректировать счетчик минут End If Goto Ndata3 Ndata2: Incr Rhour 'плюс час If Rhour > 23 Then 'при необходимости Rhour = 0 'скорректировать счетчик часов End If Ndata3: Ddat = 255 'поставить признак обновления индикации Return '---------------------------------------------------------------------------------- Программа формирования изображения Самая сложная программа. Содержит последовательность преобразований (символьное изо- бражение – двоичное число – сегментный код числа). Повторяющиеся модули оформлены в виде подпрограмм. 'обновить индикатор по завершению одной из операций в соответствии с текущим состоянием New_led: 'сформировать символьное изображение времени Bufr = "" 'очистить строку If Rhour < 10 Then 'если значение часов выражается одной цифрой Bufr = Bufr + "0" 'добавить символ лидирующего нуля End If Bufr = Bufr + Str(rhour) 'добавить значение часов If Rmin < 10 Then 'если значение часов выражается одной цифрой Bufr = Bufr + "0" 'добавить символ лидирующего нуля |