Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

[BUG?] PIC PCL PCLATH (calculated goto)
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=2394
Страница 1 от 2

Автор:  the_real_maniac [ Нед Май 21, 2006 8:47 pm ]
Заглавие:  [BUG?] PIC PCL PCLATH (calculated goto)

Напоследък удобството на тези изчислени goto-та ми излиза скъпо при работа с PIC ... лошото е , че не е логично да е така.

Изчислено goto - нищо ново под слънцето.

От Майркочип предупреждават че при ползване на addwf PCL,F трябва да се има предвид пресичането "страница" от паметта.

Ако се намираме на някои адрес Х и скока ни е възможно да пресече страница, PCLATH (съдържащ горният адрес от програмният брояч) няма да се инкрементира , тъй като операцията е само с PCL и няма прехвърляне в PCLATH при такава ситуация:


ала PCL = 0xFA = 250 , W = 0x0A = 10 PCLATH=1

addwf PCL,F
PCL = 5
PCLATH=1 , а не става 2 -> остава непроменен !

Хората предупреждават за този възможен проблем. ОК

Обаче оказва се, че при операцията с PCL ПОНЯКОГА се нулира PCLATH 8O без да сме на такъв кръстопът


Код:

92:                   bsf      PORTB,6    ; <- това съм го сложил
   122    1706     BSF 0x6, 0x6                ;за да следя къде ходи програмата
93:                   movfw   NMC
   123    082F     MOVF 0x2f, W
94:                   addwf   PCL,F
   124    0782     ADDWF 0x2, F             
95:                   goto   stop_now         
   125    2928     GOTO 0x128                 
96:                   goto   start_in           
   126    2932     GOTO 0x132
97:                   goto   stop_in
   127    2962     GOTO 0x162
98:                ;
99:                ;
100:               
101:               ;####################################;
102:               ;####################################;
103:               
104:               stop_now:
105:               
106:                  bsf      PORTB,7       <- дотук не се стига
   128    1786     BSF 0x6, 0x7
107:               
108:                  movlw   SR_RAMBASE
   129    3073     MOVLW 0x73



94: addwf PCL,F
124 0782 ADDWF 0x2, F

PC=124, PCL=24, PCLATH=1, W = 0, вместо PC=125, PCL=25, PCLATH=1 става PC=25 , PCL=25 , PCLATH=0 !!!!

0x124 = 292 минали сме страницата, която е на 255 , не сме на граница и няма опасност да минем страница , тъй като както се вижда мах W=2

Ще кажете няма логика -> е да ама не. Точно това става , защото (!)
На програмна памет с адрес 0х25 сложих bsf PORTB,0 (никъде другаде в програмата го няма операции с PORTB,0)
и познайте как след като светна PORTB,6 вместо PORTB,7 светна PORTB,0.

-> (инструкция срещана само веднъж в програмата и то на адрес 0x25 !!!)

-> Ако W>2 някак си , но това не е възможно, тъй като преди това се проверява , паметта ще скача още по-напред, а не на 25 адрес

-> 0х25 се явява _края_ на едно _Софтуерно_ закъснение от 6 секунди , а уверявам ви веднага след PORTB,6 светва и PORTB,0 (всъщност то е us , така че за мен си светват едновременно :-) ). Факта остава няма никакви 6сек. , да не говорим , че ако програмата следва нормалният си ход тези 6 сек не се стигат в този случей когато се прави преход към stop_now и т.н, и т.н, но това са подробности/

Реших да пиша:

1. Защото може да се бъркам нещо и това да е моя грешка, НО
2. Доста време вложих да СЪМ 100% сигурен че наистина това се случва. И след като поне за мен това вече е факт , реших да Ви предупредя да го имате в предвид.

Преди не съм имал проблем с тези calc goto , а не съм ги и мислил толкова, но напоследък ...

Автор:  evc [ Пон Май 22, 2006 9:27 am ]
Заглавие: 

Пробвай преди "addwf PCL,f" да сложиш "andlw 0x03". За всеки случай! И опитай да забраниш прекъсванията по време на компютед гоуто-то. НИКОГА не съм имал проблем с този метод. Използвам го дори за софтуерна ШИМ емулация. Не е проблема в ПИК-а, по скоро в задклавиатурното устройство! :D

Автор:  the_real_maniac [ Пон Май 22, 2006 1:05 pm ]
Заглавие: 

Е сега :-)

Значи да предположим , че W e повече от 2 и прескача мойте изчислени goto-та пак ще ходи напред.

Има само един вариант да стигне до 25 адрес и той е да бъде ИЗВИКАНО 6-сек закъснени , то да свърши и тогава , тъй като 25 адрес се явява краят на 6 сек закъснение. , точно инструкцията* преди return от него.
Там имаше clrwdt , вместо това аз сложих да ми светне PORTB,0. (+ WDT=OFF)

