TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: tomasguido en 13 de Abril de 2020, 00:19:28
-
Hola gente haber si puedo explicarme bien, necesito enviar un dato via serie, usando el pic 16f877a y su modulo usart, el codigo que coloco a continuación funciona correctamente, lo he probado en proteus y en la vida real.
#include "p16f877a.inc"
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
varA EQU 20
varB EQU 21
varC EQU 22
varD EQU 23
R_ContA EQU 24
R_ContB EQU 25
R_ContC EQU 26
BCD_Centenas EQU 27 ; Carga los registros con el resultado inicial.
BCD_Decenas EQU 28 ; En principio las centenas y decenas a cero.
BCD_Unidades EQU 29
TEMP_HIGH EQU 30
ORG 0
Configuracion_del_pic:
CLRF PORTA
CLRF PORTB
CLRF PORTC
BCF STATUS, RP1 ;accedo al banco 1
BSF STATUS, RP0
MOVLW B'00000111' ;modulo comparador apagado
MOVWF CMCON
MOVLW B'10011000' ; RC3, RC4 are inputs for PORTC
MOVWF TRISC
MOVLW B'00000000' ;portb.1 y portb.2 es entrada los demas salida
MOVWF TRISB
MOVLW B'00100100' ;configuro el registro TXSTA
MOVWF TXSTA
MOVLW D'25' ;cargo el registro SPBRG con la variable correpondiete segun la formula para 9600 baudios, 9 para 115200
MOVWF SPBRG
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
MOVLW B'10010000'
MOVWF RCSTA
CLRF PORTA
CLRF PORTB
CLRF PORTC
Inicio_del_pic:
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
BSF PORTB,0 ; nivel alto el bit cero del puerto b
CALL Retardo_1s
BCF PORTB,0 ; nivel bajo el bit cero del puerto b
CALL Retardo_1s
MOVLW 'I' ; envia caracter A
CALL RS232_EnviaDato
MOVLW 'N' ; envia caracter T
CALL RS232_EnviaDato
MOVLW 'I' ; envia caracter A
CALL RS232_EnviaDato
MOVLW 'C' ; envia caracter T
CALL RS232_EnviaDato
MOVLW 'I' ; envia caracter A
CALL RS232_EnviaDato
MOVLW 'O' ; envia caracter T
CALL RS232_EnviaDato
SLEEP
;-----------------------envio y recepcion de datos por puerto serial------------
RS232_EnviaDato:
MOVWF TXREG
BCF STATUS, RP1 ;accedo al banco 1
BSF STATUS, RP0
espero:
BTFSS TXSTA,TRMT ;verifico que ya se envio
GOTO espero
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
RETURN
espera_dato:
BTFSS PIR1,RCIF
GOTO espera_dato
si_hay_error:
BTFSC RCSTA,OERR
CALL error1
BTFSC RCSTA,FERR
CALL error2
MOVF RCREG,W
RETURN
error1:
BCF RCSTA,CREN
BSF RCSTA,CREN
RETURN
error2:
MOVF RCREG,W
RETURN
;-------------------------------------------------------------------------------
;----------------------------Zona de retardos-----------------------------------
Retardo_20s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_10s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_5s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'50' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_2s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_1s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'10' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_500ms: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "N".
Retardo_1Decima:
movwf R_ContC ; Aporta 1 ciclo máquina.
R1Decima_BucleExterno2:
movlw d'100' ; Aporta Nx1 ciclos máquina. Este es el valor de "M".
movwf R_ContB ; Aporta Nx1 ciclos máquina.
R1Decima_BucleExterno:
movlw d'249' ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta MxNx1 ciclos máquina.
R1Decima_BucleInterno:
nop ; Aporta KxMxNx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.
decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.
return
END
AHORA EL PROBLEMA:
La siguiente rutina funciona correctamente (pertenece al codigo),y envía y llega correctamente una "A" al Virtual terminal:
MOVLW 'A'
CALL RS232_EnviaDato
Ahora si yo hago esta otra rutina no llega nada al virtual terminal:
MOVLW B'1000001' (Corresponde a una A)
CALL RS232_EnviaDato
Ahora mi problema es que quiero mover una variable al registro TXREG(que podria provenir de la lectura de un sensor), para así enviarla por el puerto serie y que llegue al virtual terminal un numero decimal, por ejemplo quiero mover a TXREG B'10001110'(en decimal142) y que en el virtual terminal se vizualice 142, y no estoy pudiendo lograr esto ya que se hace un poco dificil encontrar proyectos en ENSAMBLADOR. Gracias y espero puedan ayudarme...
-
Busca algún código ASM que te transforme binario a BCD unpacked, o hacelo vos mismo.
Así tú binario que era 142 decimal queda separado en 3 registros conteniendo 1,4 y 2 respectivamente. (Separa centenas, decenas y unidades, podés hacerlo con restas)
El tema es que el ASCII de cero no es 0 es 48, así que si querés que aparezca el número en el terminal debes sumarle '0' o 0x30 o 48, todos iguales.
Y ahora sí tú código va a enviar en decimal 49,52,50. Que en el terminal aparecerá como '1','4','2'
Resumiendo el cuento, tenes que trasformar el numero a ASCII, entre medio vas a tener que separarlo en BCD.
-
.......
AHORA EL PROBLEMA:
La siguiente rutina funciona correctamente (pertenece al codigo),y envía y llega correctamente una "A" al Virtual terminal:
MOVLW 'A'
CALL RS232_EnviaDato
Ahora si yo hago esta otra rutina no llega nada al virtual terminal:
MOVLW B'1000001' (Corresponde a una A)
CALL RS232_EnviaDato
????? Yo copypego tu código e inserto eso y al terminal llega todo bien (como era de esperar)
Ahora mi problema es que quiero mover una variable al registro TXREG(que podria provenir de la lectura de un sensor), para así enviarla por el puerto serie y que llegue al virtual terminal un numero decimal, por ejemplo quiero mover a TXREG B'10001110'(en decimal142) y que en el virtual terminal se vizualice 142, y no estoy pudiendo lograr esto ya que se hace un poco dificil encontrar proyectos en ENSAMBLADOR. Gracias y espero puedan ayudarme...
Como ya te dijeron necesitás una rutina que convierta byte a ascii.
Este es un ejemplo hecho por el camino fácil --> retocar el código generado en C:
Byte2Asc:
;-- num = W
MOVWF num
;-- Uni = Dec = Cen = '0'
MOVLW 30
MOVWF Cen
MOVWF Dec
MOVWF Uni
;-- while(num>=100){ num-=100 ; Cen++ ;}
MOVF num,W
L016: ADDLW D'156' ; 256-100
BTFSS STATUS,C
GOTO L01E
MOVWF num
INCF Cen,F
GOTO L016
;-- while(num>=10) { num-=10 ; Dec++ ;}
L01E: MOVF num,W
L01F: ADDLW D'246' ; 256-10
BTFSS STATUS,C
GOTO L026
MOVWF num
INCF Dec,F
GOTO L01F
;-- Uni+=num
L026: MOVF num,W
ADDWF Uni,F
return
En el programa la llamás:
MOVWF dato ; el byte a convertir
CALL Byte2Asc
MOVF Cen,W ; Las centenas las devuelve en Cen
CALL RS232_EnviaDato
MOVF Dec,W ; Las decenas las .........
CALL RS232_EnviaDato
MOVF Uni,W ; Las unidades ........
CALL RS232_EnviaDato
-
bueno gente necesitaba una pequeña cachetada para darme cuenta :lol:, ya lo logre y ya que estoy dejo la rutina por si a otro le sirve, seguramente no es la rutina mas eficiente pero funciona correctamente, aca el codigo:
#include "p16f877a.inc"
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
R_ContA EQU 20
R_ContB EQU 21
R_ContC EQU 22
BCD_Centenas EQU 23
BCD_Decenas EQU 24
BCD_Unidades EQU 25
TEMP_HIGH EQU 26
TEMP_LOW EQU 27
dat EQU 29
ORG 0
Configuracion_del_pic:
CLRF PORTA
CLRF PORTB
CLRF PORTC
BCF STATUS, RP1 ;accedo al banco 1
BSF STATUS, RP0
MOVLW B'00000111' ;modulo comparador apagado
MOVWF CMCON
MOVLW B'10011000' ; RC3, RC4 are inputs for PORTC
MOVWF TRISC
MOVLW B'00000000' ;portb.1 y portb.2 es entrada los demas salida
MOVWF TRISB
MOVLW B'00100100' ;configuro el registro TXSTA
MOVWF TXSTA
MOVLW D'25' ;cargo el registro SPBRG con la variable correpondiete segun la formula para 9600 baudios, 9 para 115200
MOVWF SPBRG
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
MOVLW B'10010000'
MOVWF RCSTA
CLRF PORTB
CLRF BCD_Unidades
CLRF dat
Inicio_del_pic:
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
BSF PORTB,0 ; nivel alto el bit cero del puerto b
CALL Retardo_1s
BCF PORTB,0 ; nivel bajo el bit cero del puerto b
CALL Retardo_1s
MOVLW B'11111111' ; numero decimal 255
CALL RS232_EnvioDecimal
SLEEP
;-----------------------envio y recepcion de datos por puerto serial------------
RS232_EnviaDato:
MOVWF TXREG
BCF STATUS, RP1 ;accedo al banco 1
BSF STATUS, RP0
espero:
BTFSS TXSTA,TRMT ;verifico que ya se envio
GOTO espero
BCF STATUS, RP1 ;accedo al banco 0
BCF STATUS, RP0
RETURN
espera_dato:
BTFSS PIR1,RCIF
GOTO espera_dato
si_hay_error:
BTFSC RCSTA,OERR
CALL error1
BTFSC RCSTA,FERR
CALL error2
MOVF RCREG,W
RETURN
error1:
BCF RCSTA,CREN
BSF RCSTA,CREN
RETURN
error2:
MOVF RCREG,W
RETURN
;-------------------------------------------------------------------------------
;----------------------------Zona de retardos-----------------------------------
Retardo_20s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_10s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_5s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'50' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_2s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_1s: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'10' ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_500ms: ; La llamada "call" aporta 2 ciclos máquina.
movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "N".
Retardo_1Decima:
movwf R_ContC ; Aporta 1 ciclo máquina.
R1Decima_BucleExterno2:
movlw d'100' ; Aporta Nx1 ciclos máquina. Este es el valor de "M".
movwf R_ContB ; Aporta Nx1 ciclos máquina.
R1Decima_BucleExterno:
movlw d'249' ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta MxNx1 ciclos máquina.
R1Decima_BucleInterno:
nop ; Aporta KxMxNx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.
decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;-------------------------------------------------------------------------------
RS232_EnvioDecimal:
CLRF BCD_Centenas ; Carga los registros con el resultado inicial.
CLRF BCD_Decenas ; En principio las centenas y decenas a cero.
movwf BCD_Unidades ; Se carga el número binario a convertir.
BCD_Resta10:
movlw B'00001010' ; A las unidades se les va restando 10 en cada
subwf BCD_Unidades,W ; pasada. (W)=(BCD_Unidades) -10.
btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?
goto BIN_BCD_Fin ; No, es menor de 10. Se acabó.
BCD_IncrementaDecenas:
movwf BCD_Unidades ; Recupera lo que queda por restar.
incf BCD_Decenas,F ; Incrementa las decenas y comprueba si ha llegado
movlw B'00001010' ; a 10. Lo hace mediante una resta.
subwf BCD_Decenas,W ; (W)=(BCD_Decenas)-10).
btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Decenas)>=10?
goto BCD_Resta10 ; No. Vuelve a dar otra pasada, restándole 10 a
BCD_IncrementaCentenas: ; las unidades.
clrf BCD_Decenas ; Pone a cero las decenas
incf BCD_Centenas,F ; e incrementa las centenas.
goto BCD_Resta10 ; Otra pasada: Resta 10 al número a convertir.
BIN_BCD_Fin:
CLRF dat
MOVF BCD_Centenas,W
MOVWF dat
CALL envio_numero
CLRF dat
MOVF BCD_Decenas,W
MOVWF dat
CALL envio_numero
CLRF dat
MOVF BCD_Unidades,W
MOVWF dat
CALL envio_numero
RETURN
envio_numero:
MOVF dat,W
SUBLW B'00000000' ;es 0?
BTFSC STATUS,Z
GOTO envia_numero_0
MOVF dat,W
SUBLW B'00000001' ;es 1?
BTFSC STATUS,Z
GOTO envia_numero_1
MOVF dat,W
SUBLW B'00000010' ;es 2?
BTFSC STATUS,Z
GOTO envia_numero_2
MOVF dat,W
SUBLW B'00000011' ;es 3?
BTFSC STATUS,Z
GOTO envia_numero_3
MOVF dat,W
SUBLW B'00000100' ;es 4?
BTFSC STATUS,Z
GOTO envia_numero_4
MOVF dat,W
SUBLW B'00000101' ;es 5?
BTFSC STATUS,Z
GOTO envia_numero_5
MOVF dat,W
SUBLW B'00000110' ;es 6?
BTFSC STATUS,Z
GOTO envia_numero_6
MOVF dat,W
SUBLW B'00000111' ;es 7?
BTFSC STATUS,Z
GOTO envia_numero_7
MOVF dat,W
SUBLW B'00001000' ;es 8?
BTFSC STATUS,Z
GOTO envia_numero_8
GOTO envia_numero_9
envia_numero_0:
MOVLW '0' ; envia caracter 0
CALL RS232_EnviaDato
RETURN
envia_numero_1:
MOVLW '1' ; envia caracter 1
CALL RS232_EnviaDato
RETURN
envia_numero_2:
MOVLW '2' ; envia caracter 2
CALL RS232_EnviaDato
RETURN
envia_numero_3:
MOVLW '3' ; envia caracter 3
CALL RS232_EnviaDato
RETURN
envia_numero_4:
MOVLW '4' ; envia caracter 4
CALL RS232_EnviaDato
RETURN
envia_numero_5:
MOVLW '5' ; envia caracter 5
CALL RS232_EnviaDato
RETURN
envia_numero_6:
MOVLW '6' ; envia caracter 6
CALL RS232_EnviaDato
RETURN
envia_numero_7:
MOVLW '7' ; envia caracter 7
CALL RS232_EnviaDato
RETURN
envia_numero_8:
MOVLW '8' ; envia caracter 8
CALL RS232_EnviaDato
RETURN
envia_numero_9:
MOVLW '9' ; envia caracter 9
CALL RS232_EnviaDato
RETURN
END