Отговори на тема  [ 22 мнения ]  Отиди на страница 1, 2  Следваща
Проблем със страниците на PIC16F877 
Автор Съобщение
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение Проблем със страниците на PIC16F877
Написах на Асемблер една доста голяма програма, но при транслирането ми се появяват предупреждения, че съм преминал границата на страниците: "Crossing page boundary -- ensure page bits are set".

Доколкото си спомням, превключването ставаше по тази схема:

PCLATH<4> PCLATH<3> GOTO PAGE
---------------------------------------------
0 0 Page 0
0 1 Page 1
1 0 Page 2
1 1 Page 3

Разрових къде ли не, търсих и в този форум, но не можах да намеря нищо конкретно. В datasheet няма много по въпроса. Проблемът е, че от реда, индециран като първо преминаване между страниците, програмата спира с изпълнението, което ми отне доста време за откриване на грешката.

В общи линии ме интересува следното:
1. Има ли начин превключването да става автоматично(без да трябва да го следя)?
2. Ако НЕ, то къде става това превключване-цялата програма като едно цяло ли се третира или трябва да я организирам по страници, които се отнасят като отделни програми?
3. Със забрана за извеждане на грешките, решава ли се и проблемът със самия преход на страниците(имам предвид командите errorlevel -306 и errorlevel -302 )
4. Може ли да дадете някоя примерна част от сорс?

Поздрав!


Пет Фев 08, 2008 10:59 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Чет Фев 01, 2007 4:04 am
Мнения: 1539
Мнение Re: Проблем със страниците на PIC16F877
E1 написа:
....Разрових къде ли не, търсих и в този форум, но не можах да намеря нищо конкретно. В datasheet няма много по въпроса. Проблемът е, че от реда, индециран като първо преминаване между страниците, програмата спира с изпълнението, което ми отне доста време за откриване на грешката.

А това по-долу я познай откъде съм го копнал?
Асемблера те предупреждава да си провериш адресацията. А тя се прави преди goto и call ако сочат към друга страница и (почти) задължително след връщане от return от друга страница. Подпрограмите се "подреждат" в паметта с org.
Автоматиката при асемблера е да внимаваш. Иначе сам си видял какво става - забиваш у стърнището. :)


2.4 Program Memory Paging
All PIC16F87XA devices are capable of addressing a
continuous 8K word block of program memory. The
CALL and GOTO instructions provide only 11 bits of
address to allow branching within any 2K program
memory page. When doing a CALL or GOTO instruction,
the upper 2 bits of the address are provided by
PCLATH<4:3>. When doing a CALL or GOTO instruc-
tion, the user must ensure that the page select bits are
programmed so that the desired program memory
page is addressed. If a return from a CALL instruction
(or interrupt) is executed, the entire 13-bit PC is popped
off the stack. Therefore, manipulation of the
PCLATH<4:3> bits is not required for the RETURN
instructions (which POPs the address from the stack).
Note: The contents of the PCLATH register are
unchanged after a RETURN or RETFIE
instruction is executed. The user must
rewrite the contents of the PCLATH regis-
ter for any subsequent subroutine calls or
GOTO instructions.
Example 2-1 shows the calling of a subroutine in
page 1 of the program memory. This example assumes
that PCLATH is saved and restored by the Interrupt
(if interrupts are used).
Service Routine
EXAMPLE 2-1: CALL OF A SUBROUTINE
IN PAGE 1 FROM PAGE 0
ORG 0x500
BCF PCLATH,4
BSF PCLATH,3 ;Select page 1
;(800h-FFFh)
CALL SUB1_P1 ;Call subroutine in
: ;page 1 (800h-FFFh)
:
ORG 0x900 ;page 1 (800h-FFFh)
SUB1_P1
: ;called subroutine
;page 1 (800h-FFFh)
:
RETURN ;return to
;Call subroutine
;in page 0


Пет Фев 08, 2008 11:35 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Подреди си подпрограмите по страници, като гледай в една страница да се намират подпрограми, които се викат една друга, за да спестяваш по 2 инструкции на извикване на подпрограма. Главната програма с векторите на прекъсване разположи в нулевата страница. Направи си макрос, с които да викаш нужната ти подпрограма. Примерно, макроса може да бъде с 1 параметър - името на подпрограмата:
Код:
mcall MACRO Name_Of_The_Subroutine
         movlw HIGH(Name_Of_The_Subroutine);
         movwf PCLATH;
         call Name_Of_The_Subroutine;
