1 | ;***I2C UNTERPROGRAMME************************************************************
|
2 | ;
|
3 | ; I2C-Bus im Master-Mode übernehmen
|
4 | ; Warten bis MSSP-Modul frei ist
|
5 | i2c_idle
|
6 | Bank1
|
7 | btfsc SSPSTAT, R_W ;läuft eine Übertragung?
|
8 | goto $-1 ;ja, warten...
|
9 | i2cidle_loop2
|
10 | movfw SSPCON2 ;nein, läuft ein anderes Ereignis?
|
11 | andlw 0x1F ;test auf ACKEN, RCEN, PEN, RSEN, SEN
|
12 | btfss STATUS,Z
|
13 | goto i2cidle_loop2 ;ja, warten...
|
14 | Bank0
|
15 | return ;MSSP Modul ist nicht beschäftigt
|
16 |
|
17 | i2c_start
|
18 | call i2c_idle ;Bus frei?
|
19 | Bank1
|
20 | bsf SSPCON2, SEN ;Bus Übernahme anweisen und Startbit senden
|
21 | btfsc SSPCON2, SEN ;Auf das Ende der Startkondition warten
|
22 | goto $-1
|
23 | Bank0
|
24 | return
|
25 |
|
26 | ;Restart aktivieren
|
27 | i2c_rstart
|
28 | call i2c_idle ;Bus frei?
|
29 | Bank1
|
30 | bsf SSPCON2, RSEN ;Restart Sequence einleiten
|
31 | btfsc SSPCON2, RSEN
|
32 | goto $-1
|
33 | Bank0
|
34 | return
|
35 |
|
36 | ;ein Byte aus W senden
|
37 | ;Rückgabewert in W: 0=ACK empfangen, 1=ACK nicht empfangen
|
38 | i2c_tx
|
39 | movwf i2c_Puffer
|
40 | call i2c_idle ;Bus frei?
|
41 | bcf PIR1, SSPIF ;Lösche Interrupt Flag
|
42 | movfw i2c_Puffer
|
43 | movwf SSPBUF ;Byte wird gesendet
|
44 | btfss PIR1, SSPIF ;Senden fertig?
|
45 | goto $-1
|
46 |
|
47 | Bank1
|
48 | btfss SSPCON2, ACKSTAT ;Test ob ACK vom Slave empfangen wurde
|
49 | goto i2c_tx_ack
|
50 | Bank0
|
51 | retlw d'1' ;ACK wurde nicht empfangen
|
52 | i2c_tx_ack
|
53 | Bank0
|
54 | retlw d'0' ;ACK wurde empfangen
|
55 |
|
56 | ;ein Byte vom Slave empfangen ohne ACK
|
57 | ;Rückgabewert in W
|
58 | i2c_rx
|
59 | call i2c_idle
|
60 | bcf PIR1,SSPIF ;Interrupt Flag löschen
|
61 | Bank1
|
62 | bsf SSPCON2, RCEN ;Empfang einschalten
|
63 | Bank0
|
64 | btfss PIR1,SSPIF ;Byte empfangen?
|
65 | goto $-1 ;noch nicht
|
66 |
|
67 | Bank1
|
68 | bsf SSPCON2, ACKDT ;kein ACK senden (ACK=High)
|
69 | bsf SSPCON2, ACKEN ;sende negatives ACK
|
70 | btfsc SSPCON2, ACKEN ;fertig?
|
71 | goto $-1
|
72 | Bank0
|
73 | movfw SSPBUF ;Empfangenen Wert nach W
|
74 | return
|
75 |
|
76 | ;ein Byte vom Slave empfangen mit ACK
|
77 | ;Rückgabewert in W
|
78 | i2c_rx_ack
|
79 | call i2c_idle
|
80 | bcf PIR1,SSPIF ;Interrupt Flag löschen
|
81 | Bank1
|
82 | bsf SSPCON2, RCEN ;Empfang einschalten
|
83 | Bank0
|
84 | btfss PIR1,SSPIF ;Byte empfangen?
|
85 | goto $-1 ;noch nicht
|
86 |
|
87 | Bank1
|
88 | bcf SSPCON2, ACKDT ;ACK senden
|
89 | bsf SSPCON2, ACKEN
|
90 | btfsc SSPCON2, ACKEN ;fertig?
|
91 | goto $-1
|
92 | Bank0
|
93 | movfw SSPBUF ;Empfangenen Wert nach W
|
94 | return
|
95 |
|
96 | ; I2C-Bus wieder freigeben
|
97 | i2c_stop
|
98 | call i2c_idle
|
99 | Bank1
|
100 | bsf SSPCON2, PEN ;Stop Bit senden und Bus frei geben
|
101 | btfsc SSPCON2, PEN ;fertig?
|
102 | goto $-1
|
103 | Bank0
|
104 | return
|