1 | ;Display-Routine. Liest ab "String" das SRAM aus und gibt es auf dem Display aus.
|
2 |
|
3 | .EQU String=0x60 ;SRAM-Location
|
4 | .EQU Stringlength=8
|
5 | .EQU Symbol=0x6A ;SRAM-Location für Symbole
|
6 | .EQU Symbollength=2
|
7 | .EQU SlaveAddress=0x4A ;TID-Addresse
|
8 |
|
9 | ;*************
|
10 | .EQU SCL_OUT=0
|
11 | .EQU MRQ_OUT=1
|
12 | .EQU SDA_OUT=2
|
13 | ;*************
|
14 |
|
15 | .EQU Sendtimeout=250
|
16 | .EQU Retries=3 ;Wie oft wird versucht ein Byte zu senden?
|
17 |
|
18 |
|
19 | Display:
|
20 |
|
21 | PUSH u1
|
22 | PUSH u2
|
23 | PUSH u3
|
24 | PUSH YL
|
25 | PUSH YH
|
26 |
|
27 |
|
28 | ;*******Init**********
|
29 |
|
30 |
|
31 | LDI u1,200 ;Pause vor dem Senden machen um nicht zu viele Daten zu senden
|
32 | PUSH u1
|
33 | RCALL XDelay
|
34 | POP u1
|
35 |
|
36 | ;**********Transfer-Init*******
|
37 |
|
38 | SBI DDRB, MRQ_OUT ;MRQ auf LOW ziehen; Transfer wird initiiert.
|
39 |
|
40 | LDI u1,150 ;Maximal 15000µs auf Reaktion vom TID warten
|
41 | WaitforSDALow:
|
42 | SBIS PINB,SDA_OUT ;Schaue ob das TID die Leitung auch auf 0 zieht, also reagiert. Falls nicht, verlängere die Pause
|
43 | RJMP SDAIsLow
|
44 | RCALL Delay
|
45 | DEC u1
|
46 | BRNE WaitforSDALow
|
47 | RJMP Endtrans ;Transfer Failed, exit
|
48 |
|
49 | SDAIsLow:
|
50 | RCALL Delay ;100µs warten, dann
|
51 | CBI DDRB, MRQ_OUT ;MRQ wieder HIGH
|
52 |
|
53 | LDI u1,30
|
54 | WaitforSDAHigh:
|
55 | SBIC PINB,SDA_OUT ;Warten bis SDA vom Slave wieder auf High gesetzt wird
|
56 | RJMP SDAIsHigh
|
57 | RCALL Delay
|
58 | DEC u1
|
59 | BRNE WaitforSDAHigh
|
60 | RJMP Endtrans ;Transfer Failed, exit
|
61 |
|
62 | SDAIsHigh:
|
63 | RCALL Delay
|
64 | ;100 Mikrosekunden warten
|
65 | SBI DDRB, SDA_OUT ;SDA auf LOW setzen
|
66 | RCALL Delay ;100 Mikrosekunden warten
|
67 | SBI DDRB, SCL_OUT ;Clock Leitung auf 0 ziehen
|
68 | RCALL Delay
|
69 |
|
70 | ;*********Slave-Addresse senden*********
|
71 |
|
72 |
|
73 | LDI u1,SlaveAddress ;Slave Addresse senden
|
74 | PUSH u1
|
75 | RCALL Send
|
76 | POP u1 ;Anzahl der Versuche checken
|
77 | CPI u1,Retries+1
|
78 | BRSH Endtrans ;falls 4 Versuche gebraucht wurden dann beende das Senden
|
79 |
|
80 | ;*****Symbole senden******
|
81 |
|
82 | SBI DDRB, MRQ_OUT ;MRQ auf LOW setzen ==> Beginn der Zeichensendungen
|
83 |
|
84 | CLR u2
|
85 | LDI YL,LOW(Symbol) ;Den Pointer auf die Symbole pointen lassen
|
86 | LDI YH,HIGH(Symbol)
|
87 | SendSymbolLoop:
|
88 |
|
89 | LD u1,Y ;Stelle lesen
|
90 | ST Y+, Null ;Stelle löschen (Register leeren)
|
91 |
|
92 | PUSH u1 ;auf den Stack schieben
|
93 | RCALL Send
|
94 | POP u1
|
95 | CPI u1, Retries+1 ;s.o.
|
96 | BREQ Endtrans
|
97 | INC u2
|
98 | CPI u2, Symbollength
|
99 | BRNE SendSymbolLoop
|
100 |
|
101 | ;*****Zeichen senden*******
|
102 |
|
103 | CLR u2
|
104 | LDI YL,LOW(String) ;Den Pointer auf die Zeichen pointen lassen
|
105 | LDI YH,HIGH(String)
|
106 | SendStringLoop:
|
107 |
|
108 | LD u1,Y ;Stelle lesen
|
109 | LDI u3,' ' ;Leerzeichen laden
|
110 | ST Y+, u3 ;Stelle löschen (Mit Leerzeichen füllen)
|
111 |
|
112 | PUSH u1 ;auf den Stack schieben
|
113 | RCALL Send
|
114 | POP u1
|
115 | CPI u1, Retries+1 ;s.o.
|
116 | BREQ Endtrans
|
117 | INC u2
|
118 | CPI u2, Stringlength
|
119 | BRNE SendStringLoop
|
120 |
|
121 |
|
122 | ;********Stop-Condition erzeugen*********
|
123 |
|
124 | Endtrans:
|
125 |
|
126 | CBI DDRB, SDA_OUT
|
127 | CBI DDRB, SCL_OUT
|
128 | SBI DDRB, MRQ_OUT
|
129 | RCALL DELAY
|
130 |
|
131 | SBI DDRB, SDA_OUT
|
132 | RCALL DELAY
|
133 | CBI DDRB, SCL_OUT
|
134 | RCALL DELAY
|
135 | CBI DDRB, SDA_OUT
|
136 | RCALL Delay
|
137 | CBI DDRB, MRQ_OUT
|
138 |
|
139 | ;***************************************
|
140 |
|
141 | POP YH
|
142 | POP YL
|
143 | POP u3
|
144 | POP u2
|
145 | POP u1
|
146 |
|
147 | RET
|
148 |
|
149 |
|
150 |
|
151 | Subroutinen:
|
152 | ;===========
|
153 |
|
154 | Send:
|
155 |
|
156 | PUSH u1
|
157 | PUSH u2
|
158 | PUSH u3
|
159 | PUSH u4
|
160 | PUSH YL
|
161 | PUSH YH
|
162 |
|
163 | IN YL, SPL ;Stackpointer in u2 schieben
|
164 | IN YH, SPH
|
165 | ADIW YL, 9 ;auf das Zeichen im SRAM zeigen
|
166 |
|
167 | ;******************
|
168 |
|
169 | CLR u4 ;Send-Retry-Counter
|
170 |
|
171 |
|
172 | GenerateParity:
|
173 |
|
174 | LD u1,Y ;Parameter aus dem SRAM holen
|
175 | LDI u3,8 ;Länge eines Datenbits wird pauschal auf 8 gesetzt.
|
176 | LSL u1 ;Das überflüssige Bit rausschieben.
|
177 | CLR u2 ;"Parity-Counter"
|
178 |
|
179 | SBRC u1,7 ;Ok - Ich geb zu dass dieses Modul nicht gerade die Perle der Programmierkunst ist,
|
180 | INC u2 ;Aber es funzt => Schöön :)
|
181 | SBRC u1,6
|
182 | INC u2
|
183 | SBRC u1,5
|
184 | INC u2
|
185 | SBRC u1,4
|
186 | INC u2
|
187 | SBRC u1,3
|
188 | INC u2
|
189 | SBRC u1,2
|
190 | INC u2
|
191 | SBRC u1,1
|
192 | INC u2
|
193 |
|
194 | SBRS u2,0
|
195 | SBR u1,1
|
196 |
|
197 |
|
198 |
|
199 | Sendbyte:
|
200 |
|
201 |
|
202 | SBI DDRB, SDA_OUT ;Die SDA-Leitung wird auf LOW gezogen.
|
203 | SBRC u1,7 ;Wenn das 7.Bit eine 0 ist, dann wird der nächste Befehl übersprungen
|
204 | CBI DDRB, SDA_OUT ;Ist er eine eins, dann wird der Befehl nicht übersprungen und die Leitung auf "High"
|
205 |
|
206 | RCALL Clkgen ;Die Uhr wird jetzt einmal fallen, einmal steigen und wieder einmal fallen lassen.
|
207 | ;Wenn das SCL-Signal HIGH ist, dann müssen laut I2C-Specs die Daten auf SDA gültig sein.
|
208 |
|
209 | LSL u1 ;Logical Shift left: Das 8. Bit wird rausgeschmissen und durch das folgende ersetzt.
|
210 | DEC u3 ;length zählt mit wie oft sich die Sendeschleife wiederholen muss!
|
211 | BRNE Sendbyte ;Solange zu SendAddress springen bis length=0
|
212 |
|
213 | CBI DDRB, SDA_OUT ;SDA auf "High" setzen => Ack abwarten
|
214 | RCALL Delay
|
215 |
|
216 | CBI DDRB, SCL_OUT
|
217 | CLR u3 ;u3 wird "Timeout-Counter"
|
218 | WaitforAcklow:
|
219 | INC u3 ;Wenn innerhalb einer bestimmten Zeitspanne nicht geantwortet wird dann
|
220 | CPI u3,Sendtimeout ;wiederhole die Übertragung
|
221 | BREQ RetrySendByte
|
222 | SBIC PINB,SDA_OUT ;Auf das Ack vom TID warten
|
223 | RJMP WaitforAcklow
|
224 | RCALL Delay
|
225 | SBI DDRB, SCL_OUT
|
226 | RCALL Delay
|
227 | RJMP Bytesent
|
228 |
|
229 | RetrySendByte:
|
230 | INC u4
|
231 | CPI u4,Retries+1 ;Anzahl der Versuche überprüfen
|
232 | BRNE GenerateParity ;Wenn 4 Versuche dann gib auf
|
233 |
|
234 | ;**************
|
235 |
|
236 | ByteSent:
|
237 |
|
238 | ST Y,u4 ;u4 wieder auf den Stack als Übergabeparameter schieben
|
239 |
|
240 | POP YH
|
241 | POP YL ;Werte wieder vom Stack holen
|
242 | POP u4
|
243 | POP u3
|
244 | POP u2
|
245 | POP u1
|
246 |
|
247 | RET
|
248 |
|
249 |
|
250 | Clkgen:
|
251 |
|
252 | SBI DDRB, SCL_OUT ;Die Uhr fängt mit LOW an
|
253 | RCALL Delay ;200us Low-Clock
|
254 | RCALL Delay
|
255 |
|
256 | CBI DDRB, SCL_OUT ;Clock auf High
|
257 | RCALL Delay ;100us warten
|
258 | SBI DDRB, SCL_OUT ;Clock wieder low
|
259 |
|
260 | RCALL Delay ;200us warten
|
261 | RCALL Delay
|
262 |
|
263 | RET
|