|
AVR204, Непонятки |
|
|
|
Apr 17 2011, 10:08
|

Профессионал
    
Группа: Свой
Сообщений: 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
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 11:56
|

Профессионал
    
Группа: Свой
Сообщений: 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 , согласно приведённому коду НИКОГДА не попадут. А то что нет прямого сложения- известный факт
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 12:04
|
Гуру
     
Группа: Участник
Сообщений: 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 ???
|
|
|
|
|
Apr 20 2011, 12:11
|

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

|
Цитата(rx3apf @ Apr 20 2011, 16:04)  Как так ? А это что: CODE bBCDx_3: ld tmp16a,-Z ;get (Z) with pre-decrement ??? Я уверен , что Вы сами ответите на свой вопрос . Я ради интереса проиммулировал его. Два абсолютно независимых от друг друга кода в одном аппноуте. Могу добавить по всему коду свои комменты , но что бы не сбивать независимую оценку пока этого не сделал .
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 12:54
|

Профессионал
    
Группа: Свой
Сообщений: 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
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 13:02
|
Гуру
     
Группа: Участник
Сообщений: 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)  Вам знакомо понятие предекремента? Тут все еще хуже...
|
|
|
|
|
Apr 20 2011, 13:25
|

Профессионал
    
Группа: Свой
Сообщений: 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 корявый, да. Но все работоспособно (если чуть-чуть подумать).
Тут все еще хуже... Уже подумал и исправил, дома лежит рабочий вариант- приду выгружу. Хотя как Вы видите из начала темы , я использую другой алгоритм
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 13:37
|

Профессионал
    
Группа: Свой
Сообщений: 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 регистр,
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 20 2011, 13:40
|
Гуру
     
Группа: Участник
Сообщений: 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 регистр, Да прочитайте, в конце концов, даташит на любой кристалл, там, где описывается распределение адресного пространства, и не позорьтесь.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|