TODOPIC
Simuladores, editores de PCB, etc => Simuladores de circuitos => Proteus ISIS => Mensaje iniciado por: peterpan1000 en 19 de Agosto de 2005, 09:24:00
-
Estoy intentando simular un 16f876 conetado a una memoria 24lc6d a traves del un bus I2C, el caso es que consigo escribir correctamente en la memoria pero no leerla. Cuando intento leer varias direcciones consecutivas solo accedo correctamente a la primera mientras que para el resto de las posiciones la memoria me devuelve 0xFF.
Utilizo las funcinalidades que incorpora el PIC para el tratamiento del bus I2C. No se si es problema mio o de Proteus porque tambien me baje un programa de la pagina de microchip que realiza estas operaciones y tiene el mismo problema. Si alguien conoce si hay algun problema o si consigue simular correctamente agradeceria su ayuda.
Un saludo y gracias.
-
¿Y si pegas el código?
-
Hay va el codigo de la pagina de microchip (con unas peque�as modificaciones) y el archivo proteus. Con este codigo solo consigo escribir en la memoria y leer un solo byte. En el modo de lectura secuencial no devuelve ningun dato correcto. Cuando ponga un poco mas presentable mi codigo lo colocare tambien.
Voy a pegar aqui el codigo porque no me deja subirlo
********************************************************************
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Software License Agreement
;
; The software supplied herewith by Microchip Technology Incorporated
; (the "Company"
for its PICmicro® Microcontroller is intended and
; supplied to you, the Company’s customer, for use solely and
; exclusively on Microchip PICmicro Microcontroller products.
;
; The software is owned by the Company and/or its supplier, and is
; protected under applicable copyright laws. All rights are reserved.
; Any use in violation of the foregoing restrictions may subject the
; user to criminal sanctions under applicable laws, as well as to
; civil liability for the breach of the terms and conditions of this
; license.
;
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
; WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
; TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
; PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
; IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Filename: AN976.asm
; Date: February 1, 2005
; File Version: 1.0
; Assembled using: MPLAB IDE 7.00.00.0
;
; Author: Chris Parris
; Company: Microchip Technology, Inc.
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Files required: p16f877a.inc
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Purpose:
;
; This application note is intended to serve as a reference for
; communicating with Microchip’s I2C serial EEPROM devices with the
; use of the PICmicro MSSP module.
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Program Description:
;
; This program illustrates the following I2C operations:
; - Byte Write
; - Byte Read
; - Page Write
; - Sequential Read
; For the byte operations, 1 data byte is read from/written to
; the 24LC256 device. For the page write and sequential read, 16
; data bytes are transferred. All operations start at address 0x5AA5.
; All timings are set to meet the 100 kHz spec, and assume a 10 MHz
; crystal oscillator is used. If a different crystal frequency is
; desired, the value of SSPADD (currently 0x18) must be updated in
; Init. Also, note that no action is taken if the device does not
; respond with an ACK bit when one is expected.
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LIST P=16F876
; Port C pin descriptions
; SCL bit = 3
; SDA bit = 4
;
; 10MHz crystal is being used, thus each instruction cycle = 400 ns
;
;*******************RAM register definitions**********************
datai equ 20h ; Data input byte buffer
datao equ 21h ; Data output byte buffer
bytecount equ 22h ; Counter for byte loops
pollcnt equ 23h ; Counter for polling loops
loops equ 24h ; Delay loop counter
loops2 equ 25h ; Delay loop counter
BDel0 equ 0x29 ;Usada en retardos. Usada por subr "HacerTiempo"
BDel1 equ 0x2A ;Usada en retardos. Usada por subr "HacerTiempo"
BDel2 equ 0x2B ;Usada en retardos. Usada por subr "HacerTiempo"
Pausa equ 0x2C ;Pausa en centesima de sg. Usada por subr "HacerTiempo"
;*******************Macro definitions*****************************
WRITE_ADDR equ b"10100000" ; Control byte for write operations
READ_ADDR equ b"10100001" ; Control byte for read operations
;*******************Include file**********************************
include "p16f876.inc" ; Include file for a PIC16F877A
errorlevel -302 ; Suppress message 302 from list file
;*****************************************************************
org 0x000 ; Set the reset vector
goto start ; Go to the beginning of main
;*******************Begin Main Program****************************
start
call Init ; Initialize device
; call ByteWrite ; Byte Write operation
; call ByteRead ; Byte Read operation
call PageWrite ; Page Write operation
movlw d"40" ;Pausa de 10 centésimas de segundo para que en...
movwf Pausa ;...el arranque de tiempo a los slaves a quedar...
call HacerTiempo ;..configurados adecuadamente.
call SequentialRead ; Sequential Read operation
nop
goto $-1 ; Loop here forever
;---------------------------------------------------------------------------------------
HacerTiempo ;realiza una pausa del numero de centesimas de segundo especificadas en "Pausa"
;---------------------------------------------------------------------------------------
movf Pausa,W ;Coloca el valor de pausa en BDel2...
movwf BDel2 ;...para no alterar su contenido
;............................................................
; Generado con PDEL ver SP r 1.0 el 24/02/03 Hs 18:31:22
; Descripcion: Delay 10000 ciclos (1 centésima de segundo)
;............................................................
BCiclo movlw .8 ; 1 set numero de repeticion (B)
movwf BDel0 ; 1 |
BLoop1 movlw .249 ; 1 set numero de repeticion (A)
movwf BDel1 ; 1 |
BLoop2 nop ; 1 nop
nop ; 1 ciclo delay
decfsz BDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto BLoop2 ; 2 no, loop
decfsz BDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto BLoop1 ; 2 no, loop
BDelL1 goto BDelL2 ; 2 ciclos delay
BDelL2 nop ; 1 ciclo delay
;............................................................
decfsz BDel2,F ;Repite tantas veces el ciclo de una decima de segundo...
goto BCiclo ;..como se lo indique ADel2
return ; 2+2 Fin.
;*******************Initialization subroutine*********************
; This routine initializes the MSSP module
; for I2C Master mode, with a 100 kHz clock.
;*****************************************************************
Init
bcf STATUS,RP1 ; Select Bank 01
bsf STATUS,RP0
movlw b"11111111"
movwf TRISC ; Set PORTC to all inputs
clrf SSPSTAT ; Disable SMBus inputs
bsf SSPSTAT,SMP ; Disable slew rate control
movlw 0x18 ; Load 0x18 into WREG
movwf SSPADD ; Setup 100 kHz I2C clock
clrf SSPCON2 ; Clear control bits
bcf STATUS,RP0 ; Select Bank 00
movlw b"00101000"
movwf SSPCON ; Enable SSP, select I2C Master mode
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bcf PIR2,BCLIF ; Clear Bit Collision flag
retlw 0
;*******************Start bit subroutine**************************
; This routine generates a Start condition
; (high-to-low transition of SDA while SCL
; is still high.
;*****************************************************************
BSTART
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,SEN ; Generate Start condition
bcf STATUS,RP0 ; Select Bank 00
bstart_wait
btfss PIR1,SSPIF ; Check if operation completed
goto bstart_wait ; If not, keep checking
retlw 0
;*******************Restart bit subroutine**************************
; This routine generates a Repeated Start
; condition (high-to-low transition of SDA
; while SCL is still high.
;*****************************************************************
BRESTART
; bcf STATUS,RP1
; bcf STATUS,RP0 ; Select Bank 00
; bcf PIR1,SSPIF ; Clear SSP interrupt flag
; bsf STATUS,RP0 ; Select Bank 01
; bsf SSPCON2,RSEN ; Generate Restart condition
; bcf STATUS,RP0 ; Select Bank 00
;brestart_wait
; btfss PIR1,SSPIF ; Check if operation completed
; goto brestart_wait ; If not, keep checking
;
; retlw 0
banksel PIR1
bcf PIR1,SSPIF ; Clear SSP interrupt flag
banksel SSPCON2
bsf SSPCON2,RSEN ; Activamos la generacion de RESTART
; call CheckIdle ; Espera fin de evento
S_RESTART
btfsc SSPCON2,RSEN ; Cuando se haya dado la condición de RESTART
; se pondrá a 0
goto S_RESTART ; Si no, seguimos esperando
banksel PIR1 ; Volvemos al banco 0
return
;*******************Stop bit subroutine***************************
; This routine generates a Stop condition
; (low-to-high transition of SDA while SCL
; is still high.
;*****************************************************************
BSTOP
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,PEN ; Generate Stop condition
bcf STATUS,RP0 ; Select Bank 00
bstop_wait
btfss PIR1,SSPIF ; Check if operation completed
goto bstop_wait ; If not, keep checking
retlw 0
;*******************Data transmit subroutine**********************
; This routine transmits the byte of data
; stored in "datao" to the serial EEPROM
; device. Instructions are also in place
; to check for an ACK bit, if desired.
; Just replace the "goto" instruction,
; or create an "ackfailed" label, to provide
; the functionality.
;*****************************************************************
TX
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
movf datao,W ; Copy datao to WREG
movwf SSPBUF ; Write byte out to device
tx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto tx_wait ; If not, keep checking
bsf STATUS,RP0 ; Select Bank 01
btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received
goto ackfailed ; This executes if no ACK received
retlw 0
ackfailed goto $
;*******************Data receive subroutine***********************
; This routine reads in one byte of data from
; the serial EEPROM device, and stores it in
; "datai". It then responds with either an
; ACK or a NO ACK bit, depending on the value
; of "ACKDT" in "SSPCON2".
;*****************************************************************
RX
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,RCEN ; Initiate reception of byte
bcf STATUS,RP0 ; Select Bank 00
rx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait ; If not, keep checking
movf SSPBUF,W ; Copy byte to WREG
movwf datai ; Copy WREG to datai
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKEN ; Generate ACK/NO ACK bit
bcf STATUS,RP0 ; Select Bank 00
rx_wait2
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait2 ; If not, keep checking
retlw 0
;*******************Byte write test subroutine********************
; This routine tests the byte write feature
; of the serial EEPROM device. It will write
; 1 byte of data to the device at address 0x5AA5.
;*****************************************************************
ByteWrite
call BSTART ; Generate Start condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR ; Load control byte for write
movwf datao ; Copy to datao for output
call TX ; Send control byte to device
; Send word address high byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0x5A ; Load 0x5A for word address
movwf datao ; Copy to datao for output
call TX
; Send word address low byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0xA5 ; Load 0xA5 for word address
movwf datao ; Copy to datao for output
call TX ; Send word address to device
; Send data byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0xAA ; Load 0xAA for data byte
movwf datao ; Copy to datao for output
call TX ; Send data byte to device
call BSTOP ; Generate Stop condition
retlw 0
;*******************Page write test subroutine********************
; This routine demonstrates the page write
; feature of the serial EEPROM device. It will
; write 16 bytes of data to the device starting
; at address 0x5AA5. Since this is a page write,
; all 16 bytes will be written to the device at
; the same time.
;*****************************************************************
PageWrite
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
movlw .16
movwf bytecount ; Initialize counter to 16 bytes
call BSTART ; Generate start bit
; Now we send the control byte
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
; Send word address high byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0x5A ; Use 0x5A for address to send
movwf datao ; Copy address to buffer
call TX
; Send word address low byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0xA5 ; Use 0xA5 for address to send
movwf datao ; Copy address to buffer
call TX ; Output address to device
bcf STATUS,RP0 ; Select Bank 00
txbyte ; This loop transfers all 16 of
; the data bytes to the device
movf bytecount,W ; Use bytecount as data value
movwf datao ; Copy data to buffer
call TX ; Output data to device
bcf STATUS,RP0 ; Select Bank 00
decfsz bytecount,F ; Check if finished looping
goto txbyte ; Continue looping
call BSTOP ; Generate stop bit
retlw 0
;*******************Byte read test subroutine*********************
; This routine tests the byte read feature
; of the serial EEPROM device. It will read
; 1 byte of data at address 0x5AA5 from the device.
;*****************************************************************
ByteRead
call BSTART ; Generate Start condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR ; Load control byte for write
movwf datao ; Copy to datao for output
call TX ; Send control byte to device
; Send word address high byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0x5A ; Load 0x5A for word address
movwf datao ; Copy to datao for output
call TX ; Send high byte to device
; Send word address low byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0xA5 ; Load 0xA5 for word address
movwf datao ; Copy to datao for output
call TX ; Send word address to device
call BRESTART ; Generate Restart condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw READ_ADDR ; Load control byte for read
movwf datao ; Copy to datao for output
call TX ; Send control byte to device
; Read data byte
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKDT ; Select to send NO ACK bit
call RX ; Read data byte from device
call BSTOP ; Generate Stop condition
retlw 0
;*******************Sequential read test subroutine***************
; This routine tests the sequential read feature
; of the serial EEPROM device. It will read 16
; bytes of data to the device starting at
; address 0x50, one byte after another.
;*****************************************************************
SequentialRead
bcf STATUS,RP0 ; Select Bank 00
movlw .16
movwf bytecount ; Initialize counter to 16 bytes
call BSTART ; Generate start bit
; Now send the control byte
; for a write, to set address
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
; Send word address high byte
bcf STATUS,RP0 ; Select Bank 00
clrf datao ; Load 0x00 into datao
call TX ; Send high byte to device
; Send word address low byte
bcf STATUS,RP0 ; Select Bank 00
movlw 0x50 ; Load 0x50 for word address
movwf datao ; Copy to datao for output
call TX ; Send word address to device
call BRESTART ; Generate another start bit
; to switch to read mode
bcf STATUS,RP0 ; Select Bank 00
movlw READ_ADDR
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
rxbyte
; Finally, read the data byte
bcf STATUS,RP0 ; Select Bank 00
decfsz bytecount,F ; Check if finished looping
goto continue ; If not finished, keep going
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKDT ; Otherwise, select to send NO ACK bit
call RX ; and input final byte from device
call BSTOP ; Generate stop bit
retlw 0
continue
bsf STATUS,RP0 ; Select Bank 01
bcf SSPCON2,ACKDT ; Select to send ACK bit
call RX ; Input data from device
goto rxbyte ; Continue looping
END