Programación Específica > Microcontroladores
16f84 Y Eeprom 24c08!..
Huguen_aus_Tirol:
Hola! No sabía que era tan urgente! Bueno, mañana es feriado (se me había pasado), asi que me hago un tiempito para dejarte algo de código para los MCU que tienen el modulo MSSP.
--- Código: Text --- ;******************************************************************************; PLACA EXPERIMENTAL CON 16F873;; Autor: Hugo Rodolfo ERHARD; Fecha: 06/03/05;;****************************************************************************** include "p16f873.h" errorlevel -215, -302 __CONFIG 0x3D31;M24C02 equ b'10100000'; ; CBLOCK 0x22; VARIABLES DE USO GENERAL CNT ; contador general CNT1 ; contador general COUNT ; COUNT01 ; TMP ; temporal general PTR ; puntero general REG0 REG1 REG2 count tmp_h tmp_l temp I2C_cmd I2C_adr I2C_dat I2C_aux; _070lim; ENDC;#DEFINE STR PORTA,1 ; #DEFINE DAT PORTA,2 ; #DEFINE CLK PORTA,3 ; #DEFINE LED PORTA,4 ; #DEFINE PS PORTA,5 ; ;#DEFINE RSDIS PORTB,1 ; #DEFINE EDIS PORTB,3 ; ;#DEFINE SCL PORTC,4 ; #DEFINE SDA PORTC,3 ; #DEFINE COMEN PORTC,5 ; ;#DEFINE I2CDO I2CSTAT,6; #DEFINE I2CDI I2CSTAT,7; #DEFINE I2CACKF I2CSTAT,5; ;;;******************************************************************************; ORG 0_POR goto MAIN ; ; ORG 4_ISR movwf SAVE_W ; salvo W durante la interrupcion swapf STATUS,W; cargo STATUS en W invirtiendo nibbles movwf SAVE_S ; y salvo clrf STATUS ; para asegurar que este en banco 0;; btfsc TMR1IF ; timer 1;; goto TMR1_ISR; ;; btfsc RCIF ; USART Rx;; goto RX485_ISR; _NOISR swapf SAVE_S,W; recupero STATUS invirtiendo nibbles movwf STATUS ; swapf SAVE_W,F; recupero W de esta manera para no afectar swapf SAVE_W,W; los bits de STATUS retfie ; ;;;*****************************************************************************;; SUBRUTINAS VARIAS ;;*****************************************************************************;;I2C_IDLE bsf RP0 btfsc SSPRW goto $-1 movfw SSPCON2 andlw 0x1F btfss Z goto $-3 bcf RP0 return;;I2C_START bsf RP0 bsf SEN btfsc SEN goto $-1 bcf RP0 return ;;I2C_WRITE movwf SSPBUF bsf RP0 btfsc SSPRW goto $-1 btfsc ACKSTAT goto $-1 bcf RP0 return;;I2C_READ bsf RP0 bsf RCEN btfsc RCEN goto $-1 bcf RP0 movfw SSPBUF return;;I2C_RESTART bsf RP0 bsf RSEN btfsc RSEN goto $-1 bcf RP0 return;;I2C_NOACK bsf RP0 bsf ACKDAT bsf ACKEN btfsc ACKEN goto $-1 bcf RP0 return;;I2C_STOP bsf RP0 bsf PEN btfsc PEN goto $-1 bcf RP0 return;;RD24C02 call I2C_IDLE call I2C_START; movfw I2C_cmd call I2C_WRITE; movfw I2C_adr call I2C_WRITE; call I2C_RESTART; movfw I2C_cmd iorlw 0x01 call I2C_WRITE call I2C_READ movwf I2C_dat; call I2C_NOACK call I2C_STOP return;;*******************************************************************;;MAIN bsf RP0 ; banco 1 movlw b'00000001' ; puerto A movwf TRISA ; movlw b'00000000' ; puerto B movwf TRISB ; movlw b'10011001' ; puerto C movwf TRISC ; bcf RP0 ; banco 0 clrf PORTA ; todas las salidas en 0 clrf PORTB ; clrf PORTC ; clrf HOR ; clrf MIN ; clrf SEG ; ;; Configuro MSSP como i2c maestro; bsf RP0 ; movlw 0x09 ; velocidad 400 KHz movwf SSPADD ; movlw b'10000000' ; slew rate speed control enabled, niveles segun i2c movwf SSPSTAT ; movlw b'00000000' ; movwf SSPCON2 ; bcf RP0 ; movlw b'00111000' ; i2c habilitado, modo maestro movwf SSPCON ; clrf PIR1 clrf PIR2; bsf RP0 ; movlw b'00100001' ; int timer 1 movwf PIE1 ; bcf RP0 movlw b'11000000' ; movwf INTCON ; ; movlw 0xFF movwf I2C_aux clrf I2C_adr clrf I2C_dat;MAIN_LOOPWAIT1i2c_wr movlw M24C02 movwf I2C_cmd movlw .20 movwf I2C_aux clrf I2C_adr clrf I2C_datI2C_RLOOP call WR_OUT movlw M24C02 movwf I2C_cmd call RD24C02; movlw .1 movwf DSEGWAIT1i2c tstf DSEG bnz WAIT1i2c; incf I2C_adr,f decfsz I2C_aux,f goto I2C_RLOOP; movlw .1 movwf DSEGWAIT1S tstf DSEG bnz WAIT1S goto MAIN_LOOP; end
Quite algunas partes del programa, para que no se vea más complicado. Pero las rutinas y configuración de lo que es I2C está tal como lo usé.
Perdón por la falta de comentarios.
Con este código puedes leer una 24Cxx. Te aconsejo tener a mano la hoja de datos de los modulos MSSP.
Bueno, espero te sirva. Cualquier problema, aqui estoy!
Saludos
andre52:
HOLA...MUCHISIMAS GRACIAS POR TU CODIGO, PUEDE GUIARME UN POCO, AUNQUE NO SE PORQUE TODAVIA NO ME FUNCIONA..TENGO UN PROBLEMA AL LEER LA BANDERA DEL PIR1, SSPIF, NUNCA ME PASA DE AHI...TE AGRADEDERIA MUCHO QUE ME AYUDARAS
********************************************************************
BANCO1
CLRF TRISB ; PURTO B COMO SALIDA
movlw b'00010000'
MOVWF TRISC ; PUERTO C, ENTRADA
;MOVLW B'11001111'
;MOVWF OPTION_REG
BSF SSPSTAT,SMP ;EL DATO DE ENTRADA ES LEIDO AL FINAL DEL DATO DE SALIDA
MOVLW .9
MOVWF SSPADD ; VELOCIDAD DE 100KHZ
BANCO0
;CONFIGURACION DE MMSP
MOVLW B'00101000'
MOVWF SSPCON
CLRF PIR1
CALL WRITE
CALL READ
MOVWF PORTD
GOTO main
START
BANCO1
BSF SSPCON2,SEN ; CONDICION DE INICIO EN LOS PINES SDA Y SCL
BTFSC SSPCON2,SEN
GOTO $-1
BANCO0
CALL ESPERAR
RETURN
START2
BANCO1
BSF SSPCON2,RSEN ; CONDICION DE INICIO EN LOS PINES SDA Y SC
BANCO0
CALL ESPERAR
RETURN
SEND
BCF PIR1,SSPIF ;FLAG MSSP
MOVWF SSPBUF ; BUFFER DE SALIDA
CALL ACKX
CALL ESPERAR
RETURN
WRITE
CALL START
MOVLW B'10100000' ;DIRECCION DISPOSITIVO
CALL SEND
MOVLW B'00000000' ;DIRECCION DE LA MEMORIA
CALL SEND
MOVLW .90 ;DATO
MOVWF SSPBUF
CALL ACKX
CALL ESPERAR
CALL STOP
RETURN
ACKX
BANCO1
BTFSC SSPCON2, ACKSTAT ;TRANSMISION HA OCURRIDO
GOTO ACKX
BANCO0
RETURN
;BANCO1
;BSF SSPCON2,ACKEN ;ACTIVA GENERACION DE ACK
READ
CALL START
MOVLW B'10100000' ;DIRECCION DISPOSITIVO
CALL SEND
MOVLW B'00000000' ;DIRECCION DE LA MEMORIA
CALL SEND
CALL START2
MOVLW B'10100001' ;DIRECCION DISPOSITIVO
CALL SEND
BANCO1
BSF SSPCON2,RCEN
BANCO0
CALL ESPERAR
CALL NACK
CALL LEE_BYTE
CALL ESPERAR
MOVF SSPBUF,W
MOVWF PORTB
CALL STOP
RETURN
NACK
BANCO1
BSF SSPCON2,ACKDT ;PONE BIT ACK A 0
BSF SSPCON2,ACKEN ;ACTIVA GENERACION DE ACK
BTFSC SSPCON2,ACKEN
GOTO $-1
BANCO0
RETURN
STOP
BANCO1
BSF SSPCON2,PEN ;ACTIVA SECUENCIA DE PARADA
BTFSC SSPCON2,PEN
GOTO $-1
BANCO0
CALL ESPERAR
RETURN
ESPERAR
BCF PIR1,SSPIF
BTFSS PIR1,SSPIF ;TRANSMISION O RECEPCION HA OCURRIDO
GOTO $-1
RETURN
LEE_BYTE
BCF PIR1,SSPIF
BANCO1
BSF SSPCON2,RCEN
BTFSC SSPCON2,RCEN
GOTO $-1
BANCO0
RETURN
END
Huguen_aus_Tirol:
Hola Andre52! Fijate que en el código que te pasé no utilizo la bandera de interrupción; recuerdo que traté de hacerlo con SSPIF, pero me dio problemas. Luego me funcionó sin utilizar este flag.
No te olvides de conectar una R de 10 K entre SDA y VCC, y otra entre SCL y VCC.
Bueno, más tarde me fijo más detenidamente tu código y vemos que pasa...
Saludos :hola:
Navegación
[*] Página Anterior
Ir a la versión completa