Display.asm


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