Главная страница

Справочник по программированию «Bascom-AVR» (М.Л. Кулиш). Справочник по программированию Bascomavr Создание микропроцессорной системы Теория


Скачать 1.18 Mb.
НазваниеСправочник по программированию Bascomavr Создание микропроцессорной системы Теория
АнкорСправочник по программированию «Bascom-AVR» (М.Л. Кулиш).pdf
Дата21.03.2017
Размер1.18 Mb.
Формат файлаpdf
Имя файлаСправочник по программированию «Bascom-AVR» (М.Л. Кулиш).pdf
ТипСправочник
#4054
КатегорияПромышленность. Энергетика
страница7 из 8
1   2   3   4   5   6   7   8
Dim Tmpb As Byte 'временные байтовые данные
' ......
'определим действующие линии портов как константы
Const Pcamsk = &B11111111 'порта PA
Const Pcbmsk = &B11111111 'порта PB
Const Pccmsk = &B00000011 'порта PC
Const Pcdmsk = &B00111100 'порта PD
' ......
On Pcint0 Pc_int0 'векторы прерывания от изменения уровней на линиях портов
On Pcint1 Pc_int1
On Pcint2 Pc_int2
On Pcint3 Pc_int3
' ......
'настроить систему
Pcicr = &B00001111 'разрешим прерывания от изменения уровны во всех портах
Pcmsk0 = Pcamsk 'определим действующие линии портов: порта PA
Pcmsk1 = Pcbmsk 'порта PB
Pcmsk2 = Pccmsk 'порта PC
Pcmsk3 = Pcdmsk 'порта PD
Dub_pa = Pina And Pcamsk 'запомнить текущее состояние линий портов
Dub_pb = Pinb And Pcbmsk
Dub_pc = Pinc And Pccmsk
Dub_pd = Pind And Pcdmsk
Enable Interrupts
' ......
'главный цикл
Mc:
If Num_port <> 0 Then
Print Num_port : Num_port = 0
End If
Goto Mc
'--------------------------------------
'программы обработки прерываний от изменения уровня, сообщающие главной программе
'о наличии изменения ненулевым значением переменной Num_port
'--------------------------------------
'по линиям порта A
Pc_int0:
Tmpb = Pina Xor Pcamsk : Tmpb = Pina Xor Dub_pa : Num_port = 0
Gosub Search_pin 'добавить в Num_port номер позиции единицы
Return
'--------------------------------------
'по линиям порта B
Pc_int1:
Tmpb = Pinb Xor Pcbmsk : Tmpb = Pinb Xor Dub_pb : Num_port = 8
Gosub Search_pin 'добавить в Num_port номер позиции единицы
Return
'--------------------------------------
'по линиям порта C
Pc_int2:
Tmpb = Pinc Xor Pccmsk : Tmpb = Pinc Xor Dub_pc : Num_port = 16
Gosub Search_pin 'добавить в Num_port номер позиции единицы
Return
'--------------------------------------
'по линиям порта D
Pc_int3:
Tmpb = Pind Xor Pcdmsk : Tmpb = Pind Xor Dub_pd : Num_port = 24
Gosub Search_pin 'добавить в Num_port номер позиции единицы
Return
'--------------------------------------
'подпрограмма поиска "1" в измененного уровня, на самом деле, это преобразование
'позиционного кода в Tmpb в двоичный в Num_port. Методом сдвига вправо и искремента результата
=============================================================================
30

===================================== Справочник по программированию «Bascom-AVR» ==
Search_pin:
While Tmpb <> 0 'повторять пока регистр Tmpb не станет равным нулю
Shift Tmpb , Right : Incr Num_port
Wend
Return
'----------------------------------------------------------------------------------
Обработчик прерывания, написанный без применения ассемблера, не может иметь оптимального кода. Это показывает дисассемблированный текст (пример 6). Мы видим, что обработчик с одной стороны не выполняет недопустимых действий, а с другой – имеет явную избыточность и расточителен.
Пример 6 - Ассемблерный текст обработчика прерывания (листинг) из программы примера 5,
получаемый при компиляции Bascom-AVR
'----------------------------------------------------------------------------------
Pc_int0:
;сохранение регистрового блока
push r0
push r1
push r2
push r3
push r4
push r5
push r7
push r10
push r11
push r16
push r17
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r28
push r29
push r30
push r31
in r24,$3F
push r24
;Tmpb = Pina Xor Pcamsk
in r16,$0
ldi r20,#255
eor r16,r20
ldi r26,#5
ldi r27,#1
st x,r16
;Tmpb = Pina Xor Dub_pa
in r16,$0
lds r20,$101
eor r16,r20
ldi r26,#5
ldi r27,#1
st x,r16
;Num_port = 0
ldi r24,#0
sts $100,r24
;Gosub Search_pin 'добавить в Num_port номер позиции единицы
call 0000036A
;восстановление регистрового блока
pop r24
out $3F,r24
pop r31
pop r30
pop r29
pop r28
pop r27
pop r26
pop r25
pop r24
pop r23
pop r22
pop r21
=============================================================================
31

