[uquote="titr",url="/forum/viewtopic.php?p=3448530#p3448530"]Прошу помощи ... Контроллер PIC18F2620.
Вычисляемый переход работает как то неверно, т. е. если я присваиваю W=0, попадаю к CODE_0,[/uquote]
Хороший вопрос, лично я не быстро нашёл ответ.
Надо помнить что защёлки указателя исполняемого адреса - не заполняются сами по себе, а лишь при явном обращении проги к PC на чтение.
Надо помнить что защёлки указателя исполняемого адреса - могут портится в прерываниях и тогда их тоже надо сохранять при входе/выходе прерывания.
Лично я при написании/отладке прожекта
http://vfd.psw2.ru/ использовал 4 варианта вычисляемого перехода:
Спойлер
Код: Выделить всё
Все способы портят WREG, так что это не считается за особенность.
1. Самый надёжный способ, но нет изохронности.
; Если веток мало (дзен около 5-7, зависит от контроля границ) или сохранять PCLAT не хочется - то быстрее/удобнее работает тупой перебор:
; без порчи защёлок вычисляемым переходом и без необходимости контролировать номер ветки:
movf Case_Num,W,ACCESS ;
bz Case_0 ;
dcfsnz WREG,W,ACCESS
bra Case_1 ;
dcfsnz WREG,W,ACCESS
bra Case_2 ;
dcfsnz WREG,W,ACCESS
bra Case_3 ;
; Если номер > 3 то выполняется 4 ветка
; dcfsnz WREG,W,ACCESS
2. Макрос GoToWreg - остатки моей попытки просто складывать 24 бита адреса
GoToWreg macro TempBuff,Adr1 ; Использует Tmp 1 байт
; Переход на количество команд - смещение из WREG
; Команды располагаются непосредственно за макросом
; 20/03/2017 пробую укоротить максимально, Вроде 10 команд если 1 сдвиг
local BeginJumpBlock;
movwf TempBuff,Adr1; Спасаем РабРег
movlf High(BeginJumpBlock),PCLATH,ACCESS ; ПОРТИТ РАБРЕГ
bcf _C ; Чистим входной перенос
rlcf TempBuff,W,Adr1 ; Удваиваем номер байта для вычисляемого перехода
addlw Low(BeginJumpBlock) ; смещение в РабРеге,
btfsc _C ; Перенос был при сложении ?
incf PCLATH,F,ACCESS ; прибавляю 1 к среднему байту
clrf PCLATU,ACCESS ; Верхний - всегда =0
movwf PCL,ACCESS ; Заполняем PCLAT
BeginJumpBlock
endm
3. Макрос BraReg ; 8 команд, но BRA шагает лишь на 2^10 команд
BraReg macro RegPoint,Adr1 ; смещение номера БРА - в регистре
; Смещение - не изменяется
; Переход на количество команд - смещение из Регистра
; Команды располагаются непосредственно за макросом
local BeginJumpBlock;,Continue,Continue1 ;
movlf High(BeginJumpBlock),PCLATH,ACCESS ; ПОРТИТ РАБРЕГ
bcf _C ; Чистим входной перенос
rlcf RegPoint,W,Adr1 ; Удваиваем номер байта для вычисляемого перехода
addlw Low(BeginJumpBlock) ; смещение в РабРеге,
btfsc _C ; Перенос был при сложении ?
incf PCLATH,F,ACCESS ; прибавляю 1 к среднему байту
clrf PCLATU,ACCESS ; Верхний - всегда =0
movwf PCL,ACCESS ; Заполняем PCLAT
BeginJumpBlock
endm
4. Интересная сабпрога какого-то американца, примерно 6+4 циклов команд
; K8LH RE: PIC18F4331: COMPUTED GOTO!• Thursday, August 17, 2006 8:22 AM (permalink)
;http://www.microchip.com/forums/m182713.aspx javascript:void(showMsgNum(182838))
; Вариант вычисляемых переходов через саб прогу - быть могет удобен ?
; Две точки входа у одной сабпроги - в зависимости от используемых команд перехода.
CaseGoTo: ;; Смещение - WREG
bcf _C ; автор не чистил входной перенос - Чистка переноса на входе для пары сдвигов
rlncf WREG,F,ACCESS ; первый сдвиг
CaseBra: ; Второй вход - единственный сдвиг
rlncf WREG,F,ACCESS ;
bcf WREG,0,ACCESS ; чистка младшего бита для одного сдвига
addwf TOSL,f,ACCESS ; младший
movlw 0x0 ; авторская метка/фишка вместо традиционного CLRF WREG чистим
addwfc TOSH,f,ACCESS ; средний
;addwfc TOSU,f,ACCESS; старший for > 64-kbyte memory
return; Адрес возврата суммирован со смещением из WREG
[uquote="BOB51",url="/forum/viewtopic.php?p=3448814#p3448814"]Другое дело из "улучшенных среднемладших" - команды BRA addr, CALLW и BRW те действительно штука весьма вкусненькая![/uquote]
А можно подробнее - в чём именно их вкусность и как именно её использовать ?
[uquote="BOB51",url="/forum/viewtopic.php?p=3448922#p3448922"]а еще удобнее воспользоваться старой рекомендацией мелкощипа - все вектора переходов ставить в банке 0.[/uquote]
Это удобно если "под каждую задачу - свой мелкопроц" повышать продажи микрочипов.
Это неудобно если проект модульный и перерастает 256 команд. Как делить первые 256 команд между модулями, которых может не быть ?
Как преодолевать границы 256 байт "страниц" памяти программ, если блок переходов не вписывается в страницу ?
Варианты выше - они были найдены именно для преодоления границ 256 команд и тупого сложения смещения с PC, работают в любом месте кода.
Если кода более 64 кб - то надо раскоментить обработку/присваивание PCLATHU.
[uquote="titr",url="/forum/viewtopic.php?p=3449619#p3449619"]BRA BRA BRA!!!!
Бесконечное тебе спасибо человек! Не зря я сюда за помощью пришел)))).
Код: Выделить всё
; CLRF PCLATH
; CLRF PCLATU
RLNCF temp_code,W ; СДВИГ, УМНОЖАЮ НА 2
ORG 0X600
ADDWF PCL,F ; по лично мне здесь ошибка - используются PCLATH и PCLATU но в них неизвестные значения
; которые при сбросе могут быть любыми
BRA CODE_0
BRA CODE_1
BRA CODE_2
BRA CODE_3
BRA CODE_4
BRA CODE_5
BRA CODE_6
BRA CODE_7
[/uquote]
И как, устойчиво работает ?
Особенно при наличии нескольких таких вычисляемых переходов в проге ?
[uquote="BOB51",url="/forum/viewtopic.php?p=3448922#p3448922"]Со среднемладшими подсказать проще, с 18-й пока только "разбор полетов" по системе команд прорадатывал - редкостный кристалл и дорогой для тренировок, да и задачку надо для такого посолиднее "лампочек-кнопочек" (пока не нашел чего примутить)...[/uquote]
Быть могет частотничек для компрессора в гараже запилить ?