He comprobado con este código que no se pone a ORG 0x00 automáticamente, y si lo haces tu da problemas.
¿Hay algún ejemplo que funcione bien?
Por ejemmplo, 256 caracteres en el org 0x00, luego otros 256 en ORG 0x0100, luego en el ORG 0x200.
Recordar que las instrucciones generales están en el ORG 0x00 así que ha de volver, en los otros ORG son sólo mensajes de ejemplo.
Saludo.
Código:
; ZONA DE DATOS *******************************************************
LIST P=16F887
INCLUDE <P16F887.INC>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
__IDLOCS 0x1234
ERRORLEVEL -302
CBLOCK 0x20
TeclaPulsada ; Va a guardar el contenido de la tecla pulsada.
MensajeApuntado ; Va a guarda la dirección del mensaje apuntado.
Relays ; Estado de los relays
Estado ; Estado general
ENDC
#DEFINE PEntradasB PORTB ; Define puerto de salidas.
#DEFINE EntradaR1B 0 ; Define dónde se sitúa cada salidas.
#DEFINE EntradaR2B 1
#DEFINE EntradaR3B 2
#DEFINE EntradaR4B 3
#DEFINE EntradaR5B 4
#DEFINE EntradaR6B 5
#DEFINE EntradaR7B 6
#DEFINE EntradaR8B 7
#DEFINE PSalidasD PORTD
#DEFINE SalidaR1D 0
#DEFINE SalidaR2D 1
#DEFINE SalidaR3D 2
#DEFINE SalidaR4D 3
#DEFINE SalidaR5D 4
#DEFINE SalidaR6D 5
#DEFINE SalidaR7D 6
#DEFINE SalidaR8D 7
#DEFINE Seleccion PORTE,2 ; Selección manual/serie con un pulsador.
TECLA_RELE_1_ON EQU 'q' ; Código de las teclas utilizadas.
TECLA_RELE_1_OFF EQU 'a'
TECLA_RELE_2_ON EQU 'w'
TECLA_RELE_2_OFF EQU 's'
TECLA_RELE_3_ON EQU 'e'
TECLA_RELE_3_OFF EQU 'd'
TECLA_RELE_4_ON EQU 'r'
TECLA_RELE_4_OFF EQU 'f'
TECLA_RELE_5_ON EQU 't'
TECLA_RELE_5_OFF EQU 'g'
TECLA_RELE_6_ON EQU 'y'
TECLA_RELE_6_OFF EQU 'h'
TECLA_RELE_7_ON EQU 'u'
TECLA_RELE_7_OFF EQU 'j'
TECLA_RELE_8_ON EQU 'i'
TECLA_RELE_8_OFF EQU 'k'
TECLA_INICIO EQU 'z'
TECLA_PARADA EQU ' ' ; Código de la tecla espaciadora, (hay un espacio,
; tened cuidado al teclear el programa).
TECLA_INFO EQU 'n'
ENTER EQU 0x0A ; Código de tecla "Enter" o "Retorno de Carro".
CAMBIO_LINEA EQU 0x0D ; Código para el cambio de línea.
ORG 0x2100 ; Corresponde a la dirección 0 de la zona EEPROM
; de datos.
DE 0x00,2,3
;****************************************************************************
;* ZONA DE CODIGOS *
;****************************************************************************
;****************************************************************************
;* Rutina Principal *
;****************************************************************************
ORG 0x00
goto Inicio
; ORG 4 ; Aquí se sitúa el vector de interrupción para
; goto LeeEntradasVisualiza ; atender las subrutinas de interrupción.
Inicio
call LCD_Inicializa ; Inicializa el display LCD
call RS232_Inicializa ; Inicializa RS232.
bsf PEntradasB,EntradaR1B
bsf PEntradasB,EntradaR2B
bsf PEntradasB,EntradaR3B
bsf PEntradasB,EntradaR4B
bsf PEntradasB,EntradaR5B
bsf PEntradasB,EntradaR6B
bsf PEntradasB,EntradaR7B
bsf PEntradasB,EntradaR8B
bcf PSalidasD,SalidaR1D
bcf PSalidasD,SalidaR2D
bcf PSalidasD,SalidaR3D
bcf PSalidasD,SalidaR4D
bcf PSalidasD,SalidaR5D
bcf PSalidasD,SalidaR6D
bcf PSalidasD,SalidaR7D
bcf PSalidasD,SalidaR8D
BANKSEL CM1CON0
movlw b'00000111'
movwf CM1CON0
movwf CM2CON0
movwf CM2CON1
BANKSEL ANSEL
clrf ANSEL
clrf ANSELH
BANKSEL TRISB
movlw b'11111111'
movwf TRISB
clrw
clrf TRISD
BANKSEL PORTD
call Parado ; En principio todas las salidas deben estar
movlw 0x02
call EEPROM_LeeDato
movwf Relays
call Ejecutar ; Enciende o apaga reles seleccionados
call Mensaje_Reles
call Visualiza ; Muestra mensaje en el display
call RS232_LineasBlanco ; Visualiza unas cuantas líneas en blanco
call RS232_LineasBlanco ; para limpiar la pantalla.
; movlw b'10001000' ; Habilita la interrupción RBI y la general.
; movwf INTCON
; btfss PEntradasC,EntradaR1C ; ¿Bit 0 del PORTA es "1"?
; goto D1_OFF
; bsf PSalidasD,SalidaR1D
; goto Principal
;D1_OFF
; bcf PSalidasD,SalidaR1D
;Aqui
; btfss Seleccion
; goto Principal
; goto LeeEntradasVisualiza
; sleep
; goto Aqui
Principal ; apagadas.
call RS232_LeeDato ; Espera a recibir un carácter.
call TesteaTeclado ; Verifica caracter recibido y ejecuta accion
call Ejecutar ; Enciende o apaga reles seleccionados
call Visualiza ; Muestra mensaje en el display
call Guardar_EEPROM
; btfsc Seleccion
; goto Aqui
goto Principal ; Loop Infinito
;****************************************************************************
;* Mensajes *
;****************************************************************************
Mensajes
addwf PCL,F
MensajeParado
DT "Sistema DESACTIVADO ", 0x00
Mensaje_Reles
DT " 1 2 3 4 5 6 7 8 RL ", 0x00
Mensaje_ON
DT " 1", 0x00
Mensaje_OFF
DT " O", 0x00
Mensaje_Cambiolinea
DT ENTER, CAMBIO_LINEA, 0x00
Mensaje_Mostrarlinea
DT "----------------", 0x00
Mensaje_Activar
DT " Todos ACTIVOS ", 0x00
Mensaje_IN
DT " IN", 0x00
Mensaje_OUT
DT " OUT", 0x00
Mensaje_Avisos
DT "*** ALARMA ***", 0x00
MensajeEntradas
DT ENTER, CAMBIO_LINEA
DT " 1 2 3 4 5 6 7 8 IN"
DT ENTER, CAMBIO_LINEA
DT "-------------------"
DT ENTER, CAMBIO_LINEA, 0x00
Mensaje_Info ORG 0x0400
DT "FirmWare v2.15 ", 0x00
DT ENTER, CAMBIO_LINEA
call LCD_Linea2
DT " PIC16F887 "
DT ENTER, CAMBIO_LINEA
call Retardo_2s
call LCD_Linea1
DT " metaconta "
DT ENTER, CAMBIO_LINEA
call LCD_Linea2
DT " @gmail.com ", 0x00
call Retardo_2s
ORG 0x00D9
FinTablaASCII
;****************************************************************************
;* Testea Teclado y sensores *
;* *
;* Verifica caracer recibido y decide que accion ejecutar *
;****************************************************************************
TesteaTeclado
movwf TeclaPulsada ; Guarda el contenido de la tecla pulsada.
xorlw TECLA_RELE_1_ON ; ¿Es la tecla del movimiento hacia adelante?
btfsc STATUS,Z ;
goto R1_ON ; Sí, se desea movimiento hacia adelante.
movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.
xorlw TECLA_RELE_1_OFF ; ¿Es la tecla del movimiento hacia atrás?
btfsc STATUS,Z ;
goto R1_OFF ; Sí, se desea movimiento hacia atrás.
movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.
xorlw TECLA_RELE_2_ON ; ¿Es la tecla del movimiento hacia la izquierda?
btfsc STATUS,Z ;
goto R2_ON ; Sí, se desea movimiento hacia la izquierda.
movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.
xorlw TECLA_RELE_2_OFF ; ¿Es tecla del movimiento hacia la derecha?
btfsc STATUS,Z ;
goto R2_OFF ; Sí, se desea movimiento hacia la derecha.
movf TeclaPulsada,W ;
xorlw TECLA_RELE_3_ON ;
btfsc STATUS,Z ;
goto R3_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_3_OFF ;
btfsc STATUS,Z ;
goto R3_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_4_ON ;
btfsc STATUS,Z ;
goto R4_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_4_OFF ;
btfsc STATUS,Z ;
goto R4_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_5_ON ;
btfsc STATUS,Z ;
goto R5_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_5_OFF ;
btfsc STATUS,Z ;
goto R5_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_6_ON ;
btfsc STATUS,Z ;
goto R6_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_6_OFF ;
btfsc STATUS,Z ;
goto R6_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_7_ON ;
btfsc STATUS,Z ;
goto R7_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_7_OFF ;
btfsc STATUS,Z ;
goto R7_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_8_ON ;
btfsc STATUS,Z ;
goto R8_ON ;
movf TeclaPulsada,W ;
xorlw TECLA_RELE_8_OFF ;
btfsc STATUS,Z ;
goto R8_OFF ;
movf TeclaPulsada,W ;
xorlw TECLA_INICIO ;
btfsc STATUS,Z ;
goto Activar ;
movf TeclaPulsada,W ;
xorlw TECLA_INFO ;
btfsc STATUS,Z ;
goto Info ;
movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.
xorlw TECLA_PARADA ; ¿Es la tecla de parada?.
btfss STATUS,Z
return ; No es ninguna tecla de movimiento. Sale.
;------------------------------------------------------------------------------------------------
Parado
movlw 0x02 ; Muestra mensaje 02
movwf Estado ;
movlw 0x00 ; Como se ha pulsado la tecla de parada se
movwf Relays ; desactivan todas las salidas.
return
R1_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR1D ; Activa Relay 1
return ;
R1_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR1D ; Desctiva Relay 1
return ;
R2_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR2D ; Activa Relay 2
return ;
R2_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR2D ; Desctiva Relay 2
return ;
R3_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR3D ; Activa Relay 3
return ;
R3_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR3D ; Desctiva Relay 3
return ;
R4_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR4D ; Activa Relay 4
return ;
R4_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR4D ; Desctiva Relay 4
return ;
R5_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR5D ; Desctiva Relay 5
return
R5_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR5D ; Desctiva Relay 5
return
R6_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR6D ; Desctiva Relay 6
return
R6_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR6D ; Desctiva Relay 6
return
R7_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR7D ; Desctiva Relay 7
return
R7_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR7D ; Desctiva Relay 7
return
R8_ON
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bsf Relays,SalidaR8D ; Desctiva Relay 8
return
R8_OFF
movlw 0x00 ; Muestra estado relays
movwf Estado ;
bcf Relays,SalidaR8D ; Desctiva Relay 8
return
Activar
movlw 0x03 ; Muestra mensaje 03
movwf Estado ;
bsf Relays,SalidaR1D ; Activa Relay 1
bsf Relays,SalidaR2D ; Activa Relay 2
bsf Relays,SalidaR3D ; Activa Relay 3
bsf Relays,SalidaR4D ; Activa Relay 4
bsf Relays,SalidaR5D ; Activa Relay 6
bsf Relays,SalidaR6D ; Activa Relay 7
bsf Relays,SalidaR7D ; Activa Relay 8
bsf Relays,SalidaR8D ; Activa Relay 9
return
Info
movlw 0x01 ; Muestra mensaje 01
movwf Estado ;
return
;****************************************************************************
;* Ejecutar *
;* Obtiene estado de los relays y los activa en el puerto adecuado *
;****************************************************************************
Ejecutar
movf Relays,W ; Carga estado de relays
movwf PSalidasD ; en el puerto asignado
Return
;****************************************************************************
;* Visualiza *
;* Según el estado de las salidas visualiza el estado del sistema en el *
;* visualizador LCD y en el monitor del ordenador. *
;****************************************************************************
Visualiza
movf Estado,W ; Mensaje 00?
xorlw 0x00 ;
btfsc STATUS,Z ;
goto MostrarRelays ; Si, muestra estado de relays
movf Estado,W ; Mensaje 01?
xorlw 0x01 ;
btfsc STATUS,Z ;
goto MostrarVersion ; Si, muestra version
movf Estado,W ; Mensaje 02?
xorlw 0x02 ;
btfsc STATUS,Z ;
goto MostrarParado ; Si, muestra parado
movf Estado,W ; Mensaje 03?
xorlw 0x03 ;
btfsc STATUS,Z ;
goto MostrarActivado ; Si, muestra activado
clrf Estado ; ERROR!!!!, Reinicia variable de estado
MostrarRelays
call LCD_Borra ; Borra la pantalla del modulo LCD.
movlw Mensaje_Reles ; Muestra primera linea de mensaje
call LCD_Mensaje ; " R1 R2 R3 R4"
call LCD_Linea3 ; Selecciona 3a linea de display
call RS232_LineasBlanco ; Borra la pantalla del ordenador.
movlw Mensaje_Mostrarlinea ;
call RS232_Mensaje
movlw Mensaje_Cambiolinea
call RS232_Mensaje
movlw Mensaje_Reles ; Lo visualiza en el HyperTerminal.
call RS232_Mensaje
call RS232_LineasBlanco
movlw Mensaje_Cambiolinea
call RS232_Mensaje
btfss Relays,SalidaR1D ; Rele 1 encendido?
goto Mnsj_R1_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R2 ;
Mnsj_R1_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R2
btfss Relays,SalidaR2D ; Rele 2 encendido?
goto Mnsj_R2_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R3 ;
Mnsj_R2_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R3
btfss Relays,SalidaR3D ; Rele 2 encendido?
goto Mnsj_R3_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R4 ;
Mnsj_R3_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R4
btfss Relays,SalidaR4D ; Rele 3 encendido?
goto Mnsj_R4_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R5 ;
Mnsj_R4_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R5
btfss Relays,SalidaR5D ; Rele 2 encendido?
goto Mnsj_R5_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R6 ;
Mnsj_R5_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R6
btfss Relays,SalidaR6D ; Rele 2 encendido?
goto Mnsj_R6_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R7 ;
Mnsj_R6_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R7
btfss Relays,SalidaR7D ; Rele 2 encendido?
goto Mnsj_R7_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
goto Mnsj_R8 ;
Mnsj_R7_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
Mnsj_R8
btfss Relays,SalidaR8D ; Rele 4 encendido?
goto Mnsj_R8_OFF ; No, Escribe OFF
movlw Mensaje_ON ;
call LCD_Mensaje ;
movlw Mensaje_ON ;
call RS232_Mensaje
movlw Mensaje_Cambiolinea
call RS232_Mensaje
return ; Vuelve al programa principal.
Mnsj_R8_OFF
movlw Mensaje_OFF ;
call LCD_Mensaje ;
movlw Mensaje_OFF ;
call RS232_Mensaje
movlw Mensaje_Cambiolinea
call RS232_Mensaje
return ; Vuelve al programa principal.
MostrarVersion
movlw Mensaje_Info
movwf MensajeApuntado ; Guarda la posición del mensaje.
call LCD_Borra ; Borra la pantalla del modulo LCD.
movf MensajeApuntado,W ; Visualiza el mensaje en la pantalla
call LCD_Mensaje ; del visualizador LCD.
call RS232_LineasBlanco ; Borra la pantalla del ordenador.
movf MensajeApuntado,W
call RS232_Mensaje ; Lo visualiza en el HyperTerminal.
call RS232_LineasBlanco
return
MostrarParado
call Parado
call MostrarRelays
movlw MensajeParado
movwf MensajeApuntado ; Guarda la posición del mensaje.
; call LCD_Borra ; Borra la pantalla del modulo LCD.
call LCD_Linea4 ; Seleccionar la línea 4.
movf MensajeApuntado,W ; Visualiza el mensaje en la pantalla
call LCD_Mensaje ; del visualizador LCD.
call RS232_LineasBlanco ; Borra la pantalla del ordenador.
movf MensajeApuntado,W
call RS232_Mensaje ; Lo visualiza en el HyperTerminal.
call RS232_LineasBlanco
return
MostrarActivado
call Activar
call MostrarRelays
movlw Mensaje_Activar
movwf MensajeApuntado ; Guarda la posición del mensaje.
; call LCD_Borra ; Borra la pantalla del modulo LCD.
call LCD_Linea4 ; Seleccionar la línea 4.
movf MensajeApuntado,W ; Visualiza el mensaje en la pantalla
call LCD_Mensaje ; del visualizador LCD.
call RS232_LineasBlanco ; Borra la pantalla del ordenador.
movf MensajeApuntado,W
call RS232_Mensaje ; Lo visualiza en el HyperTerminal.
call RS232_LineasBlanco
return
;****************************************************************************
; Interrupción
;****************************************************************************
;****************************************************************************
; Subrutina
;****************************************************************************
Guardar_EEPROM
movlw .02
movwf EEADR
movf Relays,W
call EEPROM_EscribeDato
return
; btfss PEntradasC,EntradaR1C ; ¿Bit 0 del PORTA es "1"?
; goto D1_OFF
; bsf PSalidasD,SalidaR1D
; goto Principal
;D1_OFF
; bcf PSalidasD,SalidaR1D
; ---------------------------------------------------------------------------
; IF (FinTablaASCII>0xFF)
; ERROR "¡CUIDADO!: La tabla ha superado el tamaño de los"
; MESSG "primeros 256 bytes de memoria ROM. No funcionará correctamente."
; ENDIF
INCLUDE <RS232.INC>
INCLUDE <RS232MEN.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <RETARDOS.INC>
INCLUDE <EEPROM.INC>
END
¿Hay algún ejemplo que funcione bien?
Por ejemmplo, 256 caracteres en el org 0x00, luego otros 256 en ORG 0x0100, luego en el ORG 0x200.
Recordar que las instrucciones generales están en el ORG 0x00 así que ha de volver, en los otros ORG son sólo mensajes de ejemplo.
Saludo.