===================================== Справочник по программированию «Bascom-AVR» ==
pop r20
pop r19
pop r18
pop r17
pop r16
pop r11
pop r10
pop r7
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
;Return
Reti
;------
;подпрограмма Search_pin:
0000036A:
While Tmpb <> 0 'повторять пока регистр Tmpb не станет равным нулю
lds r16,$105
cpi r16,#0
brne 00000376
jmp 0000038E
00000376:
;Shift Tmpb , Right
ldi r25,#1
ldi r26,#5
ldi r27,#1
call 000003C6 ;вызов библиотечной программы
;Incr Num_port
ldi r26,#0
ldi r27,#1
ld r24,x
subi r24,#255
st x,r24
;Wend
jmp 0000036A
0000038E:
ret
;------
;библиотечная подпрограмма сдвига вправо на число в R25
000003C6:
cpi r25,#0
breq 000003D4
ld r24,x
000003CC:
lsr r24
dec r25
brne 000003CC
st x,r24
000003D4:
ret
'----------------------------------------------------------------------------------
=============================================================================
32

===================================== Справочник по программированию «Bascom-AVR» ==
Вопросы и ответы (1-10)
---------------------------------------------------------------------------------------------------------------------------------------------------
Вопрос 1
Но вот не могу понять только одного, почему в такой короткой программе, как эта:
Dim A As Byte
For A=1 to 30
Print A
Next A
End
…при компиляции размер кода составляет более 300 байт?? Абсурд! Баском конечно кушает память, но чтобы так!.. Может я в чём не прав?
Ответ 1
1 Насчет размера вашего примера. Такой же будет для любого компилятора. В этот размер входит:
- заголовок программы, включаемый в код автоматически (по умолчанию) и содержащий место под все вектора прерывания по 4 байт на вектор, очистку памяти 20-30 байт и инициализацию оборудования 30 - 100 байт;
- библиотека используемой функции и плюс 2-3 стандартных - около 100 байт;
- и собственно код вашей программы. Т.е. все сходится. Зато еще один вызов данной функции приводит к добавлению всего 20 - 30 байт.
---------------------------------------------------------------------------------------------------------------------------------------------------
Вопрос 2
Да и вообще, здесь много подводных камней, про которые даже в pdf-файле не найдешь…Я изучал когда-то давно Бейсик, сейчас плохо помню, приходиться заново учить. К какому Бейсику ближе Баском?
Ответ 2
Синтаксис и мнемоника, в принципе, отвечают стандарту Basic для DOS с учетом особенностей, ограниче- ний и дополнительных возможностей. Лучше на стандартный Basic не ориентироваться. Слишком много ограни- чений, обусловленных различными возможностями процессоров. Главное отличие в том, что нужно определить тип переменных заранее, не допускать скрытого преобразования типов и не применять больше одного действия в одном операторе.) Лучше ориентироваться на оригинальное описание Bascom-AVR – оно отличное. На русском имеется только описание Bascom-8051. И еще на примеры - их очень много.
--------------------------------------------------------------------------------------------------------------------------------------------------
Вопрос 3
Я сначала ничего не подозревал. Пытался спокойно делать себе программки в Баскоме, как вдруг понял, что реализация протокола I2C(TWI) в любом микроконтроллере происходит программно, независимо от того, есть ли в нём аппаратная поддержка данного протокола или нет. Я бы ничего этого не заметил, если бы не наткнулся на проблему нехватки памяти микроконтроллера. В конечном итоге выяснилось, что реализация аппаратного прото- кола возможна только в лицензионной версии Баскома, так как в демо-версии нет соответствующей библиотеки.
Ответ 3
По моему наблюдению, использование аппаратного контроллера с точки зрения размера кода совершенно неэффективно. При программной реализации размер кода получается равноценным. Потому, что работа с аппа- ратным портом конечно проще, но при этом требуется организовать обработку соответствующего прерывания.
Преимущество аппаратного I2C только в возможности осуществлять "прозрачную" работу одновременно с други- ми процессами и при наличии очень медленных устройств. Когда, например, в фоновом режиме нужно постоянно считывать или дописывать данные. При этом в коде "весит" именно программа организации МАССИВА записы- ваемых или считываемых данных, а не сам драйвер. Вот пример работающей программы на BAS и на ASM. В ос- новной программе применяются готовые функции. В прерывании используется ассемблерная программа (а ее размер минимален). Если устройство более медленное - нужно вместо NOP-ов добавить в программу подпро- граммы более продолжительной задержки. Не забывать, что когда работаешь с I2C, нужно бы запретить прерыва- ния. Если длительность импульса SCL превысит 10 мкс устройство может само отключится! В последующем примере переключение уровней делается изменение направления порта. Это важно. Так можно манипулировать с им намного быстрее.
'--------------------------------------------------------------
=============================================================================
33