ENDM


Това мисля, че ще е достатъчно.

При връщане от подпрограма от друга страница:

Цитат:
If a return
from a CALL instruction (or interrupt) is executed, the
entire 13-bit PC is pushed onto the stack. Therefore,
manipulation of the PCLATH<4:3> bits are not required
for the return instructions (which POPs the address
from the stack).


Ако използваш WREG за предаване на параметри на подпрограмата, трябва да промениш mcall . Вътре с #if проверяваш HIGH(Name_Of_The_Subroutine) в коя страница се намира Name_Of_The_Subroutine, след което правиш директно bsf, bcf на PCLATH<4:3>

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пет Фев 08, 2008 11:55 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
ji4ka, малко преди да вляза пак на форума и го намерих и аз. Но в началото тръгнах по съкратената процедура: Имам проблем с паметта и търсих в обясненията за паметта. А информацията се намира в обяснението за PCLATH, което е отделено.

Сега прехвърлям цялата програма. На всичкото отгоре, за да ми е по-пригледно, бях направил 6 отделни блока с по 160 GOTO команди и резултатът е няколко стотин предупреждения!
Докато бяха 50-ина условия, нямаше проблем, но като разширих програмата и...


Съб Фев 09, 2008 1:38 am
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
Промених програмата. Сега предупрежденията са около 80, което е доста по-добре, в сравнение с 350-те в началото. Но остава един съществен проблем: На много места GOTO остава по два пъти след някаква проверка. В такъв случай ми се налага да вкарам по още един условен преход, за да имам място за прехвърлянето към страницата, което става на няколко реда:

NEXT_CHARACTER

bcf STATUS,Z
movf WORK_COUNTER,w
xorlw B'00000000'
btfsc STATUS,Z
goto Ver_field
goto FIND_ASCII

И двете goto тук, отиват към друга страница. За второто не е проблем, но за първото трябва да въведа още едно поле, където да направя пренасочването.

Много би ми помогнало, ако измисля начин за най-икономична направа на едномерен масив. Например:

For i=0 to N
BUFFER=A[i]
.....

Това не го знам как става(ако е изобщо възможно с Асемблер) и практически съм принуден да пиша отделно за всеки елемент от масива, като единствено мога да следя дали е запълнен масивът до предварително определената стойност на i, която е в интервала от 0 до 160!

Друго, което може да ми реши проблема е алгоритъм за проверка дали всички елементи на едномерен масив са =0. Този масив е с размер 80 елемента. Сега програмата ми работи, но докато не разширя масивите.

Ще съм благодарен, ако някой даде идея как да се измъкна, без на 4000-те програмни реда да добавя още 1000!


Съб Фев 09, 2008 4:13 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Юни 05, 2006 1:48 pm
Мнения: 4906
Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
Мнение 
да избягаш от хилядо реда асемблерски код.... за малко промени :?: ](*,)
единствения изход е да преминеш плавно или рязко към писане на С :!:

по принцип избягвам да се меся в коментирането на грешки и проблеми с микроконтролерите от майкрочип. просто не са ми познати....

но все пак за да не се жалиш че си се изкърил от писане само за преметането на един масив от един регистър към друг, [-o<
....най-добре ползвай програмният език С :!:
вече има много свободни или "освободени"( ;) 10x to Nikola) компилатори / работни среди.
поне аз ползвам асемблера само в случай на оптимизация - когато времето или мястото е критично. иначе го смятам за най-висша форма на мазохизъм и на загуба на време...
Величината Time to Market :!: на каквото ида е изделие ни притиска да излезнем от дълбините на асемблера ;)

_________________
... ако трети ден не ти се работи... това означава, че е сряда !


Съб Фев 09, 2008 5:02 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
Това е ясно. Но програмата е вече почти готова и не искам да я оставям точно сега. Още повече, че работи, макар и с част от предвидения капацитет. Дори на моменти ми минава през ума да се пробвам да я препиша на Микропаскал. Ама защо да го правя, ако може да се намери решение за тези проблеми. Аз имам чувството, че не работя оптимално в момента и затова търся съвет. Иначе, когато написах(преди няколко месеца) във форума какво възнамерявам да правя, доста хора ми намекнаха, че е самоубийство. Още повече, че тогава дори не знаех КАК да го направя!


