Справочник по программированию «Bascom-AVR» (М.Л. Кулиш). Справочник по программированию Bascomavr Создание микропроцессорной системы Теория
Скачать 1.18 Mb.
|
End If Bufr = Bufr + Str(rmin) 'добавить значение минут '--------- Gosub Asc_seg : Buf_dis(4) = Tmpb 'получить код первого знакоместа '--------- Gosub Asc_seg2 : Buf_dis(3) = Tmpb 'получить код второго знакоместа '--------- Gosub Asc_seg2 : Buf_dis(2) = Tmpb 'получить код третьего знакоместа '--------- Gosub Asc_seg2 : Buf_dis(1) = Tmpb 'получить код четчертого знакоместа '--------- Return '----------------------------------------------------------- 'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII (ВТОРОГО СИМВОЛА) Asc_seg2: Bufr = Mid(bufr , 2) 'сдвинуть строку влево на одну позицию '--------- 'П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII Asc_seg: Tmpb = Asc(bufr) 'считать первый символ строки Tmpb = Tmpb - &H30 'преобразовать ASCII в число Tmpb = Lookup(tmpb , Tabseg0) 'считать из таблицы, используя число как смещение Return '--------- 'ТАБЛИЦА РАСПОЛОЖЕНИЯ СЕГМЕНТОВ ИНДИКАТОРА - ПРОТОТИПА '--------- ' D7 D6 D5 D4 D3 D2 D1 D0 ' ----------------------------------------------- 'BUF_DIS(1) ¦ h1 g1 f1 e1 d1 c1 b1 a1 'BUF_DIS(2) ¦ h2 g2 f2 e2 d2 c2 b2 a2 'BUF_DIS(3) ¦ h3 g3 f3 e3 d3 c3 b3 a3 'BUF_DIS(4) ¦ h4 g4 f4 e4 d4 c4 b4 a4 '------------------------------------------- ' РАСПОЛОЖЕНИЕ СЕГМЕНТОВ НА ПОЛЕ ИНДИКАТОРА ' =============================================== ' ¦ ¦ ' ¦ -a4- -a3- -a2- -a1- ¦ ' ¦ I I I I I I I I ¦ ' ¦ f4 b4 f3 b3 f2 b2 f1 b1 ¦ ' ¦ I I I I I I I I ¦ ' ¦ -g4- -g3- -g2- -g1- ¦ ' ¦ I I I I I I I I ¦ ' ¦ e4 c4 e3 c3 e2 c2 e1 c1 ¦ ' ¦ I I I I I I I I ¦ ' ¦ -d4- -d3- -d2- -d1- ¦ ' ¦ [h4] [h3] [h2] [h1]¦ ' ¦ ¦ ' =============================================== '----------------------------------------------------------- ' ТАБЛИЦА КОДОВ СЕГМЕНТОВ ОТ 0(00h) ДО 15(0Fh) , СВЕЧЕНИЕ "0" ============================================================================= 10 ===================================== Справочник по программированию «Bascom-AVR» == '----------------------------------------------------------- 'ШЕСТНАДЦАТИРИЧНЫЕ ЦИФРЫ Tabseg0: Data &HC0 , &HF9 ' 0 , 1 -d0 - Data &HA4 , &HB0 ' 2 , 3 I I Data &H99 , &H92 ' 4 , 5 D5 D1 Data &H82 , &HF8 ' 6 , 7 I I Data &H80 , &H90 ' 8 , 9 -d6 - Data &H88 , &H83 ' A , B I I Data &HC6 , &HA1 ' C , D D4 D2 Data &H86 , &H8E ' E , F I I ' -D3- [D7] '---------------------------------------------------------------------------------- ' программы клавиатуры '--------------------------------------------------------- ' --------------------------------------- ' | AVR-WATCH | ' | --------------------------------- | ' | | --- --- --- --- | | ' | | | | | | | | | | | | ' | | --- --- --- --- | | ' | | | | | | | | | | | | ' | | --- [] --- [] --- [] --- [] | | ' | --------------------------------- | ' | 1 2 3 4 | ' | _ _ _ _ | ' | |_| |_| |_| |_| | ' | | ' | Reset + + - | ' | Min Hour Min Min | ' --------------------------------------- ' выполнение программ обработки кнопок - основной список ' 0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й ' 1: Сбросить минуты 2: Добавить час 3: Добавить минуту 4: Убавить минуту '--------------------------------------------------------- Программа об- работки кнопок Назначение кнопок выбрано произвольно. Для перехода к программам обработки кнопок используется специальная функция On – Goto с индексированием списка меток. Дает быст- рый и экономичный код. Применение функции Select Case не рекомендуется, так как не по- зволяет вкладывать объемные конструкции. W_klb: On Buf_kl Goto Kn , Km1 , Km2 , Km3 , Km4 'обработать нажатие кнопки '--------- Km1: Rmin = 0 'сбросить минуты If Rmin > 30 Then 'при необходимости округления Goto Km2 'скорректировать счетчик минут End If Km1_1: Ddat = 255 'поставить признак обновления индикации Kn: Return '--------- Km2: Incr Rhour 'плюс час If Rhour > 23 Then 'при необходимости Rhour = 0 'скорректировать счетчик часов End If Goto Km1_1 '--------- Km3: Incr Rmin 'плюс минута If Rmin > 59 Then 'при необходимости Rmin = 0 'скорректировать счетчик минут End If Goto Km1_1 '--------- Km4: Decr Rmin 'минус минута If Rmin = 255 Then 'при необходимости Rmin = 59 'скорректировать счетчик минут End If Goto Km1_1 '---------------------------------------------------------------------------------- ============================================================================= 11 ===================================== Справочник по программированию «Bascom-AVR» == Первая версия программы готова, она полностью работоспособна, но функционально бедна. Структура программы во всех компонентах открыта для расширения функциональных возможностей. Определив набор до- бавляемых функций, следует выбрать путь реализации новых задач. Существует несколько подходов: - простое добавление новых функций по имеющимся правилам работы программы. Этот путь пригоден для небольших добавлений, похожих на уже имеющиеся; - добавление новых функций по другим правилам построения программы. Необходимость в этом возникает при создании многофункциональных систем и обычно решается создание других разделов с собственной структу- рой ГЦ; - добавление сложных функций в виде отдельных модулей, содержащих все необходимые компоненты вво- да и отображения данных. Это приемлемый вариант реализации небольшого количества функций при некритич- ном времени реагирования на внешние воздействия. Примером таких функций могут быть программы тестирова- ния, сохранения данных, обработка протокола установления связи; - создание новых функций посредством специальных инструментов – утилит. Утилиты – специальные про- граммы, облегчающие реализацию часто повторяющихся операций. Использование утилит для расширения сис- темы наиболее эффективно при реализации большого количества несложных и похожих функций. Рассмотрим примеры построения и применения утилит. Этап 5. «Создание утилит для расширения функциональных возможностей». Задача этапа – создание на- бора стандартных программных модулей для выполнения элементарных операций. Требуемый для расширения набор утилит определяется составом добавляемых функций. Выберем, напри- мер, следующий набор расширяемых режимов: - выбор с помощью меню; - многофункциональная клавиатура; - отображение текстовых сообщений. Для этого нам понадобятся следующие утилиты: - вывод указанного текстового сообщения на индикатор, например, с помощью индекса; - останов на фиксированное время с ожиданием нажатия кнопки. При добавлении этих утилит прошлось расширить список используемых переменных и функций прерыва- ния реального времени. Все изменения в программе можно наблюдать в полном измененном тексте, который бу- дет приведен дальше. Этап 6. «Расширение функциональных возможностей с помощью утилит». В программу версии 2 добавлено: - несколько новых переменных для обеспечения работы новых систем; - расширена функция программы прерывания таймера 0. Добавлена ветка формирования временных интер- валов 64 мс и проверка запрета звукового сигнала; - расширена функция программы формирования изображения; - добавлен и выделен отдельно раздел утилит (вспомогательных универсальных программ формирования изображения и управления). Там же расположены расширенные таблицы кодов сегментов и сообщений; - добавлено начальное сообщение; - изменены и добавлены функции клавиатуры. Функции, конечно, надуманные, но это демонстрационная программа. Показан один из основных механизмов создания многофункциональной клавиатуры; - добавлены программы коррекции монтажа индикатора и клавиатуры (при отклонении фактической раз- водки от теоретической модели. И так, программа работает и обеспечивает все требуемые режимы работы. Однако работа не закончена. Не- обходимо привести ее в порядок. Имеется в виду введение последних непринципиальных улучшений и подготов- ка исходного текста к дальнейшей модернизации, возможно даже, через продолжительное время. Все это можно назвать этапом оптимизации. Этап 7. «Оптимизация программы». Прагматичный (лишь бы работало) стиль программирования часто оказывается, безответственным. Прак- тика показывает, что встроенное программное обеспечение часто подвергается доработке в процессе производства и даже эксплуатации. Законченный программный проект в той или иной степени должен удовлетворять возмож- ности дальнейшей доработки или, в крайней случае, должен быть пригоден для заимствования его частей для дру- гих проектов. Что нужно для этого сделать? Следующее: - просмотреть текст программы и одинаковые участки, даже если это всего одна строка, попытаться офор- мить в качестве отдельной подпрограммы. В приведенной программе такие примеры имеются; - попробовать свести к одной подпрограмме похожие участки программы, сделав, например, несколько входов с различными параметрами и промежуточное преобразование; - устранить слишком длинные участки программ, оформив их как функционально законченную подпро- грамму. В первую очередь это относится к вычислительным программам; ============================================================================= 12 ===================================== Справочник по программированию «Bascom-AVR» == - провести подробное комментирование программы. Особенно тщательно описывая, протоколы, форматы данных, условия принятия решение, обязательно применительно к тем физическим процессам, с которыми взаи- модействует программа; - в максимальной степени представить применяемые цифровые константы в символьном виде. Их опреде- ление вынести в заголовки и указать их назначение; - обязательно указать номер версии продукта, разницу в версиях (историю доработок), дату создания (ком- пиляции), версию и тип компилятора. После оптимизации (и в процессе тоже) необходимо провести повторную компиляцию и проверку функ- ционирования. ПРОГРАММА 4 Вторая версия программы Содержит все добавления. '------------------------------------------ ' Программа "AVR-WATCH" (версия 2) '------------------------------------------ ' Микроконтроллер типа ATMEGA8 '------------------------------------------ ' Программируемые Fuses: ' CKSEL3...CKSEL0 = 1001 - низкочастотный кварцевый резонатор ' CKOPT=0 - внутренние конденсаторы подключены к кварцевому резонатору ' RSTDISBL=1 - порт PC6 используется как сброс ' WDTON=1 - сторожевой таймер разрешен ' SPIEN=0 - последовательное программирование разрешено ' BOOTSZ1,BOOTSZ0 = 00, BOOTRST=1 - параметры загрузчика ' EESAVE = 1 - НЕ ОЧИЩАТЬ EEPROM при программировании ' BODLEVEL=1, BODEN=1 - ПАРАМЕТРЫ СБРОСА ' SUT1=1,SUT1=0 - ВРЕМЯ СТАРТА '------------------------------------------ ' Ресурсы: ' Генератор RC - внутренний 1 МГц, а к TOSC1 and TOSC2 подключен кристалл 32768 Гц ' На выходе PB3 (OC2) импульсы длительностью 1 с (0.5 Гц) ' На выходе PB1 (OC1A) звуковой сигнал ' Порт Portd выход сегментов ' Portc0...Portc3 - код знакоместа (позиционный) он же порт сканирования клавиатуры ' Четыре кнопки: Port0...Portc3 - код сканирования клавиатуры, Portc4 - линия возврата клавиатуры '------------------------------------------ $regfile = "m8def.dat" 'определить тип микроконтроллера '------------------------------------------ Dim Ndat As Byte 'признак "обновить данные" Dim Ddat As Byte 'признак "обновить индикатор" '--------------------- Dim Mdisp As Byte 'режим отображения: 0 - ЧЧММ, 1 - ММСС, 2 - погашен Dim Msnd As Byte 'режим звука: 0 - включен, <>0 - выключен '--------------------- Dim S_tim As Byte 'программный счетчик времени Dim W_tim As Byte 'счетчик времени задержек Dim R_btim As Byte 'счетчик времени звонка '--------------------- Dim Rsec As Byte 'счетчик секунд Dim Rmin As Byte 'счетчик минут Dim Rhour As Byte 'счетчик часов '--------------------- 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 Tmpb As Byte 'временное значение Dim Index As Byte 'временное значение Dim Value As Byte 'временное значение '--------------------- Dim Bufr As String * 10 'текстовая строка '------------------------------------------ $crystal = 1000000 'генератор 1 МГц, необходим компилятору для правильного ' вычисления задержек и других временных параметров '------------------------------------------ ' назначение векторов прерывания. On Timer0 Timer0_int Nosave 'вектор прерывания от таймера 0 On Timer2 Timer2_int Nosave 'вектор прерывания от таймера 2 '------------------------------------------ Mcucr = &B10000000 'режим IDLE - разрешить ============================================================================= 13 ===================================== Справочник по программированию «Bascom-AVR» == ' ТАЙМЕРЫ Tccr0 = &B00000011 'режим таймера 0: Fкв/64 - часы реального времени '--------------------- 'режим таймера 1: Tccr1a = &B01000000 'генератор звука 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 '--------------------- Ddrc = &B00001111 'направление линий порта C: 1 - на вывод Portc = &B11111111 'исходное состояние линий C: hhhh1111 '--------------------- Ddrd = &B00000000 'направление линий порта D: 1 - на вывод Portd = &B11111111 'исходное состояние линий D: hhhhhhhh '* h - высокий уровень, подтянутый через резистор '--------------------- ' прерывания. Timsk = &B010000001 Enable Timer0 'разрешить прерывание от переполнения таймера 0 Enable Timer2 'разрешить прерывание от переполнения таймера 2 Enable Interrupts 'разрешить прерывания. '--------------------- Index = 1 : Gosub Dis_tr 'ВЫВОД СООБЩЕНИЯ СООБЩЕНИЯ (НОМЕР ВЕРСИИ) Wait 1 'подождать 'ГЛАВНЫЙ ЦИКЛ 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 Tr_klb 'скорректировать номер кнопок Gosub W_klb 'обработать нажатие Buf_kl = 0 'очистить оработанное нажатие Goto Mc End If Idle Goto Mc '---------------------------------------------------------------------------------- 'ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА '--------------------- 'обработать данные времени по истечении секунды New_data: Incr Rsec 'плюс секунда If Rsec > 59 Then 'при необходимости Rsec = 0 : Goto Ndata1 'скорректировать счетчик секунд End If Goto Ndata3 Ndata1: Incr Rmin 'плюс минута 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 'поставить признак обновления индикации ============================================================================= 14 |