реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> AVR204, Непонятки
ILYAUL
сообщение Apr 17 2011, 10:08
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Всем привет!

Месяца два назад звонил знакомый с вопросом по этому произведению фирмы Atmel. Тогда я не придал этому значения- просто дал рабочий код , но мыслишка осталась.
Разбирая по папкам данные на компе- порядок наводил, наткнулся на AVR204 и решил взглянуть поближе на сей код.
И хотя в описании алгоритма работы есть строчки: Add $03 to result byte2 и т.д. в коде я этого не вижу. Регистр tmp16a (судя по коду) всегда содержит 0 или я что-то не понял

Весь код:

Код
;***************************************************************************
;*
;* "bin2BCD16" - 16-bit Binary to BCD conversion
;*
;* This subroutine converts a 16-bit number (fbinH:fbinL) to a 5-digit
;* packed BCD number represented by 3 bytes (tBCD2:tBCD1:tBCD0).
;* MSD of the 5-digit number is placed in the lowermost nibble of tBCD2.
;*
;* Number of words    :25
;* Number of cycles    :751/768 (Min/Max)
;* Low registers used    :3 (tBCD0,tBCD1,tBCD2)
;* High registers used  :4(fbinL,fbinH,cnt16a,tmp16a)    
;* Pointers used    :Z
;*
;***************************************************************************

;***** Subroutine Register Variables

.equ    AtBCD0    =13;address of tBCD0
.equ    AtBCD2    =15;address of tBCD1

.def    tBCD0    =r13;BCD value digits 1 and 0
.def    tBCD1    =r14;BCD value digits 3 and 2
.def    tBCD2    =r15;BCD value digit 4
.def    fbinL    =r16;binary value Low byte
.def    fbinH    =r17;binary value High byte
.def    cnt16a    =r18;loop counter
.def    tmp16a    =r19;temporary value

;***** Code

bin2BCD16:
    ldi    cnt16a,16                  ;Init loop counter    
    clr    tBCD2;clear result (3 bytes)
    clr    tBCD1        
    clr    tBCD0        
    clr    ZH;clear ZH (not needed for AT90Sxx0x)
bBCDx_1:lsl    fbinL;shift input value
    rol    fbinH;through all bytes
    rol    tBCD0;
    rol    tBCD1
    rol    tBCD2
    dec    cnt16a;decrement loop counter
    brne    bBCDx_2;if counter not zero
    ret    ;   return

bBCDx_2:ldi    r30,AtBCD2+1;Z points to result MSB + 1
bBCDx_3:
    ld    tmp16a,-Z                  ;get (Z) with pre-decrement
;----------------------------------------------------------------
;For AT90Sxx0x, substitute the above line with:
;
;    dec    ZL
;    ld    tmp16a,Z
;
;----------------------------------------------------------------
    subi    tmp16a,-$03;add 0x03
    sbrc    tmp16a,3                  ;if bit 3 not clear
    st    Z,tmp16a;store back
    ld    tmp16a,Z                  ;get (Z)
    subi    tmp16a,-$30;add 0x30
    sbrc    tmp16a,7                  ;if bit 7 not clear
    st    Z,tmp16a                ;store back
    cpi    ZL,AtBCD0                  ;done all three?
    brne    bBCDx_3;loop again if not
    rjmp    bBCDx_1

Прикрепленные файлы
Прикрепленный файл  AVR204_BCD_Arithmetics.pdf ( 94.37 килобайт ) Кол-во скачиваний: 13
 


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Apr 20 2011, 10:09
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Десятая команда снизу subi tmp16a,-$03;add 0x03

В AVR нет встроенной инструкции "Сложение РОН с константой", поэтому используют "Вычитание константы из РОН" - вычитают из регистра константу с противоположным знаком, что эквивалентно сложению.
По поводу данной аппноты не скажу, а вот по умножению/делению 16 битных чисел со знаком и без в своё время повторял, работало без нареканий. Так что сомнения в работоспособности приведённого кода излишние.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 11:56
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Sergey_Aleksandrovi4 @ Apr 20 2011, 14:09) *
Десятая команда снизу subi tmp16a,-$03;add 0x03

В AVR нет встроенной инструкции "Сложение РОН с константой", поэтому используют "Вычитание константы из РОН" - вычитают из регистра константу с противоположным знаком, что эквивалентно сложению.
По поводу данной аппноты не скажу, а вот по умножению/делению 16 битных чисел со знаком и без в своё время повторял, работало без нареканий. Так что сомнения в работоспособности приведённого кода излишние.

Вы , несколько заблуждаетесь по поводу subi tmp16a,-$03 . Регистр tmp16a описан в def как временный регистр - в который должны передоваться последовательно данные из tBCD0 - tBCD3 и производится необходимые действия . Весь вопрос и состоит в том , что в этот регистр данные из tBCD0 - tBCD3 , согласно приведённому коду НИКОГДА не попадут. А то что нет прямого сложения- известный факт


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Apr 20 2011, 12:04
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(ILYAUL @ Apr 20 2011, 15:56) *
Весь вопрос и состоит в том , что в этот регистр данные из tBCD0 - tBCD3 , согласно приведённому коду НИКОГДА не попадут.