Съб Фев 09, 2008 5:16 pm
Профил WWW
Ранг: Ориентиран
Ранг: Ориентиран
Аватар

Регистриран на: Чет Май 12, 2005 11:10 am
Мнения: 211
Мнение 
Това не те ли устройва, ako примерно преходите са в 2 и 3 страница и в началото на страницата си сложил етикети page2 и page3?

NEXT_CHARACTER

bcf STATUS,Z
movf WORK_COUNTER,w
xorlw B'00000000'
btfsc STATUS,Z
goto TEMP_1
pagesel page3
goto FIND_ASCII
TEMP_1
pagesel page2
goto Ver_field


Съб Фев 09, 2008 5:17 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
Да, това работи, разбира се. Работи и макросът, който ми дал . Но няма да ми се налага да обикалям страниците, ако оптимизирам масивите.
Няма ли вариант за въвеждане на указател, така че да се съедини с етикета, подобно на това: A[i]?

С макроса успях да намаля съобщенията до 10, което вече е нещо. Но имам проблем с goto. Не знам например в следния участък какъв макрос да направя:


;--ASCII ZA "."
V_SP23 bcf STATUS,Z
movf SYM_BUFFER,w
xorlw H'2E'
btfsc STATUS,Z
goto V_SP24
SP25 ; TO4KA
movlw b'00100000'
movwf Current1
movlw b'00100000'
movwf Current2
goto SCROLL_RRL

;--ASCII ZA ","
V_SP24 bcf STATUS,Z
movf SYM_BUFFER,w
xorlw H'2C'
btfsc STATUS,Z
goto V_SP25
SP26 ; ZAPETAJA
movlw b'10100000'
movwf Current1
movlw b'01100000'
movwf Current2
movlw b'00000000'
movwf Current3
goto SCROLL_RRL


Индицира ми предупреждение на goto V_SP24. Точно между тези две секции минава границата на страниците, защото на разположените нагоре не дава предупреждения, а само от goto V_SP24 надолу.


Съб Фев 09, 2008 6:56 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Чет Фев 01, 2007 4:04 am
Мнения: 1539
Мнение 
E1 написа:
For i=0 to N
BUFFER=A[i]
.....

Това не го знам как става(ако е изобщо възможно с Асемблер) и практически съм принуден да пиша отделно за всеки елемент от масива, като единствено мога да следя дали е запълнен масивът до предварително определената стойност на i, която е в интервала от 0 до 160!

Това при пиковете се прави с т.нар. "computed goto" чрез промяна на PCL - също е описано в даташита. Там работите са малко по-сложни , трябва да се следят и сегментите (256 адреса). Обаче зависи от фамилията -16,18 и т.н. .......
:!: Обачеее , тоя масив РАМ ли е или е РОМ , че може да стане голяма обърквация.

Така се прави/чете ром-таблица на Пик16. В I се слага индекса,в W се връща резултата. Важно е таблицата да е в един сегмент (0-255, 256-511 и т.н.) защото иначе е по-сложно.

movf I,w
call GetTable
movwf Buffer

GetTable
addwf PCL,f
retlw B1
retlw B2
...
retlw Bi

Но щом си опрял до ASCII ,явно вече не си за Асемблер. Както ти казаха по-нагоре помисли за С. Асемблера е много трудоемък за обработка на масиви, не че няма да стане.


Съб Фев 09, 2008 10:57 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
Проблемът е, че трябва да организирам таблица от променливи, а не от константи. Имам в програмата си такава таблица(от променливи), но тя се състои от голям брой goto, което искам да променя. Как мога да направя да се чете всеки втори ред от таблицата?
Например на това:

Table addwf PCL,1
nop
A1 movf ROW1,w
return
A2 movf ROW2,w
return
A3 movf ROW3,w
return

Иначе тази таблица се състои в оригинал от поредица goto, пренасочващи към етикетите А1, А2... Какво може да се направи, за да се чете таблицата през ред?


