| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Проблем със страниците на PIC16F877 http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=5441 |
Страница 1 от 2 |
| Автор: | E1 [ Пет Фев 08, 2008 10:59 pm ] |
| Заглавие: | Проблем със страниците на 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. Може ли да дадете някоя примерна част от сорс? Поздрав! |
|
| Автор: | ji4ka [ Пет Фев 08, 2008 11:35 pm ] | |||||||||
| Заглавие: | Re: Проблем със страниците на PIC16F877 | |||||||||
А това по-долу я познай откъде съм го копнал? Асемблера те предупреждава да си провериш адресацията. А тя се прави преди 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:55 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Подреди си подпрограмите по страници, като гледай в една страница да се намират подпрограми, които се викат една друга, за да спестяваш по 2 инструкции на извикване на подпрограма. Главната програма с векторите на прекъсване разположи в нулевата страница. Направи си макрос, с които да викаш нужната ти подпрограма. Примерно, макроса може да бъде с 1 параметър - името на подпрограмата:
Това мисля, че ще е достатъчно. При връщане от подпрограма от друга страница:
Ако използваш WREG за предаване на параметри на подпрограмата, трябва да промениш mcall . Вътре с #if проверяваш HIGH(Name_Of_The_Subroutine) в коя страница се намира Name_Of_The_Subroutine, след което правиш директно bsf, bcf на PCLATH<4:3> |
|||||||||||||||||||
| Автор: | E1 [ Съб Фев 09, 2008 1:38 am ] |
| Заглавие: | |
ji4ka, малко преди да вляза пак на форума и го намерих и аз. Но в началото тръгнах по съкратената процедура: Имам проблем с паметта и търсих в обясненията за паметта. А информацията се намира в обяснението за PCLATH, което е отделено. Сега прехвърлям цялата програма. На всичкото отгоре, за да ми е по-пригледно, бях направил 6 отделни блока с по 160 GOTO команди и резултатът е няколко стотин предупреждения! Докато бяха 50-ина условия, нямаше проблем, но като разширих програмата и... |
|
| Автор: | E1 [ Съб Фев 09, 2008 4:13 pm ] |
| Заглавие: | |
Промених програмата. Сега предупрежденията са около 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! |
|
| Автор: | MYXATA [ Съб Фев 09, 2008 5:02 pm ] |
| Заглавие: | |
да избягаш от хилядо реда асемблерски код.... за малко промени
единствения изход е да преминеш плавно или рязко към писане на С по принцип избягвам да се меся в коментирането на грешки и проблеми с микроконтролерите от майкрочип. просто не са ми познати.... но все пак за да не се жалиш че си се изкърил от писане само за преметането на един масив от един регистър към друг,
....най-добре ползвай програмният език С вече има много свободни или "освободени"( поне аз ползвам асемблера само в случай на оптимизация - когато времето или мястото е критично. иначе го смятам за най-висша форма на мазохизъм и на загуба на време... Величината Time to Market |
|
| Автор: | E1 [ Съб Фев 09, 2008 5:16 pm ] |
| Заглавие: | |
Това е ясно. Но програмата е вече почти готова и не искам да я оставям точно сега. Още повече, че работи, макар и с част от предвидения капацитет. Дори на моменти ми минава през ума да се пробвам да я препиша на Микропаскал. Ама защо да го правя, ако може да се намери решение за тези проблеми. Аз имам чувството, че не работя оптимално в момента и затова търся съвет. Иначе, когато написах(преди няколко месеца) във форума какво възнамерявам да правя, доста хора ми намекнаха, че е самоубийство. Още повече, че тогава дори не знаех КАК да го направя! |
|
| Автор: | VANK [ Съб Фев 09, 2008 5:17 pm ] |
| Заглавие: | |
Това не те ли устройва, 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 |
|
| Автор: | E1 [ Съб Фев 09, 2008 6:56 pm ] |
| Заглавие: | |
Да, това работи, разбира се. Работи и макросът, който ми дал ¶. Но няма да ми се налага да обикалям страниците, ако оптимизирам масивите. Няма ли вариант за въвеждане на указател, така че да се съедини с етикета, подобно на това: 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 надолу. |
|
| Автор: | ji4ka [ Съб Фев 09, 2008 10:57 pm ] | |||||||||
| Заглавие: | ||||||||||
Това при пиковете се прави с т.нар. "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 ,явно вече не си за Асемблер. Както ти казаха по-нагоре помисли за С. Асемблера е много трудоемък за обработка на масиви, не че няма да стане. |
||||||||||
| Автор: | E1 [ Нед Фев 10, 2008 3:42 am ] |
| Заглавие: | |
Проблемът е, че трябва да организирам таблица от променливи, а не от константи. Имам в програмата си такава таблица(от променливи), но тя се състои от голям брой goto, което искам да променя. Как мога да направя да се чете всеки втори ред от таблицата? Например на това: Table addwf PCL,1 nop A1 movf ROW1,w return A2 movf ROW2,w return A3 movf ROW3,w return Иначе тази таблица се състои в оригинал от поредица goto, пренасочващи към етикетите А1, А2... Какво може да се направи, за да се чете таблицата през ред? |
|
| Автор: | plameniv [ Нед Фев 10, 2008 8:08 am ] | |||||||||
| Заглавие: | MMM | |||||||||
А пробвал ли си да го направиш това ровене в таблицата с индексен регистър, тогава няма да имаш този проблем със страниците , чрез индексния регистър имаш достъп до таблицата от всяка страница !!! |
||||||||||
| Автор: | ji4ka [ Нед Фев 10, 2008 2:22 pm ] | |||||||||
| Заглавие: | ||||||||||
Така кажи. Ти бъркаш РАМ(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 може да намериш нещо готово. |
||||||||||
| Автор: | E1 [ Нед Фев 10, 2008 8:21 pm ] |
| Заглавие: | |
Точно обработка на текст е. По принцип всичко става през паралелния порт, по определен протокол, който позволява и обработка на монохромно (засега) видео в реално време. Тази част работи, въпреки всички критики към възможностите на паралелния порт. Работи и текстът, доколкото се задоволя с 80 символа. Но аз искам 160. А чрез PCLATH не успявам да прехвърля страниците. Нещо важно ми е убягнало, но засега не мога да разбера какво. Правих невероятни опити да изчисля стойността на регистъра преди да извиквам таблицата, но засега не успявам. Резултатът е непредвидимо смущение и изкривяване на изображението(текста). |
|
| Автор: | Комбинатор [ Нед Фев 10, 2008 8:54 pm ] | |||||||||
| Заглавие: | ||||||||||
Това го има в PYTHON. А за другото може би да дефинираш макроси. Примерно за PAGE1 сетваш 3 бит и исчистваш 4. Опитай има ли възможност през паралелния да подаваш сигнал за смяна на страниците, при въвеждане на масива. А когато пика чете масивите трябва да се следи каде се прекъсва масива и преминава в друга страница. Поне аз така разбрах нещата. |
||||||||||
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|