Как так ? А это что:
CODE
bBCDx_3:
ld tmp16a,-Z ;get (Z) with pre-decrement

???
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 12:11
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(rx3apf @ Apr 20 2011, 16:04) *
Как так ? А это что:
CODE
bBCDx_3:
ld tmp16a,-Z ;get (Z) with pre-decrement

???

Я уверен , что Вы сами ответите на свой вопрос . Я ради интереса проиммулировал его. Два абсолютно независимых от друг друга кода в одном аппноуте. Могу добавить по всему коду свои комменты , но что бы не сбивать независимую оценку пока этого не сделал .


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Apr 20 2011, 12:16
Сообщение #6


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(ILYAUL @ Apr 20 2011, 16:11) *
Я уверен , что Вы сами ответите на свой вопрос . Я ради интереса проиммулировал его. Два абсолютно независимых от друг друга кода

Какие-такие "два независимых кода" ? tmp16a загружается из RAM по адресу, определяемому Z, с предекрементом. Z адресует аккумулятор BCD. Все в точности как задумано.

Сообщение отредактировал rx3apf - Apr 20 2011, 12:16
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 12:54
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(rx3apf @ Apr 20 2011, 16:16) *
Какие-такие "два независимых кода" ? tmp16a загружается из RAM по адресу, определяемому Z, с предекрементом. Z адресует аккумулятор BCD. Все в точности как задумано.

Ладно хорошо начнём:
Код
;***************************************************************************
;*
;* "bin2BCD16" - 16-bit Binary to BCD conversion
;*
;* This subroutine converts a 16-bit number (fbinH:fbinL) to a 5-digit
;* packed BCD number represented by 3 bytes (tBCD2:tBCD1:tBCD0).
;* MSD of the 5-digit number is placed in the lowermost nibble of tBCD2.
;*
;* Number of words    :25
;* Number of cycles    :751/768 (Min/Max)
;* Low registers used    :3 (tBCD0,tBCD1,tBCD2)
;* High registers used  :4(fbinL,fbinH,cnt16a,tmp16a)    
;* Pointers used    :Z
;*
;***************************************************************************

;***** Subroutine Register Variables

.equ    AtBCD0    =13;address of tBCD0    Какой нах адрес - простой счётчик
.equ    AtBCD2    =15;address of tBCD1   В дальнейшем used  ZL
[sub]Это не комментируется - стандарт[/sub]
.def    tBCD0    =r13;BCD value digits 1 and 0
.def    tBCD1    =r14;BCD value digits 3 and 2
.def    tBCD2    =r15;BCD value digit 4
.def    fbinL    =r16;binary value Low byte
.def    fbinH    =r17;binary value High byte
.def    cnt16a    =r18;loop counter
.def    tmp16a    =r19;temporary value

;***** Code

bin2BCD16:
    ldi    cnt16a,16                 ;Init loop counter    Присваиваем 0x10 счётчику
    clr    tBCD2;clear result (3 bytes)
    clr    tBCD1        
    clr    tBCD0        
    clr    ZH;clear ZH (not needed for AT90Sxx0x) Я даже не вспомню у когого AVR- SRAM ( свободная от всех дополнительных регистров начнётся с 0)
При эммуляциии вместо этого сделал  так
Ldi ZH,high(0x200)

bBCDx_1:
    lsl    fbinL;shift input value
    rol    fbinH;through all bytes
    rol    tBCD0;
    rol    tBCD1
    rol    tBCD2
    dec    cnt16a;decrement loop counter
    brne    bBCDx_2;if counter not zero                                      Вот отсюда всё и начинается
Как мы помним -счётчик 16 , естественно он не равен Zero поэтому , дружно , xxxeм на bBCDx_2:
    ret   ;   return

bBCDx_2:ldi    r30,AtBCD2+1;Z points to result MSB + 1 ,-

где в ZL ( мы же помним что R30 = ZL) пишем 0x0F+1 = 0x10
В итоге получаем адрес 0x10 (аппноут) , ну в моём случае 0x210
И что же мы имеем по этим адресам - да не XXXя не имеем , хорошо , что у меня макрос память чистит всю, во момент включения , так , что я 00
Так , что мы загрузим tmp16A? 0x00

И с этого момента программа делится на два , абсолютно независимых куска , где то что-то там сдвигается , где то к 0 прибавляется 3 или 0x30
И всё это красиво и не зависимо крутится

bBCDx_3:
    ld    tmp16a,-Z                 ;get (Z) with pre-decrement