Но 6 сек закъснение няма, едновременно светва PORTB,6 и 0 => или скача на адрес 25, или по някакво странно стечение на обстоятелствата PORTB,0 светва. (аз не вярвам в случайните неща :-) )

А ако искам да разбера дали W какво е ще си го пратя по серийният и ще видим.

едит:

Цитат:

; main.asm
; 4MHZ clock ( XT OSC )

ERRORLEVEL -302

LIST p=PIC16F628A
#include<p16f628a.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _BODEN_OFF
#define RAMBASE 0x20

#define RESET_VECTOR 0x000
#define INT_VECTOR 0x004

ORG RESET_VECTOR
goto start
; ORG INT_VECTOR
; goto interrupt

start:

bcf STATUS,RP0

movlw 0x07
movwf CMCON

bsf STATUS,RP0

clrf TRISA
clrf TRISB

bcf STATUS,RP0

clrf PORTA
clrf PORTB

goto calc_goto

;########################;
;########################;

ORG 0x25

bsf PORTB,0
goto $

;########################;
;########################;

ORG 0x123

calc_goto:

movlw 0 ;123
addwf PCL,F ;124
goto stop_now;125

stop_now:

bsf PORTB,7
goto $

END


Записвам на пикльото :lol: , пускам и светва PORTB,0 :-)

А де :-)

едит2: даже ми се иска грешката да е в мене , защото така с addwf е много удобно, отколкото да се проверява за всяка стойност по-отделно.

Автор:  [ Пон Май 22, 2006 11:49 pm ]
Заглавие: 

Да не би да ги палиш светодиодите с GND ?

Автор:  the_real_maniac [ Вто Май 23, 2006 12:00 am ]
Заглавие: 

Pirev - не те разбрах. 8O

Ааа ... да не би label-a stop_now да те притеснява нещо, просто реших да го запазя от горе :-)
Иначе тези bsf PORTB,x са само за индикация видимо на платката. Ммммм абе пак не мога да разбера от къде ти хрумна този въпрос :?

По-интересно ми е да кажеш относно addwf-то.

Просто след първата страница с прог. паметта такива изчислени скокове не работят, очевидно защото PCLATH=0 без идея / причина. 8O :cry:

Автор:  [ Вто Май 23, 2006 12:08 am ]
Заглавие: 

Няма нищо интересно в случая, не си чел добре документацията. Когато си извън първите 256 байта програмна памет, когато правиш сметки с PCL, задължително трябва да заредиш PCLATH със старшия байт на адреса на таблицата:
Код:

org 0x123
SomeTable:
movlw HIGH(SomeTable)
movwf PCLATH
movf offset,W
addwf PCL,F
goto SomeWhere1
...
goto  SomeWhere128



Пробвай с offset от 0 до 127 да видиш как ще ти мине през всичките goto независимо къде си пляснал таблицата.

За GND те питах, тъй като може да си сложил само 2 диода, единия на PORTB.0, другия на PORTB.7. Ако активното ти ниво е GND, след RESET палиш светодиодите с clrf PORTB, и след това щом се пали този на PORTB.0, значи кода ти е работел правилно ( защото гасиш този на PORTB.7 ). Обратна логика на програмата ти. Но причината не е в нивата, а в това което по-горе ти писах.

Автор:  Gogo [ Вто Май 23, 2006 12:32 pm ]
Заглавие: 

Чудя се, защо не ги спрат вече от производство тия 16-ки :-)

Автор:  Bezmozachen [ Вто Май 23, 2006 4:57 pm ]
Заглавие: 

Не помня как беше при 16-ките, но предполагам е както при 18-ките. PCLATH, PCLATU са shadow регистри, които при прочитане на PCL се обновяват със съдържанието на останалите байтове от програмния брояч, а при запис в PCL, тяхното съдържание се записва в програмния брояч. T.e. не е казано, че PCLATH съдържа текущата стойност на старшия байт на програмния брояч. Мисля от там идват неочакваните резултати за теб.

Автор:  the_real_maniac [ Сря Май 24, 2006 2:45 am ]
Заглавие: 

[quote=pirev]
Когато си извън първите 256 байта програмна памет, когато правиш сметки с PCL, задължително трябва да заредиш PCLATH със старшия байт на адреса на таблицата[/quote]

По-скоро не съм разбрал правилно прочетеното. Иначе за четено - четено ... :lol:
Благодаря :)

Автор:  manyov [ Чет Юни 09, 2016 2:17 pm ]
Заглавие:  Re: PIC PCL PCLATH (calculated goto)

Bezmozachen написа:
Не помня как беше при 16-ките, но предполагам е както при 18-ките. PCLATH, PCLATU са shadow регистри, които при прочитане на PCL се обновяват със съдържанието на останалите байтове от програмния брояч, а при запис в PCL, тяхното съдържание се записва в програмния брояч. T.e. не е казано, че PCLATH съдържа текущата стойност на старшия байт на програмния брояч. Мисля от там идват неочакваните резултати за теб.


