Страница 245 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 05:20:14
akl
Как вариант
Код: Выделить всё
LSR R17
ROR R16
LSR R17
ROR R16
LSL R16
ROL R17
LSL R16
ROL R17
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 09:31:10
Pink-Pank
Вроде как lsl, lsr не работают с флагом Carry. У Вас потеряются биты.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 11:20:58
COKPOWEHEU
Это кто вам сказал? lsr сдвигает вправо, на место 7-го бита ставится 0, 0-й бит помещается в C. lsl - наоборот, на место 0-го ставится 0, 7-й уходит в С.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 11:33:22
Jack_A
COKPOWEHEU, вот именно. И бит от первого сдвига потеряется : В С - то он задвинулся, но во втором LSL/LSR не используется, заполняется нулем. Но и вариант zero648 не самый оптимальный.
Лучше всего так, как у
aki
Земляк
WiseLord меня опередил. Минчане, чего вам не рождествуется, все форумуетесь

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 11:35:14
WiseLord
Получается как-то так:
Код: Выделить всё
| R17 | R16 | C
--------+----------+--------------
| abcdefgh | ijklmnop | x
--------+----------+----------+---
LSR R17 | 0abcdefg | ijklmnop | h
ROR R16 | 0abcdefg | hijklmno | p
LSR R17 | 00abcdef | hijklmno | g
ROR R16 | 00abcdef | ghijklmn | o
| R17 | R16 | C
--------+----------+--------------
| abcdefgh | ijklmnop | x
--------+----------+----------+---
LSL R16 | abcdefgh | jklmnop0 | i
ROL R17 | bcdefghi | jklmnop0 | p
LSL R16 | bcdefghi | klmnop00 | j
ROL R17 | cdefghij | klnmop00 | o
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 11:58:57
СКАЗОЧНИК
Вопрос:
Код: Выделить всё
.equ DB4 = PORTC7
.equ DB5 = PORTВ6
.equ DB6 = PORTА0
.equ DB7 = PORTD3
Так будет работать? Т.е. я хочу подключить к разным пинам разных портов. Будет ли у меня далее в программе понимать, что DB4 - это PORTC7?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 12:11:49
Jack_A
Не будет. Директива .equ просто определяет числовой константе символьное имя для более легкого понимания и модификации исходника программы. Ну какое число можно сопоставить в директиве .equ DB4 = PORTC7 идентификатору 'PORTC7' так, чтобы одним числом выражался и адрес порта, и номер бита в нем ? И вообще, директива ассемблера -- не волшебная палочка, которая может делать то, что не может делать машинный код. Ну представьте, что вышеуказанную директиву компилятор принял, и у вас написано выражение, где это DB4 использовано. Какой машинный код будет сгенерирован в этом случае ?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 12:14:11
СКАЗОЧНИК
Блин.... И я об этом думаю. Поэтому и задал вопрос для того, чтобы подтвердить сомнения...
Тогда другой вопрос.
Хочу назначить выводы индикатора на любые пины ЛЮБЫХ портов МК. Как правильно их объявить (определить)? Хочу дальше в программе не заморачиваться и писать ДБ4, а подобие дефайнов само определяло, куда он там подключен.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 12:17:34
Jack_A
Я думаю, с помощью макросов. Изменяя параметры в вызове макроса или макроопределении, можно изменять назначение разрядов/адресов. А "само" типа "разбирайтесь по своим местам" ничего не сможет, по любому назначения определяются в программе, и для того, чтобы прогу лучше понимать/корректировать макросы -- хороший инструмент.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 12:29:45
СКАЗОЧНИК
А ведь, точно! Мне же по сути не нужны по отдельности линии DB, мне нужен целиком порт и значение в нем.
Спойлер
Код: Выделить всё
.equ DB7port = PORTC
.equ DB7pin = 3
.equ DB6port = PORTC
.equ DB6pin = 2
.equ DB5port = PORTC
.equ DB5pin = 1
.equ DB4port = PORTC
.equ DB4pin = 0
.equ RSport = PORTC
.equ RSpin = 5
.equ Eport = PORTC
.equ Epin = 4
.MACRO DATA ; Вызываем просто DATA TETRADA, предварительно положив в ТЕТРАДУ то, что нужно вывести.
lsr @0 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto1 ; Если С=0, то переходим по метке
sbi DB4port, DB4pin ; Иначе, выставляем бит в 1
rjmp Next1 ; Идем проверять следующий
Pusto1: cbi DB4port, DB4pin ; Выставляем бит в 0
Next1: lsr @0 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto2 ; Если С=0, то переходим по метке
sbi DB5port, DB5pin ; Иначе, выставляем бит в 1
rjmp Next2 ; Идем проверять следующий
Pusto2: cbi DB5port, DB5pin ; Выставляем бит в 0
Next2: lsr @0 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto3 ; Если С=0, то переходим по метке
sbi DB6port, DB6pin ; Иначе, выставляем бит в 1
rjmp Next3 ; Идем проверять следующий
Pusto3: cbi DB6port, DB6pin ; Выставляем бит в 0
Next3: lsr @0 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto4 ; Если С=0, то переходим по метке
sbi DB7port, DB7pin ; Иначе, выставляем бит в 1
rjmp Next1 ; Идем проверять следующий
Pusto4: cbi DB7port, DB7pin ; Выставляем бит в 0
.ENDM
А так будет работать? Думаю, что будет. Но код не оптимальный... Может кто ткнет носом, как проще вывести то, что находится в флаге переноса прямо на пин нужного порта?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 14:13:33
Леонид Иванович
Вывод на индикатор с произвольным расположением портов делал так:
Спойлер
Код: Выделить всё
;Write nibble to LCD:
;Input: temp7..temp4 - data nibble
LCD_WN: bbrc temp,7,lwr7_0
Port_LCD_D7_1 ;D7 <- 1
rjmp lwr6
lwr7_0: Port_LCD_D7_0 ;D7 <- 0
lwr6: bbrc temp,6,lwr6_0
Port_LCD_D6_1 ;D6 <- 1
rjmp lwr5
lwr6_0: Port_LCD_D6_0 ;D6 <- 0
lwr5: bbrc temp,5,lwr5_0
Port_LCD_D5_1 ;D5 <- 1
rjmp lwr4
lwr5_0: Port_LCD_D5_0 ;D5 <- 0
lwr4: bbrc temp,4,lwr4_0
Port_LCD_D4_1 ;D4 <- 1
rjmp lwrend
lwr4_0: Port_LCD_D4_0 ;D4 <- 0
lwrend: Port_LCD_E_1 ;E <- 1
rcall Delay ;delay 2 uS
Port_LCD_E_0 ;E <- 0
ret
Там используется макрос, вот мои макросы:
Спойлер
;***** Macros
.macro clbr ;clear bit in register
cbr @0,exp2(@1)
.endm
.macro stbr ;set bit in register
sbr @0,exp2(@1)
.endm
.macro bbrc ;branch if bit in register clear
sbrs @0,@1
rjmp @2
.endm
.macro bbrs ;branch if bit in register set
sbrc @0,@1
rjmp @2
.endm
.macro bbic ;branch if bit in I/O clear
sbis @0,@1
rjmp @2
.endm
.macro bbis ;branch if bit in I/O set
sbic @0,@1
rjmp @2
.endm
.macro addi ;add immediate
subi @0,-@1
.endm
.macro ldx ;load XL, XH with word
ldi XL,byte1(@0)
ldi XH,byte2(@0)
.endm
.macro ldy ;load YL, YH with word
ldi YL,byte1(@0)
ldi YH,byte2(@0)
.endm
.macro ldz ;load ZL, ZH with word
ldi ZL,byte1(@0)
ldi ZH,byte2(@0)
.endm
.macro table ;load Z pointer
ldi ZL,low (@0*2)
ldi ZH,high(@0*2)
.endm
.macro stdi ;store immediate indirect with displacement
ldi temp,@1
std @0,temp
.endm
.macro ldsx ;load XL, XH from memory
lds XL,@0+0
lds XH,@0+1
.endm
.macro ldsy ;load YL, YH from memory
lds YL,@0+0
lds YH,@0+1
.endm
.macro ldsz ;load ZL, ZH from memory
lds ZL,@0+0
lds ZH,@0+1
.endm
.macro stsx ;store XL, XH in memory
sts @0+0,XL
sts @0+1,XH
.endm
.macro stsy ;store YL, YH in memory
sts @0+0,YL
sts @0+1,YH
.endm
.macro stsz ;store ZL, ZH in memory
sts @0+0,ZL
sts @0+1,ZH
.endm
Описание пинов портов делал так:
Спойлер
Код: Выделить всё
;
Port С:
.equ DIRC = 0b11111111 ;Port C direction
.equ PUPC = 0b11111111 ;Port C pull-ups
.equ LCD_D6 = PC1 ;LCD D6 data line
.equ LCD_D7 = PC3 ;LCD D7 data line
.macro Port_LCD_D6_0 ;LCD_D6 = 0
cbi PORTC,LCD_D6
.endm
.macro Port_LCD_D6_1 ;LCD_D6 = 1
sbi PORTC,LCD_D6
.endm
.macro Port_LCD_D7_0 ;LCD_D7 = 0
cbi PORTC,LCD_D7
.endm
.macro Port_LCD_D7_1 ;LCD_D7 = 1
sbi PORTC,LCD_D7
.endm
Port D:
.equ DIRD = 0b11111110 ;Port D direction
.equ PUPD = 0b11111111 ;Port D pull-ups
.equ LCD_W = PD2 ;LCD W line
.equ LCD_E = PD3 ;LCD E line
.equ LCD_D4 = PD4 ;LCD D4 data line
.equ LCD_D5 = PD5 ;LCD D5 data line
.macro Port_LCD_W_0 ;LCD_W = 0
cbi PORTD,LCD_W
.endm
.macro Port_LCD_W_1 ;LCD_W = 1
sbi PORTD,LCD_W
.endm
.macro Port_LCD_E_0 ;LCD_E = 0
cbi PORTD,LCD_E
.endm
.macro Port_LCD_E_1 ;LCD_E = 1
sbi PORTD,LCD_E
.endm
.macro Port_LCD_D4_0 ;LCD_D4 = 0
cbi PORTD,LCD_D4
.endm
.macro Port_LCD_D4_1 ;LCD_D4 = 1
sbi PORTD,LCD_D4
.endm
.macro Port_LCD_D5_0 ;LCD_D5 = 0
cbi PORTD,LCD_D5
.endm
.macro Port_LCD_D5_1 ;LCD_D5 = 1
sbi PORTD,LCD_D5
.endm
На ассемблере, правда, не пишу уже 10 лет.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 07, 2015 14:21:44
СКАЗОЧНИК

