Subversion Repositories group.electronics

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 - 1
  list        p=16F84A
2
    include    "p16F84a.inc"
3
 
4
;***** CONFIGURATION
5
           __CONFIG _PWRTE_ON & _HS_OSC & _WDT_OFF
6
 
7
; pin assignments
8
    #define SDA         0           ; Pin 0
9
    #define SCL         1           ; Pin 1
10
    #define TRIS_SDA    TRISB,SDA
11
    #define TRIS_SCL    TRISB,SCL
12
    #define I2C_SDA     PORTB,SDA
13
    #define I2C_SCL     PORTB,SCL
14
    #define LED         PORTB,2
15
 
16
    #define I2C_SLAVE1 0x27
17
 
18
    CBLOCK     0CH
19
        counter
20
 
21
        _I
22
        byte_send
23
        i2c_addr
24
 
25
        i2c_ret         ; I2C Return Value
26
 
27
        dly_loop1       ; Loops for delays
28
        dly_loop2
29
    ENDC
30
 
31
    ORG 0
32
    goto start           ; jump over to main routine
33
 
34
;***** Initialisation
35
start
36
        ; configure ports
37
        clrw                    ; configure PORTB and PORTC as all outputs
38
        tris    PORTB
39
        clrf    PORTB
40
 
41
        movlw   b'00000000'     ; Init our counter
42
        movwf   counter
43
 
44
;***** Main loop
45
main_loop
46
        bsf     LED
47
        call    SendCount
48
        bcf     LED
49
 
50
        goto    main_loop
51
 
52
SendCount
53
 
54
        movlw   I2C_SLAVE1      ; 7-bit address of dev
55
        bcf     STATUS,C        ; Use Write mode ('0')
56
        call    I2C_Start       ; Start a transmission
57
        call    ReadAck         ; Wait for Ack from slave
58
        movf    i2c_ret         ; Check return value
59
        btfss   STATUS,Z        ; Goto SendEnd on NACK
60
        goto    SendErr
61
 
62
        movfw   counter         ; Copy byte to write (counter) to w
63
        call    I2C_Write       ; Write the byte to the line
64
        call    ReadAck            ; Should read byte from bus here
65
                                ;  checking that its a Nack
66
 
67
        call    I2C_End         ; End the packet
68
        bcf     LED
69
        incf    counter,f
70
        call    Delay_Short
71
        return
72
 
73
SendErr
74
        call    I2C_End
75
 
76
        ;call    Delay_Long      ; Wait a while before resend
77
        return
78
 
79
I2C_Start
80
        movwf   i2c_addr        ; Save the address in W
81
        rlf     i2c_addr,f      ; Attach '0' to 8th bit
82
        call    Start           ; Start the Trans
83
        movfw   i2c_addr
84
        call    I2C_Write       ; Write byte to port
85
        return
86
 
87
I2C_End
88
        call    Stop
89
        return
90
 
91
I2C_Write
92
        movwf   byte_send
93
        movlw   .8              ; 8 bits to send
94
        movwf    _I
95
_WriteBit
96
        rlf     byte_send,f        ; Move highest bit to C
97
        btfss   STATUS,C        ; If 'C' is clear
98
        call    SDA_Low         ;   -> Set data low
99
        btfsc   STATUS,C        ; If 'C' is set
100
        call    SDA_High        ;   -> Set data high
101
 
102
        call    SCL_Pulse
103
 
104
        decfsz  _I,f        ; Decrement counter, if not clear
105
        goto    _WriteBit         ;   -> Send next bit
106
        call    SDA_Low         ; Set low to allow slave to write
107
        return
108
 
109
Nack                            ; Clock a high SDA
110
        call    SDA_High
111
        call    SCL_Pulse
112
        return
113
 
114
Ack                            ; Clock a high SDA
115
        call    SDA_Low
116
        call    SCL_Pulse
117
        return
118
 
119
ReadAck
120
        call    SCL_High
121
        clrf    i2c_ret
122
        btfsc   I2C_SDA
123
        bsf     i2c_ret,0
124
        call    SCL_Low
125
        return
126
 
127
Start
128
        call    SDA_High
129
        call    SCL_High
130
        call    SDA_Low
131
        call    SCL_Low
132
        return
133
 
134
Stop                            ; Bring SDA high while Clock high
135
        call    SCL_Low
136
        call    SDA_Low
137
        call    SCL_High
138
        call    SDA_High
139
        return
140
 
141
SCL_Pulse
142
        call  SCL_High
143
        call  SCL_Low
144
        return
145
 
146
SDA_High
147
        bsf     STATUS,RP0      ; Bank 1
148
        bsf     TRIS_SDA        ; Make SDA pin input
149
        bcf     STATUS,RP0      ; Back to bank 0
150
        call    Delay_Short
151
        return
152
 
153
SDA_Low
154
        bcf     I2C_SDA
155
        bsf     STATUS,RP0
156
        bcf     TRIS_SDA        ; Make SDA pin output
157
        bcf     STATUS,RP0
158
        call    Delay_Short
159
        return
160
 
161
SCL_High
162
        bsf     STATUS,RP0      ; Bank 1
163
        bsf     TRIS_SCL        ; Make SDA pin input
164
        bcf     STATUS,RP0      ; Back to bank 0
165
        call    Delay_Short
166
        return
167
 
168
SCL_Low
169
        bcf     I2C_SCL
170
        bsf     STATUS,RP0
171
        bcf     TRIS_SCL        ; Make SDA pin output
172
        bcf     STATUS,RP0
173
        call    Delay_Short
174
        return
175
 
176
Delay_Short                 ; 25us delay
177
        movlw   .5
178
        movwf   dly_loop2
179
Delay_Short_1
180
        nop
181
        decfsz  dly_loop2,f
182
        goto    Delay_Short_1
183
        return
184
 
185
Delay_Long
186
        movlw   .250        ; 250ms delay
187
        movwf   dly_loop1
188
Outer
189
        movlw   .110        ; Close to 1ms when set to .110
190
        movwf   dly_loop2
191
Inner
192
        nop
193
        nop
194
        nop
195
        nop
196
        nop
197
        nop
198
        decfsz  dly_loop2,f
199
        goto    Inner
200
        decfsz  dly_loop1,f
201
        goto    Outer
202
        return
203
 
204
END