Имам простичък въпрос - при условие, че W = 10, f = 1 - инструкцията 42 addwf PCL,f ни праща на 53 retlw B'11111010'. Това означава, че при W = 10 PCL=1. Защо PCL=1? Защото се изпълнява подпрограма 41table или по друга причина???
22 call table
23 bsf STATUS,RP0
24 movwf TRISB
.
.
41table
42 addwf PCL,f
43 nop
44 retlw B'11111100' ;
45 retlw B'11111100' ;
46 retlw B'11111001' ;.
47 retlw B'11111001' ;.
48 retlw B'11110011' ;.
49 retlw B'11110011' ;.
50 retlw B'11110101' ;
51 retlw B'11110101' ;
52 retlw B'11111010' ;
53 retlw B'11111010' ;
54 retlw B'11110110' ;
55 retlw B'11110110' ;
.
.
.

Автор:  slav4o.com [ Чет Юни 09, 2016 6:00 pm ]
Заглавие:  Re: [BUG?] PIC PCL PCLATH (calculated goto)

Това Table е label, не е инструкция. То не заема място в паметта. Таблицата почва от 42. Имаше и някаква особеност че така или иначе си се добавя и 1, то затова имаш и nop на 43ред. И така 42+10+1 = 53. Всъщност аз на тия неща много не обръщам внимание. Просто ги донагаждам винаги :) PCL колко е точно не се знае. f = 1 да така е, това обаче не се събира, просто показва, че резултата се слага обратно в PCL. Ако зададеш W което е 0, резултата се връща обратно в W

Автор:  Ники [ Чет Юни 09, 2016 9:33 pm ]
Заглавие:  Re: [BUG?] PIC PCL PCLATH (calculated goto)

manyov
тези номера 41, 42..55 са сложени от някакъв редактор/прозорец в който гледаш програмата, не са реални адреси.
PCL след като се прави извикване на подпорграма Table, e зареден с адреса на инструкцията 'addwf...'и в тази инструкция към него се добавя съдържанието на W.
TЪй като 'addwf' е един цикъл, а всяка инструкция с PCL е 2 цикъла, се добавя един NOP автоматично, не е нужно да се пише в асемблера, и не участва в смятането на адресите.

Автор:  manyov [ Пон Юни 13, 2016 9:50 am ]
Заглавие:  Re: [BUG?] PIC PCL PCLATH (calculated goto)

Всъщност ми е ясно, че номерата 41,42,...,55 не са адреси, а са се появили от работата на редактора. Сещам се и затова, че f = 1 означава резултатът да се запише в PCL. Обаче за абзаца „PCL след като се прави извикване на подпорграма Table, e зареден с адреса на инструкцията 'addwf...'и в тази инструкция към него се добавя съдържанието на W.
Tъй като 'addwf' е един цикъл, а всяка инструкция с PCL е 2 цикъла, се добавя един NOP автоматично, не е нужно да се пише в асемблера, и не участва в смятането на адресите.“ съм страшно благодарен, не бях се сетил за това. Само където до сега не съм срещат в букварите, че „всяка инструкция с PCL е 2 цикъла и се добавя един NOP автоматично“. Ще бъда благодарен, ако някой ми даде линк да се ограмотя повече за работата с PCL. Пробвах да разкарам ред 43 nop, като паралелно намалих w от 10 на 9, и всичко беше идентично както с nop и w=10. Има програми с nop и без него. Но все пак „42 addwf PCL,f“ означава, че сумата w+(PCL) се записва в PCL. И пак се връщзм към въпроса колко е PCL??? Когато написах „ PCL=1“ имах предвид първия адрес в подпрограмата table, а той може да е какъвто и да било.

Автор:  mitko_el [ Пон Юни 13, 2016 11:19 am ]
Заглавие:  Re: [BUG?] PIC PCL PCLATH (calculated goto)

manyov написа:
... И пак се връщзм към въпроса колко е PCL??? Когато написах „ PCL=1“ имах предвид първия адрес в подпрограмата table, а той може да е какъвто и да било.


Не съм в час с асм на пик , не става ли да заредиш адреса на 'table' (т.е. там от където почва таблицата) в PCL (това предполагам е индексен регистър). Това '1' не е ли първия адрес във флаша?

Автор:  manyov [ Пон Юни 13, 2016 12:01 pm ]
Заглавие:  Re: [BUG?] PIC PCL PCLATH (calculated goto)

Ами то това се случва:
41 table и 42 addwf PCL,f са с един и същ адрес. От там нататък следва NOP - адрес + 1 и т.н. Това може да се проследи в *.list файла.

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/