Леонид Иванович, я после каждого вашего поста себя таким тупым чувствую...
Спасибо, конечно за помощь, даже пробую разобраться. ))) Однако надо вопрос с повестки дня снять. Все равно по своему напишу все...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт янв 08, 2015 14:12:58
Jack_A
Вот от холода и нечего делать

накропал универсальный макрос. Запуливает содержимое
бита С в нужный разряд нужного порта.
Код: Выделить всё
.MACRO C_in_PORT
brcs _10
clt
rjmp _15
_10: set
; Перекинули бит С в бит Т, специально для этих целей придуманный
_15: in temp,@0
andi r16,~(1<<@1)
; Считали порт и очистили нужный разряд
bld r16,@1
out @0,temp
; заполнили разряд тем чем надо и закинули обратно в порт.
.ENDMACRO
Пример вызова : C_in_PORT PORTB,3 temp из диапазона R16...R31 определяется ранее директивой .def
Мож пригодится.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт янв 08, 2015 14:21:30
СКАЗОЧНИК
Я забубенил так:
Спойлер
Код: Выделить всё
DB_LINE:
lsr R17 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto1 ; Если С=0, то переходим по метке
sbi DB4port, DB4pin ; Иначе, выставляем бит в 1
rjmp Next1 ; Идем проверять следующий
Pusto1: cbi DB4port, DB4pin ; Выставляем бит в 0
Next1: lsr R17 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto2 ; Если С=0, то переходим по метке
sbi DB5port, DB5pin ; Иначе, выставляем бит в 1
rjmp Next2 ; Идем проверять следующий
Pusto2: cbi DB5port, DB5pin ; Выставляем бит в 0
Next2: lsr R17 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto3 ; Если С=0, то переходим по метке
sbi DB6port, DB6pin ; Иначе, выставляем бит в 1
rjmp Next3 ; Идем проверять следующий
Pusto3: cbi DB6port, DB6pin ; Выставляем бит в 0
Next3: lsr R17 ; Сдвигаем вправо, крайний вывалится в С
brcc Pusto4 ; Если С=0, то переходим по метке
sbi DB7port, DB7pin ; Иначе, выставляем бит в 1
ret ;
Pusto4: cbi DB7port, DB7pin ; Выставляем бит в 0
ret
Блин, выше же выкладывал уже...

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт янв 08, 2015 14:49:24
Jack_A
С использованием бита Т не надо никого никуда двигать.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт янв 08, 2015 14:59:03
СКАЗОЧНИК
А как же если не двигать будут биты в С вываливаться?, чтобы потом их оттуда брать, потом в Т перекидывать, а дальше уже в порт. Тогды надо по другому задачу сформулировать.
Как раскидать младшую тетраду байта по различным пинам различных портов.

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт янв 08, 2015 22:45:19
Jack_A
Ну тогда конечно... Изначально я понял задачу рулить битами по состоянию бита С. А вообще если биты в портах вразнобой, элегантного решения не получится. Абы работало

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 14, 2015 17:57:42
СКАЗОЧНИК
Коты...

