Hola que tal companeros
Me gustaria saber su opinion sobre este programa.
ya lo leei lo entendi y lo simule, el problema que veo es que, escribe correctamente pero lee basura y caracteres incorrectos.
agradeceria de su ayuda.
Me gustaria saber su opinion sobre este programa.
ya lo leei lo entendi y lo simule, el problema que veo es que, escribe correctamente pero lee basura y caracteres incorrectos.
agradeceria de su ayuda.
Código:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; 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=16F877A
; 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
;*******************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 "p16f877a.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
call SequentialRead ; Sequential Read operation
nop
goto $-1 ; Loop here forever
;*******************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
;*******************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
;*******************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
call Poll ; Poll for write completion
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
call Poll ; Poll for write completion
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
;*******************Acknowledge Polling subroutine****************
; This subroutine polls the EEPROM device
; for an ACK bit, which indicates that the
; internal write cycle has completed. Code
; is in place for a timeout routine, just
; uncomment the 'goto TimedOut' line, and
; provide a 'TimedOut' label.
;*****************************************************************
Poll
bcf STATUS,RP0 ; Select Bank 00
movlw .40
movwf pollcnt ; Set max polling times to 40
polling
call BRESTART ; Generate start bit
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR ; Now send the control byte
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
bsf STATUS,RP0 ; Select Bank 01
btfss SSPCON2,ACKSTAT ; Was the ACK bit low?
goto exitpoll ; If yes, stop polling
; If no, check if polled 40 times
bcf STATUS,RP0 ; Select Bank 00
decfsz pollcnt,F ; Is poll counter down to zero?
goto polling ; If no, poll again
; goto TimedOut ; If yes, part didn't respond
; in time, so take action
exitpoll
call BSTOP ; Generate stop bit
retlw 0
END