ensamblador – Doubt code in assembly language of communication port RS232 and PIC16F84A

Question:

I have this code in assembly language:

LIST P=PIC16F84A    ; Pic a usar

#INCLUDE P16F84A.INC    ; Lista de etiquetas de microchip

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

_CP_ON      EQU H'000F' ; Activa code protect
_CP_OFF     EQU H'3FFF' ; Desactiva code protect
_PWRTE_ON   EQU H'3FF7' ; Activa power on reset
_PWRTE_OFF  EQU H'3FFF' ; Desactiva power on reset
_WDT_ON     EQU H'3FFF' ; Activa Watchdog
_WDT_OFF    EQU H'3FFB' ; Desactiva Watchdog
_LP_OSC     EQU H'3FFC' ; Oscilador LP
_XT_OSC     EQU H'3FFD' ; Oscilador XT
_HS_OSC     EQU H'3FFE' ; Oscilador HS
_RC_OSC     EQU H'3FFF' ; Oscilador RC

__CONFIG    _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC       

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

;STATUS equ 0x03         ; Aquí le asignamos nombres a los 
;TRISA  equ 0x05         ; registros indicando la posición
;PORTA  equ 0x05
;TRISB  equ 0x06         ; en la que se encuentran 

TXREG   EQU 0x0D        ; Registro de transmisión
BITS    EQU 0x0E        ; Número de bits de datos
CNTMSEC EQU 0x0F        ; Número de milisegundos de retardo

;**************************************************************
    ORG 0   ;Comando que indica al Ensamblador
        ;la dirección de la memoria de programa
        ;donde situar la siguiente instrucción
;**************************************************************

INICIO
    BSF STATUS,RP0  ; Activa el banco de memoria 1.
    MOVLW   0       ; son salidas
    MOVWF   TRISA       ; en el puerto A
    MOVLW   0XFF        ; SON ENTRADAS
    MOVWF   TRISB       ; EN EL PUERTO B
    BCF STATUS,RP0  ; Activa el banco de memoria 0.
    BSF PORTA,0     ; ponemos a nivel alto la salida serie. Línea en reposo.
    MOVLW   0xC8        ; retardo de 200 msec.
    CALL    NMSEC       ; para que no afecten las fluctuaciones del encendido
    MOVF    TRISB,0     ; Cargo w con el valor del puerto B
    CALL    OUTCH       ; llama a la rutina de comunicación serie

    MOVLW   0X0D        ;
    CALL    OUTCH       ; 
    MOVLW   0X0A        ;
    CALL    OUTCH       ;
    MOVLW   0X00        ;
    CALL    OUTCH       ;



DATO    NOP

    GOTO    DATO        ; nos quedamos aqui, en un bucle infinito

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

OUTCH
    MOVWF   TXREG       ; coloca W en el registro de transmisión
    MOVLW   8       ; 8 bits de datos serán transmitidos
    MOVWF   BITS        ; BITS es un contador para los bits
    BCF PORTA,0     ; bit de inicio en la salida serie (activo a nivel bajo)
TXLOOP  
    MOVLW   0x31        ; Retardo de 196 microsegundos 31h = 49d
    CALL    MIC4        ; 49 x 4 = 196 microsegundos
    RRF TXREG, f    ; rotamos a la derecha el bit en el acarreo
    BTFSC   STATUS, C   ; si el acarreo es 0 saltamos y ponemos la línea a nivel bajo
    GOTO    SETUNO      ; si no, ponemos la línea a nivel alto
SETCERO
    BCF PORTA,0     ; Ponemos la salida serie a nivel bajo (transmitir un 0) 
    GOTO    TDONE       ; Comprobar si se han transmitido todos los bits de TXREG
SETUNO
    BSF PORTA,0     ; Ponemos la salida serie a nivel alto (transmitir un 1) 
    NOP         ; pasamos a probar si acabamos, directamente
TDONE   
    DECFSZ  BITS, f     ; se decrementa BITS por el bit transmitido y salta cuando llega a cero
    GOTO    TXLOOP      ; quedan más bits, vamos a transmitir el siguiente
    MOVLW   0x34        ; Retardo de 208 microsegundos 34h = 52d
    CALL    MIC4        ; 52 x 4 =  208 microsegundos para el último bit de datos que queda
    BSF PORTA,0     ; Salida serie a nivel alto para el bit de stop
    MOVLW   0x68        ; retardo de 104 x 4 microsegundos 68h = 104d
    CALL    MIC4        ; 104 x 4 =  416 microsegundos para dos bits de parada
    RETURN

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

NMSEC   
    MOVWF   CNTMSEC     ; mueve W al registro msec
MSLOOP  
    MOVLW   0xF8        ; cuenta 8 microsegundos por encima
    CALL    MIC4        ; 248 * 4 + 2 = 994
    NOP         ; realiza el resto del bucle
    NOP         ; añade 6 microsegundos
    DECFSZ  CNTMSEC, f  ; decrementa el contador y salta cuando llega a cero
    GOTO    MSLOOP      ; vuelve a realizar el bucle
    RETURN

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

MIC4
    ADDLW   0xFF        ; substrae 1 de W
    BTFSS   STATUS,Z    ; salta cuando llega a cero
    GOTO    MIC4        ; si no llega a cero vuelve a restar
    RETURN


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

    END

What I need is to be able to create a communication between the PIC and a MAX232 to pass data from an LM35 temperature sensor, through an RS232 port, to a computer. I have already created the interface to calculate the temperature, but when I load the .HEX to the PIC , it does not recognize the temperature in the interface. According to the code, it's wrong, but I can't find the error. My guess is that the connection to the data is missing in the code, but I can't find the error. Any idea how to fix the problem?

Answer:

Good day,

I was looking at your code, it is very similar to the one found at http://perso.wanadoo.es/pictob/comunicacion_pic_pc_via_rs232.htm . From the looks of it, Port A is configured as all pins outputs, while Port B is configured as inputs.

If we analyze this code fragment:

INICIO
BSF STATUS,RP0  ; Activa el banco de memoria 1.
MOVLW   0       ; son salidas
MOVWF   TRISA       ; en el puerto A
MOVLW   0XFF        ; SON ENTRADAS
MOVWF   TRISB       ; EN EL PUERTO B
BCF STATUS,RP0  ; Activa el banco de memoria 0.
BSF PORTA,0     ; ponemos a nivel alto la salida serie. Línea en reposo.
MOVLW   0xC8        ; retardo de 200 msec.
CALL    NMSEC       ; para que no afecten las fluctuaciones del encendido

Just from the following lines you have to see in detail:

MOVF    TRISB,0     ; Pone en el registro de trabajo "0x86"
CALL    OUTCH       ; llama a la rutina de comunicación serie y envia al puerto el valor del registro de trabajo.

MOVLW   0X0D        ; Retorno de Carro
CALL    OUTCH       ; 
MOVLW   0X0A        ; Nueva Linea
CALL    OUTCH       ;
MOVLW   0X00        ; Final del Mensaje
CALL    OUTCH       ;

Then we have:

DATO NOP GOTO DATO ;nos quedamos aquí, en un bucle infinito

This loop is not going to perform any operations.

What it does up to this point is:

  • Defined the PIC.
  • Defined the ports of Inputs / Outputs.
  • 0x86, Carriage return, End of message is sent.
  • Infinite loop with no operations (NOP).

It would be missing (inside the infinite loop):

  • Read LM35 which should be connected to PortB via an A/D converter.
  • Send what was read to the PC.
  • Convert the value to C°.

If you pass a diagram of how you are doing it could advance more.

Scroll to Top