; DEFINICE KONSTANT ; ------------------------------------------------------------- ; Porty pro EEPROM 24C64 #DEFINE SCL PORTA,7 #DEFINE SDA PORTA,6 #DEFINE SCLDIR TRISA,7 #DEFINE SDADIR TRISA,6 EADR EQU H'043' ; Adresa v EEPROM při čtení EVAL EQU H'044' EBYTE EQU H'049' rot EQU H'051' ; Rotace bytu ack EQU H'052' ; PODPROGRAM eeprom_read ; Přečte EEPROM na zadané adrese a hodnotu uloží do registru EVAL ; ; Vstupní registry: ; EADR - adresa ; ; Výstupní registry: ; EVAL - hodnota ; ; ------------------------------------------------------------- @eeprom_read CALL @i2c_start ; Device Address MOVLW B'10100000' CALL @i2c_write ; First Word Address MOVLW H'00' CALL @i2c_write ; Second Word Address MOVF EADR,W CALL @i2c_write CALL @i2c_start ; Device Address MOVLW B'10100001' CALL @i2c_write CALL @i2c_read MOVF EBYTE,W MOVWF EVAL CALL @i2c_stop RETURN ; ------------------------------------------------------------- ; PODPROGRAM eeprom_write ; ------------------------------------------------------------- @eeprom_write CALL @i2c_start ; Device Address MOVLW B'10100000' CALL @i2c_write ; First Word Address MOVLW H'00' CALL @i2c_write ; Second Word Address MOVLW H'00' CALL @i2c_write ; Zápis dat do EEPROM MOVLW H'99' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'66' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'00' CALL @i2c_write MOVLW H'33' CALL @i2c_write CALL @i2c_stop RETURN ; ------------------------------------------------------------- ; I2C ; ; ------------------------------------------------------------- @i2c_read MOVLW 8 MOVWF rot ; Počet rotací BSF STATUS,RP0 BSF SDADIR ; SDA vstup BCF STATUS,RP0 i2c_read_rot CALL @delay_10us ; Pauza cca 10us BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BCF STATUS,C ; Vynulujeme C BTFSC SDA ; Otestujeme SDA BSF STATUS,C ; Pokud SDA == 1, nastavíme C CALL @delay_10us ; Pauza cca 10us BCF SCL ; SCL = 0 RLF EBYTE,1 ; Rotace EBYTE přes C doleva DECFSZ rot,1 GOTO i2c_read_rot ; Cyklus CALL @delay_10us ; Pauza cca 10us BCF SDA ; SDA = 0 BSF STATUS,RP0 BCF SDADIR ; SDA výstup BCF STATUS,RP0 RETURN @i2c_send_ack BCF SDA ; SDA = 0 CALL @delay_10us ; Pauza cca 10us BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BCF SCL ; SCL = 0 RETURN @i2c_write MOVWF EBYTE ; W do EBYTE MOVLW 8 MOVWF rot ; Počet rotací i2c_write_rot RLF EBYTE,1 ; Rotace EBYTE o 1 bit doleva přes C BTFSS STATUS,C ; Otestujeme C a nastavíme SDA GOTO $+3 BSF SDA ; SDA = 1 GOTO $+2 BCF SDA ; SDA = 0 CALL @delay_10us ; Pauza cca 10us BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BCF SCL ; SCL = 0; DECFSZ rot,1 GOTO i2c_write_rot ; Cyklus CALL @delay_10us ; Pauza cca 10us CALL @i2c_ack ; ACK RETURN @i2c_start BSF SDA ; SDA = 1 BSF STATUS,RP0 BCF SDADIR ; SDA výstup BCF STATUS,RP0 BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BCF SDA ; SDA = 0 CALL @delay_10us ; Pauza cca 10us BCF SCL ; SCL = 0 RETURN @i2c_stop CALL @delay_10us ; Pauza cca 10us BCF SDA ; SDA = 0 CALL @delay_10us ; Pauza cca 10us BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BSF SDA ; SDA = 1 BSF STATUS,RP0 BCF SDADIR ; SDA vstup BCF STATUS,RP0 RETURN @i2c_ack BSF STATUS,RP0 BSF SDADIR ; SDA vstup BCF STATUS,RP0 CALL @delay_10us ; Pauza cca 10us BSF SCL ; SCL = 1 CALL @delay_10us ; Pauza cca 10us BTFSC SDA GOTO $-1 CALL @delay_10us ; Pauza cca 10us BCF SCL ; SCL = 0 CALL @delay_10us ; Pauza cca 10us BCF SDA BSF STATUS,RP0 BCF SDADIR ; SDA výstup BCF STATUS,RP0 RETURN @delay_10us GOTO $+1 GOTO $+1 RETURN ; -------------------------------------------------------------