Ejemplo de programación del módulo PSP

23 04 2008

;*************************************************************************

;* Este programa sirve como demostración del funcionamiento del Puerto Esclavo    

;* paralelo en un PIC16C64/74. El programa esta basada en una rutina de interrupción

;* que se ejecuta cada vez que el PIC trata de ser leido o escrito por el sistema

;* externo a él.

;* Si la interrupción se origina por una lectura, un registro se incrementa

;* y el nuevo valor del contador se coloca en la cola de mensajes de salida.

;* Si la interrupción es originada por una escritura, el dato escrito es sacado

;* por el PORTB.

;*

;* Traducido por Francisco Fernández Linera

;* Ver nota de aplicación 579 de microchip.

 

;;**************************************************************************

      list p=16f877

      include “p16f877.inc”

 

;Definición de registros

 

FLAGREG      equ      20h         ;registro de flags

OUTDATA      equ      21h         ;dato de salida

INDATA       equ      22h         ;dato de entrada

COUNT        equ      23h         ;Contador para las lecturas del registro de salida

 

;Definición de bits para el registro de flags

 

err           equ      00h         ;flag de error

OUTRDY        equ      01h         ;flag de dato preparado en salida

INFULL        equ      02h         ;flag de dato de entrada recibido

 

              org      0000h       ;Vector de reset

              goto      Start

 

              org      0005h       ;Vector de interrupción

              goto      Service_Int

 

Start

              clrf      OUTDATA           ;Limpia registros de datos

              clrf      INDATA

              bsf         STATUS,RP0  ;Banco 1

              movlw      b’00010111′ ;Set RD, WR, y CS como

              movwf      TRISE       ;entradas, puerto esclavo paralelo habilitado

              movlw      0FFh

              movwf      TRISB       ;PORTB como salidas

              movlw      b’10000000′ ;

              movwf      PIE1        ;Habilita interrupción del PSP

              bcf         STATUS,RP0  ;Banco 0

 

              movf      OUTDATA,W   ;Dato de salida al PORTD

              movwf      PORTD      

              movlw      b’11000000′ ;Set GIE, PEIE (habilita interrupciones)

              movwf      INTCON

 

Loop

              btfss      FLAGREG,INFULL      ;Chequea si se ha recibido dato de entrada

              goto       Checkout    ;Si no, chequea salida

              bcf        FLAGREG,INFULL      ;Limpia flag de dato de entrada preparado

              movf      INDATA,W    ;Coge el dato de entrada

              movwf      PORTB       ;Lo saca por el PORTB

 

Checkout

               btfsc      FLAGREG,OUTRDY      ;Chequea si dato de salida preparado

               goto      Loop        ;Si no, vuelve al bucle Loop

               incf      COUNT, F      ;Incrementa contador de dato de salida

               movf      COUNT,W           ;Coge el contador

               movwf      OUTDATA           ;y lo pone en la cola de salida

               bsf         FLAGREG,OUTRDY      ;Pone el flag de dato de salida preparado a 1

               goto      Loop

 

;********************************************************************************

;*Rutina de interrupción

;*      Entradas:FLAGREG – Registro de flags para/desde la rutina principal:

;*          Bit 1: OUTRDY -      Indica a la rutina de interrupción

;*          que el dato esta preparado en la cola de salida.

;*          OUTDATA    – dato de la cola de salida

;*          PIR1       – Registro del flag de interrupción

;*          TRISE      – Registro de falgs del Puerto Esclavo Paralelo

;*          PORTD      – Dato de entrada desde el puerto esclavo

;*

;*      Salidas:

;*          PORTD        – Dato de salida para el puerto esclavo

;*          INDATA       – Cola de datos de entrada

;*          FLAGREG      – Registro de flags para/desde la rutina principal:

;*          Bit 0: ERROR -  Desde la rutina de interrupcion, indica overflow en el buffer de entrada.

;*          Bit 2: INFULL -      Desde la rutina de interrupción, indica dato recibido almacenado en INDATA.

;*********************************************************************************

 

Service_Int

      btfss      PIR1,PSPIF  ;Miro si hay interrupciones en el PSP

      goto       Intout            ;No hay, salgo

      bcf        PIR1,PSPIF      ;Limpio falg del PSP

      bsf        STATUS,RP0  ;Banco 1

      btfss      TRISE,IBF      ;Chequeo si dato de entrada preparado

      goto       Notinput    ;Si no hay entrada, chequeo salida

      bcf        STATUS,RP0      ;Entrada preparada, Banco 0

      bsf        FLAGREG,INFULL      ;Pongo a 1 el flag para la rutina principal

      movf       PORTD,W     ;Cogo el dato de entrada

      movwf      INDATA            ;Pongo el byte en la cola de entrada

 

Notinput

      btfsc      TRISE,OBF      ;Chequeo si dato de salida preparado

      goto       Intout            ;No preparado, me salgo

      bcf        STATUS,RP0  ;Banco 0

      btfss      FLAGREG,OUTRDY      ;Chequeo si hay dato en la cola de salida.

      goto       Intout            ;salida no preparada, me salgo

      movf       OUTDATA,W   ;Cojo dato desde la cola

      movf       PORTD, F      ;Ponemos dato en el buffer de salida

      bcf        FLAGREG,OUTRDY      ;Limpio falg para la rutina principal

Intout

      bsf         STATUS,RP0  ;Banco 1

      btfsc       TRISE,IBOV      ;Chequeo flag de overflow en el buffer de entrada

      goto        Interror    ;si no esta a 0, error

      bcf         STATUS,RP0  ;Banco 0

      retfie                        ;Rehabilito GIE y retorno

Interror   

      bcf          STATUS,RP0  ;Banco 0

      bsf          FLAGREG,err ;Pongo a 1 el flag de error para la rutina principal

      retfie                        ;Rehabilito GIE y retorno

     

      end

 

 

 

 


Acciones

Información

Deja un comentario