;----------------------------------------------------------------
;For AT90Sxx0x, substitute the above line with:
;
;    dec    ZL
;    ld    tmp16a,Z
;
;----------------------------------------------------------------
    subi    tmp16a,-$03;add 0x03
    sbrc    tmp16a,3                 ;if bit 3 not clear
    st    Z,tmp16a;store back
    ld    tmp16a,Z                 ;get (Z)
    subi    tmp16a,-$30;add 0x30
    sbrc    tmp16a,7                 ;if bit 7 not clear
    st    Z,tmp16a               ;store back
    cpi    ZL,AtBCD0                 ;done all three?
    brne    bBCDx_3;loop again if not
    rjmp    bBCDx_1


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 20 2011, 13:00
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ILYAUL @ Apr 20 2011, 16:54) *
Ладно хорошо начнём:

Вам знакомо понятие предекремента?
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Apr 20 2011, 13:02
Сообщение #9


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(ILYAUL @ Apr 20 2011, 16:54) *
Ладно хорошо начнём:
......
.equ AtBCD0 =13;address of tBCD0 Какой нах адрес - простой счётчик
...

В итоге получаем адрес 0x10 (аппноут) , ну в моём случае 0x210
И что же мы имеем по этим адресам - да не XXXя не имеем , хорошо , что у меня макрос память чистит всю, во
...

Собственно, на этом можно и закончить. Учите архитектуру AVR, и особое внимание обратите на распределение адресного пространства. Аппликуха корявая, да. И AVRASM корявый, да. Но все работоспособно (если чуть-чуть подумать).

Цитата(aaarrr @ Apr 20 2011, 17:00) *
Вам знакомо понятие предекремента?

Тут все еще хуже...
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 13:25
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(aaarrr @ Apr 20 2011, 17:00) *
Вам знакомо понятие предекремента?

Вы что считаете , что я не могу посчитать 15+1 и что такое преддекремент мне известно. Посмотрите присвоение equ AtBCD2 Мы говорим о том , что ATMEL с этим аппноутом накосячил.

Цитата(rx3apf @ Apr 20 2011, 17:02) *
Собственно, на этом можно и закончить. Учите архитектуру AVR, и особое внимание обратите на распределение адресного пространства. Аппликуха корявая, да. И AVRASM корявый, да. Но все работоспособно (если чуть-чуть подумать).


Тут все еще хуже...

Уже подумал и исправил, дома лежит рабочий вариант- приду выгружу. Хотя как Вы видите из начала темы , я использую другой алгоритм


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 20 2011, 13:32
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ILYAUL @ Apr 20 2011, 17:25) *
Вы что считаете , что я не могу посчитать 15+1 и что такое преддекремент мне известно. Посмотрите присвоение equ AtBCD2 Мы говорим о том , что ATMEL с этим аппноутом накосячил.

Ничего не накосячил: 15 - это адрес регистра r15 (tBCD2).
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Apr 20 2011, 13:34
Сообщение #12


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(ILYAUL @ Apr 20 2011, 17:25) *
Вы что считаете , что я не могу посчитать 15+1 и что такое преддекремент мне известно. Посмотрите присвоение equ AtBCD2 Мы говорим о том , что ATMEL с этим аппноутом накосячил.

Нисколько. Странное на первый взгляд присвоение - это из-за кривизны самого AVRASM. Логика же программы совершенно правильная.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 13:37
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(aaarrr @ Apr 20 2011, 17:32) *
Ничего не накосячил: 15 - это адрес регистра r15 (tBCD2).

.def tBCD2 =r15;BCD value digit 4
а это тогда что?
И с каких пор , назначение абстрактной переменной привязано к регистру .equ AtBCD2 =15 , а если я напишу .equ AtBCD2=24 - это что 24 регистр,


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Apr 20 2011, 13:40
Сообщение #14


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(ILYAUL @ Apr 20 2011, 17:37) *
.def tBCD2 =r15;BCD value digit 4
а это тогда что?

А это сам регистр, в котором набирается BCD. Просто нельзя записать ldi ZL,low(r15), приходится вот так изгаляться...
Цитата
И с каких пор , назначение абстрактной переменной привязано к регистру .equ AtBCD2 =15 , а если я напишу .equ AtBCD2=24 - это что 24 регистр,

Да прочитайте, в конце концов, даташит на любой кристалл, там, где описывается распределение адресного пространства, и не позорьтесь.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 20 2011, 13:43
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(rx3apf @ Apr 20 2011, 17:34) *
Нисколько. Странное на первый взгляд присвоение - это из-за кривизны самого AVRASM. Логика же программы совершенно правильная.

Простите какая ,тут логика и причём здесь AVRASM , если в temp регистр не передаётся число , он проходит весь цикл и проверяет BCD0-BCD3 а в Sram по этим адресам 00, после сдвига нет записи в sram- откуда темпу данные брать?!


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01505 секунд с 7
ELECTRONIX ©2004-2016