I2C-ga suhtlemine
#1
Õhtast!
Ma viimasel ajal muudkui küsin...
Samunegi et I2C PICi realisatsioonis näeb ette "clock strechingut" ehk peale aadressi saamist ja ACKi andmist võib neeger(slave) hoida CLk otsa madalana kuni andmed ette valmistatud. Aga.. kas ainult siis või on stretching lubatud ka järgnevate databaitide ajal? Mulle tundub, et mitte sest muud slaved kippusid siis databaiti enda kohta käivana lugema ja võtsid kohe sõna... Ilmselt saadi strechingust vajalik start-condition kätte. Seega: millal on viivitus lubatud? Microchipi I2C slave DS-ist ei saanud nagu hästi aru ... ja see tähendas paraku mitu päeva debugimist - viga ilmnes ju ainult siis kui databait langes kokku kellakivi aadressiga!
Vasta
#2
peaks alati lubatud olema. Uuri miks START käsk tekib - seal on kala.
Slave I2C on prosedes üsna sageli kõveralt välja kukkunud ning see on üsna igavene peavalu teema.
Lihtsaim lahendus on master'i softi mudimine selles suunas et andestaks slave'i lollused.
Vasta
#3
"clock streching" on mõeldud selleks, et kui peab veel millegagi tegelema peale I2C data kättesaamist ja see on aega nõudev, siis saab strechinguga kogu I2C kommunikatsiooni liini kinni tõmmata nagu pausi peal panna , et ei juhtuks nii, et saabub juba uus ülesanne, kui vana on veel täitmata.
Arvan, et üldjuhul seda ei pea kasutama, pakettide vahel on ka arvestatav aja vahemik ja mida rohkem mooduleid liini peal, seda rohkem on ajalist reservi.
Miski 200mikrosekundit ei ole probleemiks.
Mis asjaga sinu slave siis tegeleb, et see nii kaua aega võtab?

Lisan näidise.
Minul oli selline situatsioon, et on 11väljundiga I2C slave moodul, see on mõnevõrra eriline ,kuna tal on TDE1798 igas väljundis ja see omab lühisekaitset ja PIC saab ka tagasisidet lühise kohta ja transpordib seda Masterile , muidugi, kui masterisse on selline küsimine sisestatud.
Lisaks on kõigil 11 lühise lugemise ahelatel valehäirete vastane 200ms viide peal, et suvaline impulss valehäiret ei annaks.

Trükkplaadi tegemisel oli hea teha väljundid registrite suhtes risti-rästi, aga programmis peab siis tegelema nende ringi tõlkimisega.
Kogu I2C on interruptis.
Aga OTRANS1 ja OTRANS2 on need kohad, kus peab tõlkima ja siin ongi
"clock streching" kasutuses. Enne, kui tõlkimise protsess pole lõppenud ei lasta I2C kommunikatsiooni vabaks.
Praktikas on see ülepingutus, kuna kahe I2C paketi vahe on ca 184 mikrosekundit, aga tõlke protsess võtab vast 22 mikrosekundit, ei hakka laus täpselt arvutama.
aga sisse tema sai programmi pantud.
Kasutatud on 16F883(16F882,884) MSSP moodulit.
Reaalselt töötav programm.
; 16F883 I2C 23 INPUTS SLAVE MODULE WITH ANALOG AND DIGITAL FULL FILTERING
; 11 OUT 0,5A feedback from short cricuit.
;
list p=16F883 ;tell assembler what chip we are using
include "P16F883.inc" ;include the defaults for the chip
errorlevel 0,-302 ;suppress bank selection messages

__CONFIG1 EQU 20C4
;FOSC Oscillator Selection bitsINTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
;WDTE Watchdog Timer Enable bitWDT disabled and can be enabled by SWDTEN bit of the WDTCON register
;PWRTE Power-up Timer Enable bitPWRT enabled
;MCLRE RE3/MCLR pin function select bitRE3/MCLR pin function is digital input, MCLR internally tied to VDD
;CP Code Protection bitProgram memory code protection is disabled
;CPD Data Code Protection bitData memory code protection is disabled
;BOREN Brown Out Reset Selection bitsBOR disabled
;IESO Internal External Switchover bitInternal/External Switchover mode is disabled
;FCMEN Fail-Safe Clock Monitor Enabled bitFail-Safe Clock Monitor is disabled
;LVP Low Voltage Programming Enable bitRB3 pin has digital I/O, HV on MCLR must be used for programming

