Bueno gente, les digo que solucione el tema cambiando el pic. Me dolio un poco el bolsillo pero lo solucione.
Bien ahora tengo otro problema, es con respecto al bus i2c, yo tengo dispuesto a el pic tal que el bus esta conectado al puerto E, en el bit 0 e 1.
Podría ver usado el del pic, pero me entere tarde que tenia uno, asi que lo que estoy haciendo ahora es un prog para hacer andar el bus. Anteriormente realice pruebas exitosas con el 16f84 a 4mhz, ahora tengo problemas con el 16f877 a 20mhz. Queria ver si alguien me puede ayudar a solucionar el problema. Les paso mi prog para que puedan ver y ayudarme un poco. El mismo solo lee cuando se habilita el bit de interrupción
ESPERO QUE ME PUEDAN AYUDAR, es un poco largo el código, pero agradecería de su ayuda. Disculpen los errores en el mismo
;******************************************************************* Autómata Programable***************************************************
list p=16f877A ; Defino el procesador
#include <p16f877A.inc> ; Adjunto librerias a utilizar del pic
__CONFIG _CP_OFF & _DEBUG_OFF & _PWRTE_ON & _LVP_OFF & _CPD_OFF & _BODEN_OFF & _WDT_OFF & _HS_OSC & _WRT_OFF
;************************************************************** Declaro de variables *******************************************************
CBLOCK 0x25
status_temp ;respaldo del registro de status cuando hay interrupcion
w_temp ;respaldo del registro de trabajo cuando hay interrupcion
Datosfirth ;Se almasenan los pits de la entrada en crudo
DatosIN1 ;Aqui se almasenan los bist de las entradas 0 a la 7
DatosIN2 ;Aqui se almasenan los bist de las entradas 8 a la 15
contadoretardo ;Aqui se almasena la cuenta del retardo de los 4 micros del bus
contadorretardo2 ;Aqui se almasena la cuenta del retardo de los 20ms del bus
contadorretardo3 ;Aqui se almasena la cuenta del retardo de los 20ms del bus
PCF8574_Dato ;Aquí guarda el resultado del dato leído o que se va a escribir.
I2C_ContadorBits ;Cuenta los bits a transmitir o a recibir.
I2C_Dato ;Dato a transmitir o recibido.
I2C_Flags ;Guarda la información del estado del bus I2C.
PCF8574_DireccionLectura ;Almasen de codigo del integrado cuando trabaja
ENDC
;******************************************************** Variables de puertos del pic en el programa **************************************
;____________________PUERTO E_______________________________________________¦
#DEFINE SCL PORTE,0 ;Línea SCL del bus I2C ¦
#DEFINE SDA PORTE,1 ;Línea SDA del bus I2C ¦
;___________________________________________________________________________¦
#DEFINE I2C_UltimoByteLeer I2C_Flags,0 ;último byte a leer por el maestro
;************************************************************ Zona de comienzo programa e interrupcion**************************************
ORG 0 ;DIRECCION NORMAL
clrf PCLATH ;Borro la bandera la interrupcion
goto principal ;Me voy a donde comienza el programa normalmente
ORG 4 ;DIRECCION INTERRUPCION
goto interrupcion ;Me voy a hacer la interrupcion
;************************************************************ Interrupcion *****************************************************************
interrupcion
movwf w_temp ;pongo en la variable lo que habia en trabajo
movf STATUS,W ;Muevo el registro status a w
movwf status_temp ;Mando la configuracion de status a mi variable
clrf STATUS ;ME ASEGURO QUE ESTOY EN EL BANCO 0
bcf INTCON, GIE ;desabilito cualquier otra interrupcion que pueda ocurrir
btfsc INTCON, INTF ;FLAG INTERRUPCION Se genero una interrupcion?
;---------------IR PROGRAMA INTERRUPCION-----
goto generoint ;si se va a atender la interrupcion
;--------------------------------------------
goto restaurar
restaurar ;parte para salir de la interrupcion y dejar todo como estaba
movf status_temp,w ;recupero los registros ante de la interrupcion
movwf STATUS ;y los dejo como estuban antes de la misma
swapf w_temp,f
swapf w_temp,w
bcf INTCON,INTF ;Limpia las interrupciones pendientes
bsf INTCON,GIE ;habilito las interrupciones
retfie
;************************************************************ Configuracion puertos del pic*************************************************
principal
clrf STATUS
bsf STATUS,RP0 ;Acceso al banco 1
movlw b'00000110'
movwf ADCON1 ;Desavilito las salidas analogicas
movlw b'111111' ;Configuro todo como entrada PUERTO A
movwf TRISA
movlw b'00000001' ;Configuro todo como salida menos el ultimo bit de interrupcion
movwf TRISB
movlw b'00000000' ;Configuro todo como salida el PUERTO B
movwf TRISC
movlw b'00000000' ;Configuro todo como salida el PUERtO C
movwf TRISD
bcf TRISE,2
bsf INTCON, INTE ;Habilito las interrupciones del puerto B0
bcf OPTION_REG, INTEDG ;La interrupcion se abilita por flanco de bajada
bsf INTCON,GIE ;habilito las interrupciones
bcf STATUS,RP0 ;Acceso al banco 0
;************************************************************ Programa principal***********************************************************
;Programa principal:
clrf PORTB
stard
movf DatosIN1, W
movwf PORTC
movf DatosIN2, W
movwf PORTD
goto stard
;*******************INTERRUPCION*************************************************INTERRUPCION**********************************************
generoint ;Programa para atender la interrupcion
;primera lectura
movf b'01000011',W ;paso a trabajo la direccion del primer integrado
movwf PCF8574_DireccionLectura;paso la direccion a esta variable para poder leer este integrado
call Retardo_10ms ;Retardo para asegurarnos que no fue un rebote
call PCF8574_Lee ;leo la info que hay en el bus del primer micro
movwf DatosIN1 ;almaseno probisoriamente los datos recibidos aca
;segunda lectura
movf b'01000001',W ;paso a trabajo la direccion del segundo integrado
movwf PCF8574_DireccionLectura;paso la direccion a esta variable para poder leer este integrado
call PCF8574_Lee ;leo la info que hay en el bus del primer micro
movwf DatosIN2 ;almaseno probisoriamente los datos recibidos aca
goto restaurar
;___SUBRUTINA PARA LA COMUNICACION PCF8574____________________________________________________________
PCF8574_Lee ; Para leer la info del micro
call I2C_EnviaStart ; Envía la condición de Start.
movlw PCF8574_DireccionLectura; Apunta al expansor de lectura.
call I2C_EnviaByte
bsf I2C_UltimoByteLeer
call I2C_LeeByte ; Lee el puerto.
movwf PCF8574_Dato ; Lo guarda en el registro correspondiente.
call I2C_EnviaStop ; Acaba de leer.
movf PCF8574_Dato,W ; Recupera el valor del dato leído.
return
;___SUBRUTINA PARA LA COMUNICACION del BUS I2C_________________________________________________________
SDA_Bajo ; Subrutina "SDA_Bajo"
bsf STATUS,RP0 ; Configura la línea SDA como salida.
bcf SDA
bcf STATUS,RP0
bcf SDA ; SDA en bajo.
return
SDA_AltaImpedancia ; Subrutina "SDA_AltaImpedancia"
bsf STATUS,RP0 ; Configura la línea SDA entrada.
bsf SDA ; Lo pone en alta impedancia y, gracias a la
bcf STATUS,RP0 ; Rp de esta línea, se mantiene a nivel alto.
return
SCL_Bajo ; Subrutina "SCL_Bajo"
bsf STATUS,RP0
bcf SCL ; Configura la línea SCL como salida.
bcf STATUS,RP0
bcf SCL ; La línea de reloj SCL en bajo.
return
SCL_AltaImpedancia ; Subrutina "SCL_AltaImpedancia"
bsf STATUS,RP0 ; Configura la línea SCL entrada.
bsf SCL ; Lo pone en alta impedancia y, gracias a la Rp
bcf STATUS,RP0 ; de esta línea, se mantiene a nivel alto.
SCL_EsperaNivelAlto
btfss SCL ; Si algún esclavo mantiene esta línea en bajo
goto SCL_EsperaNivelAlto ; hay que esperar.
return
; Subrutina "I2C_EnviaStart" ------------------------------------------------------------
I2C_EnviaStart
call SDA_AltaImpedancia ; Línea SDA en alto.
call SCL_AltaImpedancia ; Línea SCL en alto.
call Retardo_4micros ; Tiempo tBUF del protocolo.
call SDA_Bajo ; Flanco de bajada de SDA mientras SCL está alto.
call Retardo_4micros ; Tiempo tHD;STA del protocolo.
call SCL_Bajo ; Flanco de bajada del reloj SCL.
call Retardo_4micros
return
; Subrutina "I2C_EnviaStop" -------------------------------------------------------------
I2C_EnviaStop
call SDA_Bajo
call SCL_AltaImpedancia ; Flanco de subida de SCL.
call Retardo_4micros ; Tiempo tSU;STO del protocolo.
call SDA_AltaImpedancia ; Flanco de subida de SDA.
call Retardo_4micros ; Tiempo tBUF del protocolo.
return
; Subrutina "I2C_EnviaByte" -------------------------------------------------------------
I2C_EnviaByte
movwf I2C_Dato ; Almacena el byte a transmitir.
movlw 0x08 ; A transmitir 8 bits.
movwf I2C_ContadorBits
I2C_EnviaBit
rlf I2C_Dato,F ; Chequea el bit, llevándolo previamente al Carry.
btfsc STATUS,C
goto I2C_EnviaUno
I2C_EnviaCero
call SDA_Bajo ; Si es "0" envía un nivel bajo.
goto I2C_FlancoSCL
I2C_EnviaUno
call SDA_AltaImpedancia ; Si es "1" lo activará a alto.
I2C_FlancoSCL
call SCL_AltaImpedancia ; Flanco de subida del SCL.
call Retardo_4micros ; Tiempo tHIGH del protocolo.
call SCL_Bajo ; Termina el semiperiodo positivo del reloj.
call Retardo_4micros ; Tiempo tHD;DAT del protocolo.
decfsz I2C_ContadorBits,F ; Lazo para los ocho bits.
goto I2C_EnviaBit
call SDA_AltaImpedancia ; Libera la línea de datos.
call SCL_AltaImpedancia ; Pulso en alto de reloj para que el esclavo
call Retardo_4micros ; pueda enviar el bit ACK.
call SCL_Bajo
call Retardo_4micros
return
; Subrutina "I2C_LeeByte" ---------------------------------------------------------------
I2C_LeeByte
movlw 0x08 ; A recibir 8 bits.
movwf I2C_ContadorBits
call SDA_AltaImpedancia ; Deja libre la línea de datos.
I2C_LeeBit
call SCL_AltaImpedancia ; Flanco de subida del reloj.
bcf STATUS,C ; En principio supone que es "0".
btfsc SDA ; Lee el bit
bsf STATUS,C ; Si es "1" carga 1 en el Carry.
rlf I2C_Dato,F ; Lo introduce en el registro.
call SCL_Bajo ; Termina el semiperiodo positivo del reloj.
call Retardo_4micros ; Tiempo tHD;DAT del protocolo.
decfsz I2C_ContadorBits,F ; Lazo para los 8 bits.
goto I2C_LeeBit
btfss I2C_UltimoByteLeer ; Si es el último, no debe enviar el bit de reconocimiento ACK.
call SDA_Bajo ; Envía el bit de reconocimiento ACK porque todavía no es el último byte a leer.
call SCL_AltaImpedancia ; Pulso en alto del SCL para transmitir el
call Retardo_4micros ; bit ACK de reconocimiento. Este es tHIGH.
call SCL_Bajo ; Pulso de bajada del SCL.
call Retardo_4micros
movf I2C_Dato,W ; El resultado se manda en el registro de
return ; de trabajo W.
;___Retardos___________________________________________________________________________________________
;Retardo de 4micros para la comunicacion del bus
Retardo_4micros
movlw .0 ; 1 set numero de repeticion 230
movwf contadoretardo ; 1
Hegaint
decfsz contadoretardo , 1 ; es el tiempo 0 ?
goto Hegaint
return ; 2+2 Fin.
;Retardo de 10 milisegundo para asegurarnos que no fue un rebote
Retardo_10ms
movlw .99 ; 1 set numero de repeticion (B)
movwf contadorretardo2 ; 1 |
AAA movlw .100 ; 1 set numero de repeticion (A)
movwf contadorretardo3 ; 1 |
BBB decfsz contadorretardo3, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto BBB ; 2 no, loop
decfsz contadorretardo2, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto AAA ; 2 no, loop
return
;-----------------------FIN_____________________________________________
END