===================================== Справочник по программированию «Bascom-AVR» ==
' Программы обслуживания АЦП типа ADS1110 (Burr-Broun)
'--------------------------------------------------------------
' результаты
' 1 смещение входа имеется и весьма заметно 1-2 мВ. Зависит от включенного коэффициента усиления
' 2 При усилении К=1 шум меньше 1 дискрета, что делает усреднение бесполезным
' 3 При максимальном усилении К=8 шум составляет около 20-30 мкВ пик-пик
'--------------------------------------------------------------
Config Sda = Portc.1 'линия данных
Config Scl = Portc.0 'линия синхронизации
Config I2cdelay = 1 'наивысшая скорость
'-----------------------------
'АВТООПРЕДЕЛЕНИЕ АДРЕСА АЦП
Find_adr:
Adradc = 142 'АДРЕС НУЛЕВОЙ ПРОШИВКИ(90h -2)
Disable Interrupts 'запретить прерывания
Findadr1:
Adradc = Adradc + 2 'АДРЕС ДЛЯ ЧТЕНИЯ + 2
If Adradc <> 160 Then
Goto Findadr2 'ПРОВЕРИМ НА МАКСИМУМ(90h + 16)
End If
Adradc = 144 'АДРЕС НУЛЕВОЙ ПРОШИВКИ (90h)
Goto En_intr 'НА ВЫХОД ЕСЛИ ВСЕ АДРЕСА ПРОЙДЕНЫ
Findadr2:
$asm
Lds R31 , {Adradc} 'АДРЕС ДЛЯ ЧТЕНИЯ
Inc R31
Rcall Start_bit 'СТАРТ, ДАННЫЕ И ЖДЕМ ПОДТВЕРЖДЕНИЯ
'------------
Rcall R_byte 'ПРИМЕМ СТАРШИЙ БАЙТ
Rcall Mstr_ack 'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ
Rcall R_byte 'ПРИМЕМ МЛАДШИЙ БАЙТ
Rcall Mstr_ack 'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ
Rcall R_byte 'ПРИМЕМ СТАТУС
Rcall No_ack 'ДА - БЕЗ ПОДТВЕРЖДЕНИЯ И СФОРМИРУЕМ СТОП-БИТ
Andi R31 , &B01100000 'АНАЛИЗИРУЕМ D5 И D6. ВСЕГДА Д.Б. = 0
Brne Findadr1 'ЕСЛИ НЕ НУЛЬ - ПОВТОРИТЬ
$end Asm
Goto En_intr 'НА ВЫХОД ЕСЛИ АДРЕС НАЙДЕН
'------------------------------------------
'п/п записи статуса АЦП ADS1110 (нормальный медленный режим) 15 изм/с. Шкала 1.024 В
Slow_adc:
' ------------ Запуск преобразования: 1 только в одиночном
' | --------- Запуск: 0 - автоматический, 1 - одиночное
' | |
' | | ------- Скорость: 00 - 240 SPS, 01 - 60 SPS
' | | | 10 - 30 SPS, 11 - 15 SPS
' | | |
' | | | ----- Усиление: 00 - 1 , 01 - 2
' | | | | 10 - 4 , 11 - 8
' | | | |
' | |||||
Value = &B00001101
Wr_adc:
Disable Interrupts 'запретить прерывания
I2cstart 'старт
I2cwbyte Adradc 'байт адреса
I2cwbyte Value 'байт режима
I2cstop 'стоп
$asm
'подготовить порты к дальнейшему использованию ассемблерной программой
Cbi Ddrc , 0 'установим на Scl плавающую "1"
Cbi Portc , 0 'подготовим "0" для вывода
Cbi Ddrc , 1 'установим на Sda плавающую "1"
Cbi Portc , 1 'подготовим "0" для вывода
$end Asm
En_intr:
Enable Interrupts 'разрешить прерывания
Return
'------------------------------------------
'п/п записи статуса АЦП ADS1110 (быстрый режим) 240 изм/с. Шкала 1.024 В
Speed_adc:
' ------------ Запуск преобразования: 1 только в одиночном
' | --------- Запуск: 0 - автоматический, 1 - одиночное
' | |
' | | ------- Скорость: 00 - 240 SPS, 01 - 60 SPS
' | | | 10 - 30 SPS, 11 - 15 SPS
' | | |
' | | | ----- Усиление: 00 - 1 , 01 - 2
' | | | | 10 - 4 , 11 - 8
=============================================================================
34