__CONFIG2 EQU 3EFF
;BOR4V Brown-out Reset Selection bitBrown-out Reset set to 2.1V
;WRT Flash Program Memory Self Write Enable bitsWrite protection off

;###################
; INPUTS / OUTPUTS
;###################

;SCL - PORTC3 (PIN 14 )
;SDA - PORTC4 (PIN 15 )

;###################
; USER RAM ADRESSES
;###################
;USER RAM 020h - 16Fh

cblock 0x20 ;start of general purpose registers

OUTI2C_1_8
OUTI2C_9_11
ALI2C_1_8
ALI2C_9_11
CTRLBY
ADRBY
WRONGW
WRONGR

TMRA
MARKER_I2C
W_TEMP
STATUS_TEMP

D_AL1
D_AL2
D_AL3
D_AL4
D_AL5
D_AL6
D_AL7
D_AL8
D_AL9
D_AL10
D_AL11

endc ;END of general purpose registers
;###################
; MACRO MOVLF
;###################
MOVLF MACRO LITERAL,DESTINATION
MOVLW LITERAL ; PUT THE LITERAL IN W
MOVWF DESTINATION ; & OUT TO THE DESTINATION FILE
ENDM
;###################
; MACRO MOVFF
;###################
MOVFF MACRO DEST1,DEST2
MOVF DEST1,W
MOVWF DEST2
ENDM
;#######################
; MACRO RESTORE END INT
;#######################
XINTEND MACRO
SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register in
;(sets bank to original state
MOVWF STATUS ;Move W into STATUS register
SWAPF W_TEMP,F ;Swap W_TEMP
SWAPF W_TEMP,W ;Swap W_TEMP into W
ENDM
;#######################
; MACRO LEAVE MSSP INT
;#######################
YINTEND MACRO
BCF PIR1,3 ;SSPIF CLEAR MSSP INTERRUPT
BSF SSPCON,4 ;SCK release control ,1 = Enable clock
RETFIE ;RETURN FROM INTERRUPT
ENDM
;########################################################
; MACRO 1 OUT BITS TRANSLATE FOLLOWING WITH I2C RECEIVED
;########################################################
OTRANS1 MACRO
BTFSC OUTI2C_1_8,0
BSF OUT1
BTFSS OUTI2C_1_8,0
BCF OUT1
BTFSC OUTI2C_1_8,1
BSF OUT2
BTFSS OUTI2C_1_8,1
BCF OUT2
BTFSC OUTI2C_1_8,2
BSF OUT3
BTFSS OUTI2C_1_8,2
BCF OUT3
BTFSC OUTI2C_1_8,3
BSF OUT4
BTFSS OUTI2C_1_8,3
BCF OUT4
BTFSC OUTI2C_1_8,4
BSF OUT5
BTFSS OUTI2C_1_8,4
BCF OUT5
BTFSC OUTI2C_1_8,5
BSF OUT6
BTFSS OUTI2C_1_8,5
BCF OUT6
BTFSC OUTI2C_1_8,6
BSF OUT7
BTFSS OUTI2C_1_8,6
BCF OUT7
BTFSC OUTI2C_1_8,7
BSF OUT8
BTFSS OUTI2C_1_8,7
BCF OUT8
ENDM
;########################################################
; MACRO 1 OUT BITS TRANSLATE FOLLOWING WITH I2C RECEIVED
;########################################################
OTRANS2 MACRO
BTFSC OUTI2C_9_11,0
BSF OUT9
BTFSS OUTI2C_9_11,0
BCF OUT9
BTFSC OUTI2C_9_11,1
BSF OUT10
BTFSS OUTI2C_9_11,1
BCF OUT10
BTFSC OUTI2C_9_11,2
BSF OUT11
BTFSS OUTI2C_9_11,2
BCF OUT11
ENDM

;###################
; DECLARATIONS
;###################

ALDELAY EQU D'3' ;RESET TIMER SETTINGS FOR AL

;#############################################

#DEFINE IN1 PORTC,5 ;IN 1 - PORTC5 (PIN 16)
#DEFINE IN2 PORTC,2 ;IN 2 - PORTC2 (PIN 13)
#DEFINE IN3 PORTC,0 ;IN 3 - PORTC0 (PIN 11)
#DEFINE IN4 PORTA,7 ;IN 4 - PORTA7 (PIN 9 )
#DEFINE IN5 PORTA,4 ;IN 5 - PORTA4 (PIN 6 )
#DEFINE IN6 PORTA,2 ;INA 6 - PORTA2 (PIN 4 )
#DEFINE IN7 PORTA,1 ;INA 7 - PORTA1 (PIN 3 )
#DEFINE IN8 PORTB,1 ;INA 8 - PORTB1 (PIN 22)
#DEFINE IN9 PORTB,7 ;IN 9 - PORTB7 (PIN 28)
#DEFINE IN10 PORTB,5 ;INA 10 - PORTB5 (PIN 26)
#DEFINE IN11 PORTB,3 ;INA 11 - PORTB3 (PIN 24)

#DEFINE OUT1 PORTC,6 ;OUT 1 - PORTC6 (PIN 17)
#DEFINE OUT2 PORTC,7 ;OUT 2 - PORTC7 (PIN 18)
#DEFINE OUT3 PORTC,1 ;OUT 3 - PORTC1 (PIN 12)
#DEFINE OUT4 PORTA,6 ;OUT 4 - PORTA6 (PIN 10)
#DEFINE OUT5 PORTA,5 ;OUT 5 - PORTA5 (PIN 7 )
#DEFINE OUT6 PORTA,3 ;OUT 6 - PORTA3 (PIN 5 )
#DEFINE OUT7 PORTA,0 ;OUT 7 - PORTA0 (PIN 2 )
#DEFINE OUT8 PORTB,0 ;OUT 8 - PORTB0 (PIN 21)
#DEFINE OUT9 PORTB,2 ;OUT 9 - PORTB2 (PIN 23)
#DEFINE OUT10 PORTB,6 ;OUT 10 - PORTB6 (PIN 27)
#DEFINE OUT11 PORTB,4 ;OUT 11 - PORTB4 (PIN 25)

;###############
; PROGRAM START
;###############
ORG 0 ;startup address = 0000
GOTO BEGIN ;SRY ADDRESS 0004 IS RESERVED FOR INTERRUPT
;###############
; INTERRUPT
;###############
ORG 4 ;INTERRUPT START ADDRESS
;SAVING STATUS AND W REGISTERS IN RAM
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into
;Swaps are used because they
MOVWF STATUS_TEMP ;Save status to bank zero STA
;Insert user code here
;##################################################################
RW_OR_TMR0FF BTFSS INTCON,2 ;CHK READ/WRITE OR TMR0FF OVERFLOW INTERRUPT
GOTO R_OR_W ;IF SSPSTAT,2 = 0, GOTO READ/WRITE INTERRUPT
INCF TMRA,F ;IF SSPSTAT,2 = 1,INCREASE TMRB+1=TMRB
BSF INTCON,5 ;T0IE Timer0 Overflow Interrupt Enable bit
BCF INTCON,2 ;T0IF CLEAR Timer0 Overflow Interrupt Flag bit
XINTEND ;RESTORE BEFORE INT W AND OPTION REG
RETFIE ;RETURN FROM INTERRUPT
;##################################################################
R_OR_W BSF STATUS,RP0 ;SELECT BANK 1
BTFSC SSPSTAT,2 ;CHK READ OR WRITE (A0 OR A1) RECEIVED
GOTO INT_READ ;IF SSPSTAT,2 = 0, GOTO READ OPERATION
;IF SSPSTAT,2 = 1, DO WRITE OPERATION
;##################################################################
INT_WRITE BCF STATUS,RP0 ;SELECT BANK 0

CHK_CRTLBY BTFSS MARKER_I2C,0 ;CHK ADRBYTE DONE OR NOT
GOTO INT_ADRBY ;IF NOT DONE GOTO COPY ADRBYTE
BTFSS MARKER_I2C,1 ;CHK CONTRBYTE (01,02) DONE OR NOT
GOTO INT_CTRLBY ;IF NOT DONE GOTO COPY CONTRBYTE
GOTO CHK_W1 ;IF ADRBYTE AND CONTRBYTE DONE GO TEST 01 02

INT_ADRBY BSF STATUS,RP0 ;SELECT BANK 1
BSF SSPCON2,0 ;SEN 1 = Clock stretching is enabled
BCF STATUS,RP0 ;SELECT BANK 0
BCF SSPCON,4 ;SCK release control ,0 = Holds clock low (clock stretch)
MOVFF SSPBUF,ADRBY ;COPY I2C CONTROLBYTE
BSF MARKER_I2C,0 ;CLEAR MARKERI2C,REG SAVE IS DONE
GOTO INTW_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

INT_CTRLBY BSF STATUS,RP0 ;SELECT BANK 1
BSF SSPCON2,0 ;SEN 1 = Clock stretching is enabled
BCF STATUS,RP0 ;SELECT BANK 0
BCF SSPCON,4 ;SCK release control ,0 = Holds clock low (clock stretch)
MOVFF SSPBUF,CTRLBY ;COPY I2C CONTROLBYTE
BSF MARKER_I2C,1 ;CLEAR MARKERI2C,REG SAVE IS DONE
GOTO INTW_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

CHK_W1 MOVLW H'01' ;TEST I2C CONTROL BYTE FOR FIRST SAVE READ
XORWF CTRLBY,W ;CHK IF SSPBUF REG EQU 01
BTFSS STATUS,Z ;TEST RESULT OF XOR
GOTO CHK_W2 ;IF 01 IS NOT MACHING, THEN GO TEST 02
BSF STATUS,RP0 ;SELECT BANK 1
BSF SSPCON2,0 ;SEN 1 = Clock stretching is enabled
BCF STATUS,RP0 ;SELECT BANK 0
BCF SSPCON,4 ;SCK release control ,0 = Holds clock low (clock stretch)
MOVFF SSPBUF,OUTI2C_1_8 ;COPY I2C FIRST RECEIVED DATA TO REG
OTRANS1 ;TRANSFER 1 RECEIVED I2C BITS TO OUT BY ORDER
BCF MARKER_I2C,0
BCF MARKER_I2C,1 ;CLEAR MARKERI2C,REG SAVE IS DONE
GOTO INTW_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

CHK_W2 MOVLW H'02' ;TEST I2C CONTROL BYTE FOR FIRST SAVE READ
XORWF CTRLBY,W ;CHK IF SSPBUF REG EQU 01
BTFSS STATUS,Z ;TEST RESULT OF XOR
GOTO WRONG_W ;DO WRITE DATA WITH WRONG CONROLBYTE TO EMTY REG
BSF STATUS,RP0 ;SELECT BANK 1
BSF SSPCON2,0 ;SEN 1 = Clock stretching is enabled
BCF STATUS,RP0 ;SELECT BANK 0
BCF SSPCON,4 ;SCK release control ,0 = Holds clock low (clock stretch)
MOVFF SSPBUF,OUTI2C_9_11 ;COPY I2C SECOND RECEIVED DATA TO REG
OTRANS2 ;TRANSFER 2 RECEIVED I2C BITS TO OUT BY ORDER
BCF MARKER_I2C,0
BCF MARKER_I2C,1 ;CLEAR MARKERI2C,REG SAVE IS DONE
GOTO INTW_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

WRONG_W BSF STATUS,RP0 ;SELECT BANK 1
BSF SSPCON2,0 ;SEN 1 = Clock stretching is enabled
BCF STATUS,RP0 ;SELECT BANK 0
BCF SSPCON,4 ;SCK release control ,0 = Holds clock low (clock stretch)
MOVFF SSPBUF,WRONGW ;COPY I2C RECEIVED DATA TO WRONGW
BCF MARKER_I2C,0
BCF MARKER_I2C,1 ;CLEAR MARKERI2C,REG SAVE IS DONE
GOTO INTW_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT
;##################################################################
INT_READ BCF STATUS,RP0 ;SELECT BANK 0

CHK_R1 MOVLW H'01' ;TEST I2C CONTROL BYTE FOR FIRST SAVE READ
XORWF CTRLBY,W ;CHK IF SSPBUF REG EQU 01
BTFSS STATUS,Z ;TEST RESULT OF XOR
GOTO CHK_R2 ;IF 01 IS NOT MACHING, THEN GO TEST 02
INT_R1 MOVFF ALI2C_1_8,SSPBUF ;COPY ALARM REG1 TO SSPBUF
CLRF CTRLBY
GOTO INTR_END ;LEAVE INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

CHK_R2 MOVLW H'02' ;TEST I2C CONTROL BYTE FOR FIRST SAVE READ
XORWF CTRLBY,W ;CHK IF SSPBUF REG EQU 01
BTFSS STATUS,Z ;TEST RESULT OF XOR
GOTO WRONG_R ;DO WRONG READ H00 FOR WRONG CONTROLBYTE
INT_R2 MOVFF ALI2C_9_11,SSPBUF ;COPY ALARM REG2 TO SSPBUF
CLRF CTRLBY
GOTO INTR_END ;INTERRUPT OPERATIONS,PREPARE FOR NEXT INT

WRONG_R MOVFF WRONGR,SSPBUF ;COPY WRONGR TO SSPBUF
CLRF CTRLBY
GOTO INTR_END ;INTERRUPT OPERATIONS,PREPARE FOR NEXT INT
;##################################################################
INTW_END XINTEND ;RESTORE BEFORE INT W AND OPTION REG
BSF STATUS,RP0 ;SELECT BANK 1
BCF SSPCON2,0 ;SEN 0 = Clock stretching is disabled
BCF STATUS,RP0 ;SELECT BANK 0
YINTEND ;LEAVE MSSP INTERRUPT
;##################################################################
INTR_END XINTEND ;RESTORE BEFORE INT W AND OPTION REG
YINTEND ;LEAVE MSSP INTERRUPT
;##################################################################

;###############
; BEGIN
;###############
BEGIN
CLRF PORTA ;INIT PORTA
CLRF PORTB ;INIT PORTB
CLRF PORTC ;INIT PORTC
CLRF PORTE ;INIT PORTE

MOVLF B'11011000',STATUS ;SELECT BANK 2
MOVLF B'00000000',CM1CON0 ;SET COMPARATOR 1 NOT ACTIVE, DISABLE COMPARATOR1
MOVLF B'00000000',CM2CON0 ;SET COMPARATOR 2 NOT ACTIVE, DISABLE COMPARATOR2

MOVLF B'11111000',STATUS ;SELECT BANK 3
MOVLF B'00000000',ANSEL ;SET ALL DIGITAL INPUTS, SET NO ANY ANALOG IN
MOVLF B'00000000',ANSELH ;SET ALL DIGITAL INPUTS, SET NO ANY ANALOG IN
MOVLF B'00111000',STATUS ;SELECT BANK 1

MOVLF B'10010110',TRISA ;SET A1,A2,A4,A7 = IN, A0,A3,A5,A6 = OUT
MOVLF B'10101010',TRISB ;SET B1,B3,B5,B7 = IN, B0,B2,B4,B6 = OUT
MOVLF B'00111101',TRISC ;SET C0,C2,C3(SCL),C4(SDA),C5 = IN, C1,C6,C7 = OUT
MOVLF B'00001000',TRISE ;SET E1 = IN
MOVLF B'10000111',OPTION_REG ;TMR0 IS INTERNAL TIMER WITH MAX DELAY,NO PORTB PULLUP RESISTORS
MOVLF H'90',SSPADD ;SET I2C ADDRESS
MOVLF B'01110111',OSCCON ; 8MHZ AND STABLE, NO CONFIG SET.
BSF SSPCON2,0 ;SEN CLOCK STRECH ENABLED *SIIN STRECH

BCF STATUS,RP0 ;SELECT BANK 0
MOVLF B'00110110',SSPCON ;I2C SLAVE MODE 7-BIT ADDRESS XX1X0110,ENABLE I2C FUNCTION

;##############
; MAIN ROUTINE
;##############

CALL CLEAR

BSF INTCON,7 ;GIE ENABLE GLOBAL INTERRUPT
BSF INTCON,5 ;SET INTERRUPT READY FOR TMR0 = FF
BSF INTCON,PEIE ;INTCON,6 ENABLE PERIPHERAL INTERRUPT
BSF STATUS,RP0 ;SELECT BANK 1
BSF PIE1,3 ;SSPIE ENABLE MSSP INTERRUPT
BCF STATUS,RP0 ;SELECT BANK 0

;#############################################
; AL BLINK CONVERT TO STABLE AL SIGNAL ON/OFF
;#############################################
MAIN

AL1_TEST_A BTFSC IN1 ;CHK IN1 ALARM PRESENT OR NOT
GOTO AL1_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,0 ;IF ALARM PRESENT SET ALIN1 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL1 ;COPY RESULT TO REG D_AL1
GOTO AL2_TEST_A ;DO NEXT IN ALARM TEST
AL1_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL1,W ;COMPARE D_AL1 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL2_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,0 ;IF TIME REACHED AND NO AL, CLR ALIN1 IN I2C TRANSPORT REG
;#####################################
AL2_TEST_A BTFSC IN2 ;CHK IN2 ALARM PRESENT OR NOT
GOTO AL2_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,1 ;IF ALARM PRESENT SET ALIN2 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL2 ;COPY RESULT TO REG D_AL2
GOTO AL3_TEST_A ;DO NEXT IN ALARM TEST
AL2_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL2,W ;COMPARE D_AL2 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL3_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,1 ;IF TIME REACHED AND NO AL, CLR ALIN2 IN I2C TRANSPORT REG
;#####################################
AL3_TEST_A BTFSC IN3 ;CHK IN3 ALARM PRESENT OR NOT
GOTO AL3_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,2 ;IF ALARM PRESENT SET ALIN3 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL3 ;COPY RESULT TO REG D_AL3
GOTO AL4_TEST_A ;DO NEXT IN ALARM TEST
AL3_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL3,W ;COMPARE D_AL3 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL4_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,2 ;IF TIME REACHED AND NO AL, CLR ALIN3 IN I2C TRANSPORT REG
;#####################################
AL4_TEST_A BTFSC IN4 ;CHK IN4 ALARM PRESENT OR NOT
GOTO AL4_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,3 ;IF ALARM PRESENT SET ALIN4 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL4 ;COPY RESULT TO REG D_AL4
GOTO AL5_TEST_A ;DO NEXT IN ALARM TEST
AL4_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL4,W ;COMPARE D_AL4 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL5_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,3 ;IF TIME REACHED AND NO AL, CLR ALIN4 IN I2C TRANSPORT REG
;#####################################
AL5_TEST_A BTFSC IN5 ;CHK IN5 ALARM PRESENT OR NOT
GOTO AL5_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,4 ;IF ALARM PRESENT SET ALIN4 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL5 ;COPY RESULT TO REG D_AL5
GOTO AL6_TEST_A ;DO NEXT IN ALARM TEST
AL5_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL5,W ;COMPARE D_AL5 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL6_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,4 ;IF TIME REACHED AND NO AL, CLR ALIN5 IN I2C TRANSPORT REG
;#####################################
AL6_TEST_A BTFSC IN6 ;CHK IN6 ALARM PRESENT OR NOT
GOTO AL6_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,5 ;IF ALARM PRESENT SET ALIN6 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL6 ;COPY RESULT TO REG D_AL4
GOTO AL7_TEST_A ;DO NEXT IN ALARM TEST
AL6_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL6,W ;COMPARE D_AL6 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL7_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,5 ;IF TIME REACHED AND NO AL, CLR ALIN6 IN I2C TRANSPORT REG
;#####################################
AL7_TEST_A BTFSC IN7 ;CHK IN7 ALARM PRESENT OR NOT
GOTO AL7_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,6 ;IF ALARM PRESENT SET ALIN7 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL7 ;COPY RESULT TO REG D_AL7
GOTO AL8_TEST_A ;DO NEXT IN ALARM TEST
AL7_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL7,W ;COMPARE D_AL7 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL8_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,6 ;IF TIME REACHED AND NO AL, CLR ALIN7 IN I2C TRANSPORT REG
;#####################################
AL8_TEST_A BTFSC IN8 ;CHK IN8 ALARM PRESENT OR NOT
GOTO AL8_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_1_8,7 ;IF ALARM PRESENT SET ALIN8 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL7 ;COPY RESULT TO REG D_AL8
GOTO AL9_TEST_A ;DO NEXT IN ALARM TEST
AL8_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL7,W ;COMPARE D_AL8 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL9_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_1_8,7 ;IF TIME REACHED AND NO AL, CLR ALIN8 IN I2C TRANSPORT REG
;#####################################
AL9_TEST_A BTFSC IN9 ;CHK IN9 ALARM PRESENT OR NOT
GOTO AL9_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_9_11,0 ;IF ALARM PRESENT SET ALIN9 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL9 ;COPY RESULT TO REG D_AL9
GOTO AL10_TEST_A ;DO NEXT IN ALARM TEST
AL9_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL9,W ;COMPARE D_AL9 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL10_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_9_11,0 ;IF TIME REACHED AND NO AL, CLR ALIN9 IN I2C TRANSPORT REG
;#####################################
AL10_TEST_A BTFSC IN10 ;CHK IN10 ALARM PRESENT OR NOT
GOTO AL10_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_9_11,1 ;IF ALARM PRESENT SET ALIN10 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL10 ;COPY RESULT TO REG D_AL10
GOTO AL11_TEST_A ;DO NEXT IN ALARM TEST
AL10_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL10,W ;COMPARE D_AL10 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO AL11_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_9_11,1 ;IF TIME REACHED AND NO AL, CLR ALIN10 IN I2C TRANSPORT REG
;#####################################
AL11_TEST_A BTFSC IN11 ;CHK IN11 ALARM PRESENT OR NOT
GOTO AL11_TEST_B ;IF NOT PRESENT ALARM GOTO TIME COMPARE
BSF ALI2C_9_11,2 ;IF ALARM PRESENT SET ALIN11 IN I2C TRANSPORT REG
MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
ADDLW ALDELAY ;W+ALDELAY=W
MOVWF D_AL11 ;COPY RESULT TO REG D_AL11
GOTO ALEND_TEST_A ;DO NEXT IN ALARM TEST
AL11_TEST_B MOVF TMRA,W ;COPY TMRA NOW TO WORKREG
SUBWF D_AL11,W ;COMPARE D_AL11 WITH WORKREG
BTFSC STATUS,0 ;CHK RESULT OF XOR
GOTO ALEND_TEST_A ;DO NEXT IN ALARM TEST
BCF ALI2C_9_11,2 ;IF TIME REACHED AND NO AL, CLR ALIN11 IN I2C TRANSPORT REG

ALEND_TEST_A GOTO MAIN ;REPEAT IN1-IN11 TEST FOREVER

;###############################
;EXSTRA STARTUP CLEARS
;###############################
CLEAR
CLRF OUTI2C_1_8
CLRF OUTI2C_9_11
CLRF ALI2C_1_8
CLRF ALI2C_9_11
CLRF CTRLBY
CLRF ADRBY

CLRF WRONGW
CLRF WRONGR

CLRF TMRA
CLRF MARKER_I2C
CLRF W_TEMP
CLRF STATUS_TEMP

CLRF D_AL1
CLRF D_AL2
CLRF D_AL3
CLRF D_AL4
CLRF D_AL5
CLRF D_AL6
CLRF D_AL7
CLRF D_AL8
CLRF D_AL9
CLRF D_AL10
CLRF D_AL11

RETURN

;###############################

END
I2C ei ole pic-s häda mitte midagi, töötab ideaalselt.
Probleem on tavaliselt selles, et ei saada täiesti korralikkult aru, kuidas see I2C täpselt töötab ja lisaks on raske saada netist korralikku näidist.
Ja ka simuleerimine on probleemne, ISIS-s on I2C näiteks 16f883(882,884) MSSP moodulite kasutamisel päris kööbakas, lihtsalt ISIS tegija ei ole saanud korralikkult aru , kuidas I2C toimib ja vastavalt on ka simulaator vigane ja praktikas mitte kasutatav. Oshon ei ole isege MSSP moodulit lisatud , ja simuleerimine ei olegi seal mõeldav.
Tuli teha reaalsed trükkplaadid ja skeemid valmis ja nende peal ka simuleerida.
Lisaks tehakse neid I2C asju tavaliselt basic või C keeles, aga nood kasutavad kellegi ette tehtud h. faile, ja kui seal ei ole asi ideaalselt tehtud, või vastavat h. faili veel keegi teinud pole, siis jääbki tegemata.(juhul, kui tegija ise nii kõva mees pole, et oskab h. faili ise ära teha.)
Näieks I2C 2x16 LCD ei saanudki teha, aga assembleris sai asi ilusti ära tehtud.
Vasta


Alamfoorumi hüpe:


Kasutaja, kes vaatavad seda teemat: 1 külali(st)ne