TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: jca en 06 de Febrero de 2008, 20:11:59
-
Buenas a todos de nuevo, espero que esta vez alguien me eche una mano, se que esto del asm esta en declibe pero seguimos quedando nostalgicos que todavía programamos en ello, bueno al lío....
El título lo dice todo.... al igual que mucha gente nos hemos pasado a la familia de los 18f jeje y estoy haciendo un programa que creo sencillo aunque por el contrario no termina de funcionar, ya he hecho bastantes cosillas con el usart de la familia 16f sin ningún problema, comunicaciones entre pics, comunicación con el pc en fin, pero con este micro no funciona, ante todo dar las gracias a PalitroqueZ por el post "Mi primeros pasos con el 18f4550" del cual me he ayudado para empezar con esta familia de micros....
Bueno os explico el programa.... tan solo pretendo establecer una comunicación con el pc por medio del usart, creo que es bastante sencillo y esta bien explicado, en principio configuro los puertos... los registros del usart... deshabilito los modulos que no voy a utilizar, enciendo y despues de un segundo apago el puerto D para saber que llego a la rutina de espera de interrupción, en esta rutina aprovecho para probar a mandar datos al pc, "aquí esta el primer fallo" que yo mando al pc un 31H(49 en decimal) el cual en ascii es un "1" lo conecto al hiperterminal y me aparece todo el rato un "elevado al cuadrado"(²) osease, que es como si yo estuviese mandando un FD(253 en decimal) :? incomprensible pero es asi.........en esta rutina estoy hasta que mando un dato desde el ordenador, esto hace saltar la interrupción y bueno lo único que pretendo es que lo que yo le mando desde el ordenador me lo muestre en binario por el puerto D con unos leds que tengo conectados y la verdad aqui está el otro fallo, da igual la tecla que pulses si son números muestra un (11000000) y si mando letras (00111110) :? incomprensible de nuevo...... tengo que decir que el puerto con el hiperterminal le configuro a 19200, bits de datos 8, paridad ninguna, bit de parada 1 y control de flujo ninguno(vaya, como lo tengo configurado en los registros del pic, o eso creo).
A continuación os pongo el programa para que le echeis un vistazo, a lo mejor es una tontería y estoy tan obcecado que no veo el fallo pero creo que no va a ser por no haberme leido y trasteado con los registros del pic para hacerlo funcionar pero nada.... no se pq manda ese dato cuando yo estoy poniendo que mande otro y tampoco se pq recibe eso......
List p=18F4550
#include "p18F4550.inc"
;configure a 20MHz crystal to operate at 48MHz
CONFIG FOSC = HSPLL_HS, PLLDIV = 5,CPUDIV = OSC1_PLL2,USBDIV = 2,PWRT = ON,BOR = SOFT, VREGEN = ON , WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
PDel0 equ 0x30
PDel1 equ 0x31
PDel2 equ 0x32
dato equ 0x33
org 0x00
goto inicio
;************************************************************************
;INTERRUPCION
;************************************************************************
org 0x04
Inter
btfss PIR1,RCIF ;Ha sido interrupción en la recepción ??
goto esperando ;No, falsa interrupción
bcf PIR1,RCIF ;Si, restaurar el flag de interrupción
movff RCREG, WREG ;Lee el dato recibido y lo pongo en W
movwf dato ;copio el dato a la variable dato
movff dato, PORTD ;muevo el dato al puerto D
nop
retfie
;************************************************************************
;INICIO DEL PROGRAMA Y CONFIGURACION DE REGISTROS
;************************************************************************
inicio
clrf TRISA ; configuar el portA como salida
clrf TRISB
movlw b'10000000'
movwf TRISC ;RC7/Rx RC6/Tx usart activado
clrf TRISD
clrf TRISE
movlw b'00100100'
movwf TXSTA ;TX en On, modo asíncrono con 8 bits y alta velocidad
movlw .64
movwf SPBRG ;19200 baudios con Fosc=20MHz
movlw b'00000000'
movwf BAUDCON
bsf PIE1,RCIE ;Habilita interrupción en la recepción
bsf IPR1,RCIP ;prioridad alta a interrupción del usart
bsf RCON,IPEN ;habilita prioridad de interrupciones
movlw b'11000000' ;Activa interrupción de periféricos
movwf INTCON ;Activa interrupciones
movlw b'10010000'
movwf RCSTA ;USART en On, recepción contínua
;*********************************************************
; deshabilitación de modulos
;*******************************************************
clrf,ADCON0 ; desactiva el CAD
movlw 0xf
movwf ADCON1 ; todas digitales
;bcf INTCON,GIE ; desactiva interrupciones
movlw 0x7
movwf CMCON ;desactiva el modulo comparador
;clrf CVRCON ; desactiva el Vref del comparador
clrf SPPCON ; desactiva el modulo (SPP)
clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
bcf UCON,USBEN ; desactiva el modulo USB
bsf INTCON2,RBPU ; desactiva las resistencias en PORTB
;*******************************************************
call DEMORA ;esto es para ver durante dos segundos lo que manda el ordenador antes de borrar el puerto
call DEMORA
clrf PORTD
nop
movlw 0xff
movwf PORTD
call DEMORA
clrf PORTD
esperando ;rutina de espera en la cual se manda un caracter cada 2 segundos
movlw 0x31 ;Envia el caracter, valor hex
movwf TXREG ;del codigo ascii
COMP_TX
btfss TXSTA,TRMT ;comprueba si acabo de Tx.
goto COMP_TX
call DEMORA
call DEMORA
goto esperando
;************************************************************************
;RETARDO DE 1 SEGUNDO
;************************************************************************
DEMORA
movlw .165 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0 movlw .41 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .147 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
return ; 2+2 Fin.
;************************************************************************
end
Espero encarecidamente que me echeis una mano pq es importante que este programa me salga, si no no voy a poder seguir adelante con el proyecto que tengo en mente...
1SAludo y Gracias.........
-
En un libro del 16F84a me pone que para el Hyperterminal que usamos es el bit de parada 2, y Baudios 9600.
Prueba esto por casualidad.
Si te pasa de baudios, habrá errores. Es como que una línea de letras que aparece en una anuncio que dan en TV justo debajo que se mueve muy rápido y no te da tiempo de leerlo de lo rápido que va.
EDIT:
Prueba con 9600 8-N-1 y otra con 9600 8-N-2
-
Gracias por tu interés meta en principio mi programa esta configurado para 19200 baudios a si que probé lo que me dijiste 19200 8-N-1 y 19200 8-N-2 poniendo en bit de parada un 2 mandaba y recivía diferentes cosas que antes pero siguen sin ser las buenas....
Seguiré probando a cambiar los fuses o los registros(pero ya al tuntun pq en principio creo que los registros estan asi bien) aber si suena la flauta pero vamos que si lo logro asi me llevaría a pensar que mi programa no es seguro y seguiria sin valerme, espero que alguien me diga algun fallo en concreto que tenga en el codigo...
1Saludo.....
-
Te toca probar el 9600 baudios por si las moscas. Hazlo a ver que pasa.
-
Buenas...nada sigue haciendolo mal :( la verdad no se que pensar estoy empezando a desesperarme....
-
Busca en los foros en buscar, si no te han ayudado alguien por algo es...
-
Hola Jca, si bien yo no trabajo con estos micros, pero veo un error en la interrupción, ya que no guardas o salvas los registros (ejemplo status o W) y no empleas ni retfie , por lo que al entrar a la interrupcion, luego continua con el inicio del programa :shock:
Suerte!
Norberto
-
Hola todopic gracias por tu aporte, pero no entiendo para que guardar por ejemplo el registro status, el W ya lo guardo en la variable dato aunque tampoco haría falta pq puedo mandar el dato que recibo desde el registro de recepción a W y de aqui al puerto, por ahora me da igual conservar el dato solo quiero ver que lo que envio y recibo es lo correcto y en cuanto al retfie lo único que consigo es que el micro no pase por el inicio del programa si no que vuelva a la rutina de espera dejandome asi el dato erroneo en el puerto todo el rato, creo que mi problema es con la velocidad del micro en transmision y recepción volveré a mirar los fuses por enesima vez haber que pasa pero no obstante muchas gracias otra vez....
Meta creo que ya no puedo leer mas veces los 6 u 8 post que salen cuando pones en el buscador "usart 18f4550" aunque de verdad que del único "y que nadie se sienta ofendido" que se saca algo en claro de este micro es del post de PalitroqueZ(por lo menos de todos los que he leido).
Saludos...
-
Buenas, jeje ya esta solucionado :-/ el error estaba en los fuses pensé que al configurarlos como los tenia me valdrían para cualquier programa tanto para el usart como para el futuro cuando intente implementar el usb y no es así....en fin... lo positivo de estos 3 dias es que ya se para que valen cada uno de los fuses que tiene el 18f4550 :mrgreen:
1Saludo y gracias a todos....
PD: por cierto para quien quiera el programa en los fuses ha de poner......
CONFIG FOSC = HS, PLLDIV = 5,PWRT = ON,BOR = SOFT, VREGEN = OFF , WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
-
PD: por cierto para quien quiera el programa en los fuses ha de poner......
CONFIG FOSC = HS, PLLDIV = 5,PWRT = ON,BOR = SOFT, VREGEN = OFF , WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
¿Y cómo los tenías antes que no te funcionaba? Por curiosidad.
-
Meta arriba del todo en la cabecera del programa que he publicado estan los antiguos fuses.....
Tb debo de decir que llevo bastante rato trasteando un poco y hay una cosa que es muy rara, por poner un ejemplo, mando el dato de la "a" que sería un 61H en binario un "01100001" vale? pues yo envio ese dato al ordenador y este por el hiperterminal entiende que es una "a" por lo que supongo que lo envia bien pero si yo desde el ordenador envio una "a" el pic me muestra en el puerto un "01000001", lo mismo ocurre si mando el dato a otro 18f4550, por lo que el programa todavia no funciona al 100%, a alguien se le ocurre que es lo que pasa?he pensado que podía ser el comando movwf PORTD, y lo he cambiado por movwf LATD pero nada, hace lo mismo..... :?
-
Bueno aqui seguimos cacharreando con el micro...ya he visto cual es el fallo, no es que mande el dato mal ni nada por el estilo, si no que no muestra bien los datos por el puerto....parece ser que solo estan configurados los pines RD0, RD1, RD6 y RD7 vamos que solo son esos los que puedo encender, desde RD2 hasta RD5 nada, esos no hay manera de encenderlos, he desactivado el modulo CCP el SPP el ECCP he configurado el pin RDPU del PORTE que por lo visto tb configura los pines del PORTD, en fin no me quedan mas "ces" y mas "pes" que desactivar pero sigue sin funcionar bien el puerto,por no decir tb que a las 10 o 12 veces que le mando algo por el usart se queda bloqueado y hay que resetearlo...
Y yo me pregunto.... se an dado cuenta estos ingeniertos de microchip lo dificil que es configurar estos micros, para que luego en definitiva la aplicación te siga sin funcionar, pq vamos creo que programa mas simple que este no se puede hacer, os habeis dado cuenta de que para hacer que funcione el puertoD hay que configurar 5 registros?(y sigue sin funcionar) y bueno sin hablar de los fuses que son un total de 14 registros con una media de 6 bit configurables cada uno, todo esto para intentar controlar solo el usart, imaginaros cuando intente poner a trabajar el USB el USART y el I2C en el mismo micro :? la cantidad de registros va a subir exponencialmente, aunque la verdad que se me estan quitando las ganas... pq si para hacer funcionar un puerto llevo 2 dias y no lo he conseguido será imposible hacer lo otro..... :(
PD: Bit a Bit si puedo encenderlo osea que si le mando la orden de encender el bit 5, o el 3, o el 2 del puertoD los enciende, pero si mando un dato previamente grabado en un registro no los enciende..... :shock:
-
hola
creo que deberias hacer caso a todopic, y guardar los registros que se puedan modificar durante la rutina de interrupcion, como W, STATUS,FSR si lo usas ..... y algun otro de los 18f que yo desconozco, seguramente sea por eso por lo que tienes que reiniciar cuando le envias datos, piensa que si envias un dato cuando esta moviendo w a otro registro , salta la interrupcion y se modifica w el dato que guardara al volver al programa principal sera otro, lo mismo que status este ha de hacerse con swap o si te pilla el salto en una rutina de demora que utilicen tanto el prog principal como la interrupcion, cuando vuelva de esta los registros de la demora estarán en un valor diferente pues cambió el valor de los registros durante la rutina de interrupción y estaran a cero al volver al prog principal. yo solo te he puesto un par de ejemplos del por qué se recomienda guardarlos , ahora es tu criterio quien debe decidir como hacerlo
este es un ejemplo para un 16f877 tendras que ver que registros son para un 18
INTERRUP
MOVWF W_TEMP
SWAPF STATUS,W
BANKSEL STATUS_TEMP
MOVWF STATUS_TEMP
SWAPF STATUS_TEMP,W
MOVWF STATUS
MOVF W_TEMP,W
BANKSEL W_TEMP
MOVWF W_TEMP
BANKSEL PCLATH_TEMP
MOVF PCLATH,W
MOVWF PCLATH_TEMP
testea el tipo de interrupcion....
FIN_INT
BCF STATUS,RP0
CALL CONTADOR
CALL ENVIA_TEXTO
CLRF PIR1
CLRF PIR2
BSF STATUS,RP0
CLRF PIE1
CLRF PIE2
BSF PIE1,RCIE
BSF INTCON,6
BSF INTCON,5
BSF INTCON,4
BCF INTCON,3
MOVF FSR_TEMP,W
MOVWF FSR
MOVF PCLATH_TEMP,W
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
MOVF W_TEMP,W
RETFIE
aps se me olvidaba tienes este post que hizo Maunix de eco con la usart (http://www.todopic.com.ar/foros/index.php?topic=13698.msg80327#msg80327) para un 18f
un saludo espero te sirva
-
Gracias alogic.on por tu aporte....no es problema de guardar registros...pues con la idea de hacer un eco he visto que el programa funciona perfectamente, cuando lo conecto al hiperterminal la tecla que le mando me la devuelve bien al pc jeje :mrgreen: "Me da verguenza decir esto" pero creo que no voy a conseguir mostrar por el puertoD lo que ponga en un registro, que es lo que no consigo....y ahi es donde esta el error, el recibir y enviar datos por el usart funciona perfectamente....
1saludo y gracias....
-
Hola de nuevo... aqui sigo peleandome con el 18f4550 y el ensamblador...creo que estoy llegando a la conclusión de que es imposible controlar los puertos en este micro con el ensamblador, despues de ser incapaz de conseguir mostrar un registro por el puerto D ahora estoy intentando que valla mirando una a una las patas del puerto B y en función de como esten si a 1 o a 0 pues que haga una cosa u otra, por supuesto TRISB configurado como entrada...el RBPU del INTCON2 a 1 para quitar las resistencias del puerto...cargo un F en el ADCON1 para poner todos los pines digitales...en fin...ya no se me ocurre nada mas y este simpre programa de 3 instrucciones que pongo a continuacion es imposbible hacerlo funcionar:
esperando
btfss PORTB,2 ;pregunto si la pata 2 del puerto B esta a 1
goto esperando ;si es 1 que salte, si no que siga esperando
movlw 0x02
movwf datousart_out ;pongo el dato en el registro
call mandar_dato ;subrrutina mandar dato por usart al pc
me gustaría que alguien me explicase por que sin tener la pata 2 del puertoB 5v manda todo el rato el dato, me pregunto si programase este chisme en C de verdad no tendría todos estos problemas???
1Saludo.... espero alguna repuesta que me pueda solucionar esto pq me esta volviendo loco.... al final mucho 18f y voy a tener que volver a los 16 que por lo visto son los únicos que hacen caso a las instrucciones que pongo.....