Нед Фев 10, 2008 3:42 am
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Окт 10, 2004 9:55 am
Мнения: 1718
Мнение MMM
E1 написа:
Проблемът е, че трябва да организирам таблица от променливи, а не от константи. Имам в програмата си такава таблица(от променливи), но тя се състои от голям брой goto, което искам да променя. Как мога да направя да се чете всеки втори ред от таблицата?
Например на това:

Table addwf PCL,1
nop
A1 movf ROW1,w
return
A2 movf ROW2,w
return
A3 movf ROW3,w
return

Иначе тази таблица се състои в оригинал от поредица goto, пренасочващи към етикетите А1, А2... Какво може да се направи, за да се чете таблицата през ред?

А пробвал ли си да го направиш това ровене в таблицата с индексен регистър, тогава няма да имаш този проблем със страниците , чрез индексния регистър имаш достъп до таблицата от всяка страница !!!

_________________
Избийте баламите и тарикатите сами ще умрат!
Няма невъзможни работи - има много трудни работи!
----------------------------------------------------------------------------------
"Я в Москве с киркой уран найду, при такой повышенной зарплате" !


Нед Фев 10, 2008 8:08 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Чет Фев 01, 2007 4:04 am
Мнения: 1539
Мнение 
E1 написа:
Проблемът е, че трябва да организирам таблица от променливи, а не от константи. Имам в програмата си такава таблица(от променливи), но тя се състои от голям брой goto, което искам да променя. Как мога да направя да се чете всеки втори ред от таблицата?


Така кажи. Ти бъркаш РАМ(DataMemory) с ROM(ProgramMemory). Такава таблица се прави в РАМ-а . Тогава чети този раздел:

2.5 Indirect Addressing, INDF and
FSR Registers
The INDF register is not a physical register. Addressing
the INDF register will cause indirect addressing.
Indirect addressing is possible by using the INDF reg-
ister. Any instruction using the INDF register actually
accesses the register pointed to by the File Select Reg-
ister, FSR. Reading the INDF register itself, indirectly
(FSR = 0) will read 00h. Writing to the INDF register
indirectly results in a no operation (although status bits
may be affected). An effective 9-bit address is obtained
by concatenating the 8-bit FSR register and the IRP bit
(Status<7>) as shown in Figure 2-6.

При адресирането в РАМ-а въобще не се ползва goto,call,PCL защото си има хардуерни регистри точно с тази цел. Даже е по-лесно.

movf I,w ;индекса 0..160
addlw First ;First е началния адрес на таблицата в DataMemory.
movwf FSR ;тук се зарежда вече истинския адрес
movf INDF,w ; тук извлича стойността в W
movwf Buffer ; и я слагаш в буфера

Тука в I се намира индекса 0..160 .Организираш го като брояч. Ако искаш през един,просто всеки път го увеличаваш с 2, напр. два пъти incf I,f.
Тука вече е важно таблицата да е в една банка - прочети как става нагласянето на банките с IRP.

Ти да не правиш обработка на текст.? Провери на http://piclist.com/techref/microchip/codeflow.htm може да намериш нещо готово.


Нед Фев 10, 2008 2:22 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение 
Точно обработка на текст е. По принцип всичко става през паралелния порт, по определен протокол, който позволява и обработка на монохромно (засега) видео в реално време. Тази част работи, въпреки всички критики към възможностите на паралелния порт. Работи и текстът, доколкото се задоволя с 80 символа. Но аз искам 160.

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


Нед Фев 10, 2008 8:21 pm
Профил WWW
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Чет Авг 30, 2007 2:14 pm
Мнения: 118
Мнение 
Цитат:
Много би ми помогнало, ако измисля начин за най-икономична направа на едномерен масив. Например:

For i=0 to N
BUFFER=A[i]
.....

Това го има в PYTHON.
А за другото може би да дефинираш макроси.
Примерно за PAGE1 сетваш 3 бит и исчистваш 4.
Опитай има ли възможност през паралелния да подаваш сигнал за смяна на страниците, при въвеждане на масива.
А когато пика чете масивите трябва да се следи каде се прекъсва масива и преминава в друга страница.
Поне аз така разбрах нещата.


Нед Фев 10, 2008 8:54 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 22 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: Google [Bot] и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни