TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: guancho2002 en 05 de Noviembre de 2008, 12:32:58
-
Algún alma caritativa... :(
Resulta que estoy montando un 18F452 con dos PCF8574, uno con LEDS y el otro con pulsadores. Pués bien, no sé que puede estar ocurriendo que me enciende leds aleatoriamente y no como le digo que haga. Para esto estoy utilizando la interrupción 0 como aviso de que se ha pulsado alguna tecla pero no termina de ir bien... ¿alguien que puede ayudarme? Gracias.
DEVICE=18F452
XTAL=20
@CONFIG_REQ
@__CONFIG CONFIG1H, OSCS_OFF_1 & HS_OSC_1
@__CONFIG CONFIG2L, PWRT_ON_2
@__CONFIG CONFIG2H, WDT_OFF_2 & WDTPS_128_2
@__CONFIG CONFIG4L, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
DECLARE SCL PORTC.3
DECLARE SDA PORTC.4
DECLARE SLOW_BUS ON
TRISB = %00000001
SYMBOL GIE = INTCON.7 'Habilitar las interrupciones
SYMBOL INT0IE = INTCON.4
SYMBOL INT0IF = INTCON.1
SYMBOL INTEDG0=INTCON2.6
SYMBOL RBPU=INTCON2.7
INTEDG0=0
RBPU=0 'Habilita la resistencia interna para la interrupción.
DIM PCFBTN AS BYTE
DIM LEDFIN AS BYTE
ON_INTERRUPT GoTo Interrupcion
GoTo Inicio
Interrupcion:
GIE=0
INT0IE=0
HBUSIN %01000011,[PCFBTN]
DELAYMS 20
INT0IF=0
INT0IE=1
GIE=1
RETFIE
Inicio:
HBUSOUT %01000000,[%11111111] 'Borra los puertos del expansor
LEDFIN=%11111111
PORTB=0
INT0IE=1
GIE = 1
Bucle:
IF PCFBTN=%11111110 THEN LEDFIN=%00000001 ^ LEDFIN:GOsub Boton
IF PCFBTN=%11111101 THEN LEDFIN=%00000010 ^ LEDFIN:GOsub Boton
IF PCFBTN=%11111011 THEN LEDFIN=%00000100 ^ LEDFIN:GOsub Boton
IF PCFBTN=%11110111 THEN LEDFIN=%00001000 ^ LEDFIN:GOsub Boton
GOTO Bucle
Boton:
HBUSOUT %01000000,[LEDFIN]
DELAYMS 20
PCFBTN=0
RETURN
END
-
De momento he avanzado algo... he realizado la misma prueba sin utilizar la interrupción y haciendolo por sondeo de los pulsadores y me funciona de maravilla con lo que el problema está a la hora de trabajar con la interrupción. Voy a seguir con ello pero si a alguien se le ocurre algo bien venido sea. :)
-
Que tal amigo!
Mira yo hice un programa hace tiempo con el pcf8574 pero con el pic16f876A pero es facilmente configurable para el tuyo :mrgreen:
Y utilice interrupcion por el portb.0 utilizando el hardware interrupt :shock:
Lo puedes utilizar como una guia, a ver si te sirve simulado y todo :-/
Saludos
-
Gracias RALF2 por tu ayuda pero tras revisarlo me encuentro con un problema, necesito hacerlo con el PROTON+ y este no entiende la instrucción I2CIN. He probado a sustituirlo por HBUSIN pero me sigue dando el mismo problema. ¿Alguna idea?
Otra cosa es que lo necesito usar con pulsadores con lo que cada vez que se pulsa genera dos pasos por la interrupción ¿como lo puedo evitar en PROTON+?
Gracias de nuevo.
-
Que tal guancho2002!
Mira el programa que te pase esta hecho en proton con la ultima version 3.3.4.8 :mrgreen:
Y soporta el i2cin, asi que no deberias tener problemas con eso otra opcion pudiese ser que utilices el busin, si operas con el hbusin tienes que manejar algunos registros del pic, ya que, el proton si bien te ayuda no lo hace todo leete la ayuda del manual alli lo explican :mrgreen:
Sino vuelve por aqui a ver que le podemos hacer.
La configuracion de los fuses que coloque, no son soportadas, por versiones anteriores del proton eso te puede dar problemas :shock:
Lo de los pulsadores o interruptores (en mi caso) no es problema solo deberias añadir un pequeño retardo en la rutina de interrupcion, por lo del rebote del contacto :mrgreen:
Otro detalle es que yo utilice interrupciones por hardware que la trae solo la ultima version del compilador optimizada y tu utilizas interrupciones por software, eso tambien te podria dar problemas al compilar :?
Saludos
-
Hola RALF2, me está sirviendo de mucho tu ayuda, gracias por tu tiempo. Te comento, la versión que comentas no la tengo :( con lo que me tengo que conformar con la 2.1.3. He probado a utilizarlo a través de BUSIN "por software" en vez de HBUSIN y parece que funciona bien, digo parece porque lo tengo montado en una protoboard y creo que hay malos contactos y de vez en cuando cuando pulso uno de los botones me enciende un led que no toca, con lo que tienes razón en cuanto a utilizar registros que no estoy utilizando. ¿me puedes ayudar con ellos? estoy revisando el manual pero no me llego a hacer con ellos. Te lo comento porque es una lástima no poder usarlo por hardware cuando el micro lo permite.
En cuanto a los pulsadores tenías razón, tan simple como poner un pequeño retardo... :)
Y por último no sé a que te refieres a que uso la interrupción por software, ¿que tengo configurado para que así sea? pensaba que me estaba trabajando por hardware... para volverse loco. :?
-
Que tal guancho2002!
Tienes razon estas utilizando la interupcion por hardware :D no me habia dado cuenta!
Dame algo de tiempo a ver en que te puedo ayudar :mrgreen:
Podrias postear el esquematico, para que asi me quede claro como va todo conectado?
Saludos
-
Me dejas más tranquilo, jeje. te lo adjunto. He probado con HBUSIN y me funciona sin problemas tanto HBUSIN como HBUSOUT pero siempre un cuando no pase por la rutina de la interrupción, es decir, si la lectura la hago cuando se produce la interrupción ya empieza a funcionar mal. Creo que hay algún registro que se me está pasando o algún problema de temporización...
Gracias.
-
Que tal guancho2002!
Mira veo una serie de cosas que te podrian dar problemas con la version del proton que posees :shock:
primero al momento de entrar a la interrupcion no hace falta colocar gie = 0 y intoie = 0, el pic al entrar en la rutina de servicio a la interrupcion automaticamente coloca el gie = 0, deshabilitando de esta forma todas las interrupociones que pudiesen ocurrir, lo otro al final debes colocar context restore, eso no lo veo, sino debes utilizar retifie 1 (retfie fast) si quieres restaurar el registro W, status Y BSR :mrgreen:
Lo otro veo que estas transmitiendo datos cuando no estas en la interrupcion, eso no deberias hacerlo porque si se genera una interrupcion a la mitad de un envio, se frego el programa :D
Yo te recomendaria que cambiaras de estrategia, y procedas de forma similar a como yo hice :mrgreen:
Simplemente te quedas a la espera a que ocurra una interrupcion, en mi caso puse a parpadear un led.
Luego cuando se presione algun pulsador, el pic salta a la rutina de interrupcion y alli lee el pcf8574 al cual estan conectados los pulsadores y de acuerdo a lo que quieras hacer activas los led.
De esta forma la rutina de lectura y escritura del los pcf8574, no se veria interrumpida :-/
Saludos
-
Efectivamente no hace falta el forzar el GIE ni al inicio ni al final ya que lo restaura el CONTEXT RESTORE pero es que ya he probado de todo y tengo basura por todas partes. Te comento, he realizado todos los cambios que me indicas y la verdad es que sigue sin funcionar, el problema es que en PROTEUS te lo simula de una manera y en la realidad de otra. Tras ir despejando errores del programa he llegado a un problema absurdo hasta este momento pero que ya no me deja avanzar... no me retorna la interrupción :shock: ¿que estás ocurriendo? he despejado todo lo posible en el programa pero no le veo el problema y claro, si no consigo que funcione bien la interrupción pues como para hacer funcionar el I2C... el programa es muy simple, lo único que hace es parpadear un LED mientras está fuera de la interrupción y cuando entras en la interrupción se hace un TOGGLE en otro led y luego debería de volver a la intermitencia del LED inicial, pero no lo hace...
DEVICE=18F452
XTAL=20
@CONFIG_REQ
@__CONFIG CONFIG1H, OSCS_OFF_1 & HS_OSC_1
@__CONFIG CONFIG2L, PWRT_ON_2
@__CONFIG CONFIG2H, WDT_OFF_2 & WDTPS_128_2
@__CONFIG CONFIG4L, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
TRISB = %00000001
SYMBOL GIE = INTCON.7 'Habilitar las interrupciones
SYMBOL INT0IE = INTCON.4
SYMBOL INT0IF = INTCON.1
SYMBOL INTEDG0=INTCON2.6
SYMBOL RBPU=INTCON2.7
INTEDG0=0
RBPU=1 '1 deshabilita la resistencia interna para la interrupción
ON_INTERRUPT GoTo Interrupcion
GoTo Inicio
Interrupcion:
DELAYMS 20
TOGGLE PORTD.0
INT0IF=0
CONTEXT RESTORE
Inicio:
INT0IE=1
GIE = 1
Bucle:
DELAYMS 20
TOGGLE PORTD.1
GOTO Bucle
END
-
Que tal guancho2002!
Mira voy a compilar el ultimo programa que hiciste y lo pruebo en proteus a ver si es el programa o es la version de tu compilador :shock:
Y te aviso luego!
Saludos
-
Como lo llevas? yo sigo sin avanzar por más que leo el datasheet... :(
A estas alturas y con un problema básico de este tipo... para volverse loco.
-
Bueno, de momento ya he avanzado, si en vez de poner "DELAYMS 20" en el buble de interrupción, ponemos "DELAYUS 20000" ya funciona sin problemas... :shock:
Esto acabará conmigo y mi ingreso en un psiquiátrico está garantizado.
Ahora podré continuar investigando lo del I2C pero casi seguro que por aquí estaban algunos de los problemas que tenía.
Gracias a todos por vuestra ayuda y en especial a RALF2 por tu interes constante.
Un saludo.
-
Que tal guancho2002!
El problema seguro esta en el compilador :shock:
No me queda duda :mrgreen:
Saludos
-
Pués si, era el compilador... bueno, ya está todo solucionado.
Una duda que me queda de estos circuitos es la siguiente: si hubiesen 3 o 4 PCF8574 y todos se conectasen a la int0, en el caso de pulsar algún botón y este circuito generase la interrupción, ¿hay alguna manera de saber cual fué el PCF8574 sin necesidad de ir comprobando uno por uno? lo digo porque llegados el caso en el que hubiesen unos cuantos habría un retardo considerable cuando se intentase comprobar cual fué. Está claro que podemos utilizar otras interrupciones pero como en su datasheet indica la posibilidad de conectarlos todos a la misma interrupción... no sé, ¿hay algún modo?
Gracias...
-
Que tal guacho2002!
Mira la interrupcion se activa, solo cuando se produce un cambio en algunas de las entradas del pcf8574, cuando esta programado en modo entrada y como se usa por lo general como un espansor de puertos al momento de generarse una interrupcion, deberias leer todas pcf programados como entradas.
Ya que no hay manera de saber cual fue el pcf8574 que genero la interrupcion sino es leyendolos todos :mrgreen:
Saludos
-
Me lo temia... gracias RALF2 :)