Может кому не лень будет, глянет в АВРстудии проект мой. Никак не могу понять, почему у меня руки из жопы...
Проект без ошибок в плане компиляции. Однако, после выхода из подпрограммы инициализации дисплея (по ret) попадает не туда, откуда начал...
Уже исправил одну проблему, когда перекидывало по ret выше на два адреса, а теперь НИЖЕ перекидывает...
З.Ы. За одно можете посмотреть мою реализацию выставления портов данных для индикатора. получилось вроде ОЧЕНЬ даже маленькая. ))))
Код: Выделить всё
DB_LINE: ; Выводим тетраду в линии дисплея
rcall CLR_PORT
sbrc R18, 4 ; Пропустить слудующую, еслли бит сброшен
sbi DB4port, DB4pin ; Ставим бит
sbrc R18, 5 ; Пропустить слудующую, еслли бит сброшен
sbi DB5port, DB5pin ; Ставим бит
sbrc R18, 6 ; Пропустить слудующую, еслли бит сброшен
sbi DB6port, DB6pin ; Ставим бит
sbrc R18, 7 ; Пропустить слудующую, еслли бит сброшен
sbi DB7port, DB7pin ; Ставим бит
ret
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 14, 2015 18:28:06
Pink-Pank
СКАЗОЧНИК писал(а):Коты...

Может кому не лень будет, глянет в АВРстудии проект мой. Никак не могу понять, почему у меня руки из жопы...

Дык это не к нам. Это к проктологу.
А вообще, проверяйте стек. Где-то с push/pop не доглядели
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср янв 14, 2015 18:30:52
СКАЗОЧНИК
В том то и дело, что стек инициализирован. Но он используется только самими подпрограммами по (rcall и ret). Я сам ничего в стек не кладу....

Все туда кладет и берет компилятор.
При отладке смотрел. Переполнений не происходит никаких, т.к. их и не может быть... Всего на три или четыре глубины прогружается в стек.
ЗЫ. Я думаю, у меня проблема со структурой самой программы и подключением ИНКЛУДАМИ... Где-то я последовательность нарушаю... Все должно быть элементарно, а я не вижу.