Файл: Справочник по программированию «Bascom-AVR» (М.Л. Кулиш).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 17.06.2025
Просмотров: 755
Скачиваний: 3
===================================== Справочник по программированию «Bascom-AVR» ==
Пример 5 - Прерывание от изменения уровня на линиях порта
'---------------------------------------------------------------------------------- |
"m644def.dat" |
'для чипа ATMega644 |
$regfile = |
||
' ...... |
||
Dim Num_port As Byte |
'номер порта с изменившимся уровнем |
|
Dim Dub_pa |
As Byte |
'дублер порта A |
Dim Dub_pb |
As Byte |
'дублер порта B |
Dim Dub_pc |
As Byte |
'дублер порта C |
Dim Dub_pd |
As Byte |
'дублер порта D |
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: |
Num_port <> 0 Then |
|
If |
||
Print Num_port : Num_port = 0 |
||
End If |
||
Goto Mc |
||
'-------------------------------------- |
обработки прерываний от изменения уровня, сообщающие главной программе |
|
'программы |
||
'о наличии |
изменения ненулевым значением переменной Num_port |
|
'-------------------------------------- |
порта A |
|
'по линиям |
||
Pc_int0: |
Pina Xor Pcamsk : Tmpb = Pina Xor Dub_pa : Num_port = 0 |
|
Tmpb = |
||
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: |
'повторять пока регистр Tmpb не станет равным нулю |
While Tmpb <> 0 |
|
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 |
r24,#0 |
|
ldi |
||
sts |
$100,r24 |
'добавить в Num_port номер позиции единицы |
;Gosub Search_pin |
||
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: |
'повторять пока регистр Tmpb не станет равным нулю |
|
While Tmpb <> 0 |
r16,$105 |
|
lds |
||
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 |
r26,#0 |
|
ldi |
||
ldi |
r27,#1 |
|
ld |
r24,x |
|
subi |
r24,#255 |
|
st |
x,r24 |
|
;Wend |
0000036A |
|
jmp |
||
0000038E: |
||
ret |
||
;------ |
||
;библиотечная подпрограмма сдвига вправо на число в R25 |
||
000003C6: |
r25,#0 |
|
cpi |
||
breq |
000003D4 |
|
ld |
r24,x |
|
000003CC: |
r24 |
|
lsr |
||
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