TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Andres_526 en 15 de Septiembre de 2005, 17:08:00
-
TENGO UNA DUDA RESPECTO AL MANEJO DEL PCLATH, TENGO UN PROGRAMA QUE SE SOBREPASO DE 7FF DE DIRECCION DE PROGRAMA, LASINSTRUCCIONES QUE SE VAN DE ESA DIRECCION PARA ARRIBA SE PIERDEN, QUISIERA SABER COMO PUEDO OPTIMIZAR TODA LA MEMORIA flash del micro , estoy utilizando un 16f877 ADEMAS TENGO PROBLEMAS CON UNAS TABLAS QUE YA MANDE AL INICIO DEL PROGRAMA YA QUE SON MUCHAS Y SE SOBREPASARON DEL DIRECCIONAMIENTO DEL PCL, PUEDO UTILIZARLAS MAS ALLA DE ESE DIRECCIONAMIENTO?, TODAS LAS TABLAS CONTIENEN MENUS DEL LCD, SI ME PUEDEN AYUDAR LES AGRADEZCO MUCHO
CORDIALMENTE
ANDRES JIMENEZ
-
Hola, hasta ahora no he llegado a sobrepasar la memoria de la primera pagina de un pic, pero asumo q se hara como en asembler primero editas el PCLATH para cambair de pagina y luego llamas a la funcion algo asi:
.....
PCLATH.3=1
PCLATH.4=0 " selecionamos la pagina 1
GOSUB Funcion
PCLATH.3=0
PCLATH.4=0 " selecionamos la pagina 0
.......
Y para ello deberiamos declarar las direcciones como en asm
.......
ORG 0x800 " algun comando que tenga algo equivalente...
Funcion:
.....
Otra cosa que puedes hacer es guardar los valores de tus tablas en la eeprom, para que ahorres espacio, siempre y cuando esos valores o caracteres sean casi constantes.
Espero no me equivoque, cualquier cosa mandas un mensaje para ver que se puede hacer... Como te repito no lo he hecho antes, y si puedes dejas como lo solucionaste para cuando a mi me llegue el dia jeje...
Un abrazo, nos vemos
-
Hola Andres. Esto que te pongo a continuación no es muy elegante ( incluso me da un poco de vergüenza ponerlo ) pero... por lo menos si te funciona puedes salir del paso.
Al final de tu programa pon:
org 0x800
Todo lo que escribas despues en tu programa estará a partir de esa dirección de memoria ( en la segunda página, puesto que nos pasamos de 7FF )
Puedes poner entonces tus mensages para el display ( ya estaremos en la 2ª página )
¿como hacemos entonces para llamar a estas tablas desde la 1ª página?
Puedes utilizar "lcall"
Con "lcall" (long call) tu programa podrá saltar a cualquiera de las páginas en la que esté la funcion a la que llames.Te recomiendo que busques información sobre LCALL porque tiene un par de particularidades que tienes que conocer.
Como tenemos que volvar de la función si por ejemplo está en la página 2ª??
Antes de escribir la instrucción "retlw 0" escribe "clrf PCLATH". De esta forma podremos retornar de la tabla (que está en la página 2ª<img src="http://pics.miarroba.com/caretos/wink.gif" alt="Giño" title="Giño" /> a la parte del programa desde donde hacemos la llamada (en la página 1ª<img src="http://pics.miarroba.com/caretos/wink.gif" alt="Giño" title="Giño" />
Ejemplo:
...
...
...
main ; remaining code goes here
bcf STATUS,RP1 ; Nos pasamos al Banco 1 para configurar pines de E/S
bsf STATUS,RP0
movlw b"01100000"
movwf TRISB ; Configuramos el "PUERTO B"
movlw b"00001111" ; PUERTO C = 0000 1111 (Los pines IN)
movwf TRISC
movlw b"11000000" ; todo salidas excepto el bit 7 que sera la entrada del boton encargado de sacar el menu.
movwf TRISD ; RD0 y RD1 serán las patillas encargadas de comunicarse con el ULN2003 que a su vez se comunicará con los relés.
movlw b"10000111" ; CON ESTO PONEMOS EL PREESCALADOR A 256
movwf OPTION_REG
bsf PIE2,EEIE ; Interrupcion de escritura en la EEPROM habilitada
bcf STATUS,RP0 ; Nos pasamos al Banco 0
...
...
...
call LCDCLEAR
call DELAY500
call LINEA1
call DELAY500
lcall
call unSEGUNDO
call unSEGUNDO
call DELAY500
call LCDCLEAR
...
...
...
org 0x800
bcf INTCON,GIE
lCALL DELAY500
movlw "P"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "E"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "P"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "E"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "P"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "P"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "O"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "T"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw " "
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "N"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "T"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "O"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "M"
lCALL LCDPUTCHAR
lCALL DELAY500
movlw "L"
lCALL LCDPUTCHAR
lCALL DELAY500
bsf INTCON,GIE
clrf PCLATH ; SI ESTAMOS EN LA PAG. 1, ponemos esto
para poder pasar a la pag. 0
retlw 0
--------------------------------
Si te fijas en las funciones LCDPUTCHAR y DELAY500 veras que las llamo con LCALL. Esto es porque, las tengo en la página 1ª.
Ya te digo de antemano que no es elegante pero funciona. Lo ideal es hacerte un buen sistema de paginación q sea cómodo y facil de utilizar, de todas formas... ahí queda esto. Espero que te sirva como mínimo de guía para poder atacar al problema.
Un saludo desde Alicante
-




bien
La solucion que das es buena, por que mala? Es precisamente lo que indica la aplication note 556 de microchip(si utilizas tablas largas, o muchas tablas(de manera tal que sobrepasen las 256 posiciones)).
El contador del programa PCL,es de 8 bits, o sea 256 posibilidades. Como la memoria de los PIC es gralmente mayor a esto, cuando el PCL se desborda(cuando suma 1 a 255), incrementa en una unidad el PCLATH... y vuelve a cero(el PCL).
Suponte: mi programa esta en las primeras 256 posiciones de programa,o sea que PCLATH = 0x00 bien?
ok.
Tengo una tabla, o muchas, y las quiero llamar.
Hago asi:
ubico las tablas en una posicion especifica(preferentemente al inicio de un nuevo paso de los 256 del PCL...)
ej : ORG 0x080
mitabla addwf PCL,F
retlw 0xff
retlw 0xf1
retlw 0xe0
...............
mitabla2 addwf PCL,F
retlw 0xaa
retlw 0xbb
retlw 0xcc
...............
Luego, desde el programa, cargo primero la posicion de memoria ALTA de la tabla.
ej:
movlw HIGH mitabla ; cargo en W el valor de los 8 bits altos de mitabla
movwf PCLATH ;copio el valor leido a PCLATH
movf datatoanalyze,W
call mitabla ;listo para llamar a la tabla
movwf resultado
;mas programa
movlw HIGH mitabla2 ; cargo en W el valor de los 8 bits altos de mitabla
movwf PCLATH ;copio el valor leido a PCLATH
movf datatoanalyze,W
call mitabla2 ;listo para llamar a la tabla
movwf resultado
;mas programa
el peor problema surge cuando una tabla supera en tamaño las 256 posiciones, o bien una tabla cruza los pasos del PCL...pero, tiene solucion 
Espero que haya quedado claro, sino busca la Aplication Note que mencione arriba.
Como se complica el tema al programar , te recomiendo que pruebes llamar a las funciones con el MPLAB, y te fijas si las llama bien, al menos eso es lo que hago cuando no quiero renegar ...
-
Pegale un ojo a este documento. Aqui pone las particularidades de "LCALL" y además te pone un ejemplo de un sistema de paginación muy elegante (desde mi punto de vista).
Un saludo desde Alicante.
----------------------------------------------------------------------------------------------------
Writing PIC Programmes Larger Than 2K
For our American friends I will translate the title:-
Writing PIC programs larger than 2K
(Sorry people but I think the Oxford dictionary has it wrong - the true English is in the title that I have chosen.....)
The EPE September 2003 edition arrived a few hours ago. One article which caught my eye is about the use of the HIGH operator in MPASM. (In our assembler MSB[LABEL] has the same function). The author Malcolm Wiles suggests that by setting PCLATH manually rather than using LCALL and LGOTO that a contiguous programme larger than 2k can be successfully written. He is quite right but he does not fully explain the problem.
Consider this section of programme code:-
Label1: call FLASH
decfsz COUNT,f
goto LABEL1
return
If count starts with a value of 10 the programme will loop back to LABEL1 ten times then return. This section of programme will only work correctly if the location of LABEL1 is within the same 2k memory page as the GOTO LABEL1 instruction. If we want this section of code to be able to float in a section of memory larger than 2k we cannot just change to using LCALL and LGOTO. The reason is that LGOTO creates three instructions so it cannot be used after DECFSZ because when the test is met just one instruction is skipped over.
If we set PCLATH manually rather than using LGOTO we are able to place the two extra instructions before DECFSZ and so avoid the problem. The modified code is as follows:-
Label1: movlw msb[FLASH]
movwf PCLATH
call FLASH
movlw msb[LABEL1]
movwf PCLATH
decfsz COUNT,f
goto LABEL1
return
This will work correctly anywhere in memory even when the 2k boundary crosses the middle of the routine. Take special notice that PCLATH must be set immediately before DECFSZ.
I have also chosen to set PCLATH manually before the CALL. LCALL could be used in this routine without the two preceding lines of text but as LCALL also sets PCLATH back to its original value that option would create another two instructions.
My Viewpoint
There is no doubt that if we manually set PCLATH as in the above example that PIC code can be written which occupies the whole memory as one contiguous programme. In the real world any PIC programme which exceeds 2k is a very large programme. Remember that this size in a properly organised programme will not include lookup data as that must always be organised into a known area of the memory. So the idea that this manual technique will actually make the programme easier to be free of bugs can only be wrong.
My advice when the programme is very large is to place all the major subroutines into high memory and keep all the main code within the first 2k. Then create a sequence of LCALL instructions with RETURNs at the end of your code making sure that they are within the first 2k. By doing it this way all your CALL and GOTO instructions will be normal instructions. Any that call into the high memory will go via your call table.
Do something like add a Z to the front of the label when it is in high memory and then life becomes very simple AND simple programming gives the greatest freedom from bugs.
For more information about the use of high memory addresses see page 219 and 223 of Experimenting with the PIC16F877
An example programme of a simple 4 bit counter is shown below. This can be run on the Brunning Software programmer module using a PIC with at least 4k of memory. When the two push buttons are pressed alternatively so the count shown on the 4 LEDs goes from zero to 15 then starts again.
pic16f877
count equ 20h
goto start
org 0004h
goto start
org 0005h
start: call setports
Begin: btfsc porta,ra0 ;Test bit 0 of port A.
goto begin ;Wait for button S2 to be pressed.
call counter
bn1: btfsc porta,ra1 ;Test bit 1 of port A.
goto bn1 ;Wait for button S3 to be pressed.
goto begin
Setports: lcall zsetports ;Table of LCALLs into high memory.
return
Counter: lcall zcounter
return
org 2048
Zsetports: bank1
movlw 0
movwf trisb ;Configure all port B as outputs.
movlw 7 ;Set all port A and port E bits
movwf adcon1 ; as normal I/O lines.
movlw 3 ;Set portA bit 0 and 1 as inputs
movwf trisa ; and bits 2, 3, 4, 5 as outputs.
clrwdt ;Clear watchdoge timer.
bank0
clrf portb ;Clear port B (all LEDs off).
return
Zcounter: incf count,f ;Add one to the value in COUNT.
btfsc count,4 ;Reset COUNT
clrf count ; if bit 4 is set.
movf count,w ;Move COUNT value in to W.
movwf portb ;Move W into port B.
return
Note that each subroutine in the high memory should ideally be completely self contained in which case all the CALLs and GOTOs will be normal. Calls can be made to external subroutines in which case it is best to use LCALL to the name in your call table even when the routine being called is in the same area of high memory. This prevents the problems that would result if at a later date the subroutines are moved when you have long forgotten that certain ones need to be in the same 2k area of memory.
The programme shown above is the complete text which needs to be typed into BWPICA. If you have never used the Brunning Software PIC assembler you may be surprised to see that there are no definitions needed. BWPICA has these programmed into it which creates a more reliable system. For example bit 1 of port B is called RB1 if RB1 is used with port A (e.g. BCF PORTA,RB1) BWPICA will give an error message. All other assemblers will accept this instruction although it obviously has an error.
If you have any comments on this please email high@brunningsoftware.co.uk