===================================== Справочник по программированию «Bascom-AVR» ==
' | | | |
' | |||||
Value = &B00000001
Goto Wr_adc
'------------------------------------------
'п/п записи статуса АЦП ADS1110 (нормальный режим) 15 изм/с. Шкала 2.048 В
Wide_adc:
' ------------ Запуск преобразования: 1 только в одиночном
' | --------- Запуск: 0 - автоматический, 1 - одиночное
' | |
' | | ------- Скорость: 00 - 240 SPS, 01 - 60 SPS
' | | | 10 - 30 SPS, 11 - 15 SPS
' | | |
' | | | ----- Усиление: 00 - 1 , 01 - 2
' | | | | 10 - 4 , 11 - 8
' | | | |
' | |||||
Value = &B00001100
Goto Wr_adc
'------------------------------------------
'ЧТЕНИЕ ДАННЫХ ИЗ АЦП В R27(ст), R26(мл), статус в R31
Rd_adc:
$asm
' Cbi Ddrc , 0 'установим на Scl плавающую "1"
' Cbi Portc , 0 'подготовим "0" для вывода
' Cbi Ddrc , 1 'установим на Sda плавающую "1"
' Cbi Portc , 1 'подготовим "0" для вывода
Lds R31 , {Adradc} 'АДРЕС ДЛЯ ЧТЕНИЯ
Inc R31
Rcall Start_bit 'СТАРТ, ДАННЫЕ И ЖДЕМ ПОДТВЕРЖДЕНИЯ
'------------
Rcall R_byte 'ПРИМЕМ СТАРШИЙ БАЙТ
Mov R29 , R31 'ЗАПИШЕМ ДАННЫЕ В ОЗУ
Rcall Mstr_ack 'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ
Rcall R_byte 'ПРИМЕМ МЛАДШИЙ БАЙТ
Mov R28 , R31 'ЗАПИШЕМ ДАННЫЕ В ОЗУ
Rcall Mstr_ack 'ВЫДАЧА СИГНАЛА ПОДТВЕРЖДЕНИЯ
Rcall R_byte 'ПРИМЕМ СТАТУС
Rjmp No_ack 'ДА - БЕЗ ПОДТВЕРЖДЕНИЯ И СФОРМИРУЕМ СТОП-БИТ
'------------------------------------------
'порты PC.0, PC1 инициализированы на ввод (исходно DDRC.0 = 0, DDRC.1 = 0),
'а в порты PORTC.0 PORTC.1 записывается "0". Таким образом на линиях устанавливается "1".
'воспроизведение "0" производися переключением направления
'------------------------------------------
' Portc.0 - Scl, Portc.1 - Sda
'------------------------------------------
'ФОРМИРОВАНИЕ СТАРТ-БИТА И ЕЩЕ ДВЕ ОПЕРАЦИИ
Start_bit:
Cbi Ddrc , 0 'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l
Nop '------------------
Nop ' ¦ ¦
Cbi Ddrc , 1 '--- -
Nop 'Scl-----------------
Nop '
Sbi Ddrc , 1 '-------------
Nop ' ¦ ¦
Nop '------- ------
Sbi Ddrc , 0 'Sda-----------------
'--------------------------
'ВЫДАЧА НА ЛИНИЮ БАЙТА ДАННЫХ ЗАПИСАННЫХ В R31
T_byte:
Ldi R30 , 8 'ЧИСЛО БИТ
T_by0:
Sbi Ddrc , 0 'ЦИКЛ ПЕРЕДАЧИ
Rol R31 'СДВИГ
Brcc T_by1
Cbi Ddrc , 1 'порт в "1"
Rjmp T_by2
T_by1:
Sbi Ddrc , 1 'порт в "0"
T_by2:
'УСТАНОВКА И ОЖИДАНИЯ ОТПУСКАНИЯ ЛИНИИ Scl_l
Cbi Ddrc , 0 '- ----- - - -- -----
Dec R30 ' ¦ ¦ ¦ ¦ ¦ ¦
Brne T_by0 '------ ---- ----
'Scl--------------------------------
'
'---- ---------- --- - - --- -------
1   2   3   4   5   6   7   8


написать администратору сайта