1 | ;ADDAhilf.a51**************************************** erweitert Jan2004
|
2 | ;************* Hilfsprogramme für den AD- und DA- Umsetzer mit I2C-Bus *****
|
3 | ;***************************************************************************
|
4 | code
|
5 | include C51RD2.inc
|
6 |
|
7 | ;****** verwendete Adressen und Abkürzungen für den AD- und DA-Umsetzter ***
|
8 | Adr_lies EQU 10010001b ;1001 fest, 000 durch Platine, 1 Wert lesen
|
9 | Adr_schreib EQU 10010000b ;1001 fest, 000 durch Platine, 0 Wert lesen
|
10 | Contr_Ain0 EQU 01000000b ;4 einzelne ADU, Kanal0
|
11 | Contr_Ain1 EQU 01000001b ;4 einzelne ADU, Kanal1
|
12 | Contr_Ain2 EQU 01000010b ;4 einzelne ADU, Kanal2
|
13 | Contr_Ain3 EQU 01000011b ;4 einzelne ADU, Kanal3
|
14 |
|
15 | delay EQU 10 ; Zeitverzögerung der Datenübertragung nach jedem Bit
|
16 | ; Normalwert 10, minimal 1 möglich = schneller
|
17 | ; diese Verzögerung wird nur wirksam bei $set (fast=0)
|
18 | $set (fast=0) ; maximale Schnelligkeit mit fast=1
|
19 |
|
20 | reg7 data 07 ; als Register verwendete Speicherstellen
|
21 | reg0 data 00
|
22 |
|
23 | ;****** hier die verwendeten I2C-Leitungen eintragen ************************
|
24 | daten EQU p3.5 ;SDA, i2c-Datenleitung
|
25 | clock EQU p3.4 ;SCL, i2c-Taktleitung
|
26 | ; Trigger: EQU p3.6 ;Hilfsausgang für das Oszilloskop
|
27 | ;***************************************************************************
|
28 |
|
29 | public Ain0,Ain1,Ain2,Ain3,Aout ; für normale Ein- und Ausgaben
|
30 | public initAD0,initAD1,initAD2,initAD3,ADin_fast,stoppAD ; für schnelle Eingaben
|
31 | public initDA,DAout_fast,stoppDA ; für schnelle Ausgaben
|
32 | public initi2c,starti2c,stoppi2c,ausgabei2c ; I2C-Bus-Routinen
|
33 | public einleseni2c_ohne_ack,einleseni2c_mit_ack
|
34 |
|
35 |
|
36 | ;******* Verwendung der Hilfsprogramme (Beispiele) ***************************
|
37 | ; Übergaberegister ist immer der Akku
|
38 | ; -------------- einfache Ein- und Ausgaben --------------------------
|
39 | ; lcall Ain0 ; Einlesen analoger Eingang 0 (0 bis 5V)
|
40 | ; mov P2,a ; Ausgeben des digitalisierten Wertes an P2
|
41 | ; mov a,P1 ; 8 Schalterstellungen einlesen und
|
42 | ; lcall Aout ; Ausgeben als Analogwert 0 bis 5V an Aout
|
43 | ; -------------- schnelle Eingaben ----------------------------------
|
44 | ; mov r0,#80h ; Anfangsadresse int. RAM
|
45 | ; lcall initAD0 ; Analogeingang0 initialisieren
|
46 | ;in: lcall ADin_fast ; einen Analogwert einlesen
|
47 | ; mov @r0,a ; Wert im RAM ablegen
|
48 | ; inc r0 ; nächste Speicherstelle
|
49 | ; cjne r0,#0ffh,in ; Endwert?
|
50 | ; lcall stoppAD ; Ende AD-Protokoll
|
51 | ; -------------- schnelle Ausgaben ---------------------------------
|
52 | ; mov r0,#80h ; Anfangsadresse int. RAM
|
53 | ; lcall initDA ; Analogausgang initialisieren
|
54 | ;out: mov a,@r0 ; Wert aus RAM holen
|
55 | ; lcall DAout_fast ; als Analogwert ausgeben
|
56 | ; inc r0 ; nächste Speicherstelle
|
57 | ; cjne r0,#0ffh,out; Endwert?
|
58 | ; lcall stoppDA ; Ende DA-Protokoll
|
59 |
|
60 | ;************ Analoge Eingänge einlesen ***************************
|
61 | Ain0: mov a,#Contr_Ain0 ;Controll-Byte Kanal0
|
62 | lcall Ain
|
63 | ret
|
64 | Ain1: mov a,#Contr_Ain1 ;Controll-Byte Kanal1
|
65 | lcall Ain
|
66 | ret
|
67 | Ain2: mov a,#Contr_Ain2 ;Controll-Byte Kanal2
|
68 | lcall Ain
|
69 | ret
|
70 | Ain3: mov a,#Contr_Ain3 ;Controll-Byte Kanal3
|
71 | lcall Ain
|
72 | ret
|
73 |
|
74 | Ain:
|
75 | lcall initAD ; Analogeingang initialisieren
|
76 | lcall einleseni2c_ohne_ack ; Wert holen und einlesen beenden
|
77 | lcall stoppi2c ; Protokoll beenden
|
78 | ret
|
79 |
|
80 | initAD0:
|
81 | push acc
|
82 | mov a,#Contr_Ain0 ;Controll-Byte Kanal0
|
83 | lcall initAD
|
84 | pop acc
|
85 | ret
|
86 | initAD1:
|
87 | push acc
|
88 | mov a,#Contr_Ain1 ;Controll-Byte Kanal1
|
89 | lcall initAD
|
90 | pop acc
|
91 | ret
|
92 | initAD2:
|
93 | push acc
|
94 | mov a,#Contr_Ain2 ;Controll-Byte Kanal2
|
95 | lcall initAD
|
96 | pop acc
|
97 | ret
|
98 | initAD3:
|
99 | push acc
|
100 | mov a,#Contr_Ain3 ;Controll-Byte Kanal3
|
101 | lcall initAD
|
102 | pop acc
|
103 | ret
|
104 |
|
105 | initAD: ; Analogeingang initialisieren
|
106 | push acc
|
107 | push acc ; Controll-Byte mit Kanalnummer retten
|
108 | lcall initI2C ; Initialisierung der Leitungen (Grundzustand)
|
109 | lcall starti2c ; Startbedingung des I2C-Bus: Jetzt gehts los
|
110 | mov a,#Adr_schreib ; Adresse des IC und Schreibwunsch (zur Kanalwahl)
|
111 | lcall ausgabei2c ; ausgeben
|
112 | pop acc ; Controll-Byte mit Kanalnummer
|
113 | lcall ausgabei2c ; ausgeben
|
114 | lcall stoppi2c
|
115 | lcall starti2c
|
116 | mov a,#Adr_lies ; Adresse des IC und Lesewunsch
|
117 | lcall ausgabei2c ; ausgeben
|
118 | lcall einleseni2c_mit_ack ; Wandlung starten
|
119 | pop acc
|
120 | ret
|
121 |
|
122 | ;ADin_fast siehe unten wie einleseni2c_ohne_ack
|
123 |
|
124 | stoppAD: ; Ende AD-Protokoll
|
125 | push acc
|
126 | lcall einleseni2c_ohne_ack ; Ende dem I2c-IC mitteilen
|
127 | lcall stoppi2c
|
128 | pop acc
|
129 | ret
|
130 |
|
131 | Aout: ; Analoge Ausgabe
|
132 | lcall initDA ; mit Initialisierung
|
133 | lcall DAout_fast
|
134 | lcall stoppDA ; und Abschluss des Protokolls
|
135 |
|
136 | initDA: ; Analogausgang initialisieren
|
137 | push acc
|
138 | lcall initi2c
|
139 | lcall starti2c
|
140 | mov a,#Adr_schreib
|
141 | lcall ausgabei2c
|
142 | mov a,#Contr_Ain0
|
143 | lcall ausgabei2c
|
144 | pop acc
|
145 | ret
|
146 | ; DAout_fast wie ausgabei2c siehe unten
|
147 | ; stoppDA wie stoppi2c siehe unten
|
148 |
|
149 | initI2C: ;Leitungen in den Grundzustand High
|
150 | setb Daten
|
151 | setb Clock
|
152 | lcall warte
|
153 | ret
|
154 |
|
155 | starti2c: ;Startbedingung
|
156 | ;setb Trigger
|
157 | ;nop
|
158 | ;clr Trigger
|
159 | clr daten
|
160 | lcall warte
|
161 | clr clock
|
162 | lcall warte
|
163 | ret
|
164 |
|
165 | ;*********** Byte im Akku ausgeben ****************************************
|
166 | ;*********** Adressen- oder Datenausgabe **********************************
|
167 | ;*********** Acknoledge-Bit = Carry nach Up-Ende **************************
|
168 | DAout_fast:
|
169 | ausgabei2c:
|
170 | push reg7
|
171 | mov reg7,#08h ;Rundenzähler
|
172 | aloop:
|
173 | mov c,acc.7 ;Datenbit aus Akku holen
|
174 | mov daten,c ;und ausgeben
|
175 | lcall warte
|
176 | setb clock ;Daten sind gültig
|
177 | rl a ;Daten links schieben => nächstes Datenbit
|
178 | lcall warte
|
179 | clr clock ;Datenausgabe ist beendet
|
180 | lcall warte
|
181 | djnz reg7,aloop
|
182 | setb daten ;Leitung freigeben (high) für Acknowledge-Bit
|
183 | lcall warte
|
184 | setb clock ;Slave kann bestätigen
|
185 | lcall warte
|
186 | mov c,daten ;Acknoledge-Bit einlesen
|
187 | clr clock ;
|
188 | pop reg7
|
189 | ret
|
190 |
|
191 | ADin_fast: ; Wert der letzten Wandlung holen, steht dann im Akku
|
192 | einleseni2c_mit_ack:
|
193 | lcall lies8bit ;Datenbyte der letzten Wandlung lesen und Konvertierung des neuen Datenbytes starten
|
194 | clr daten ;Acknowledge-Bit senden
|
195 | lcall warte
|
196 | setb clock ;Ackn. gültig
|
197 | lcall warte
|
198 | clr clock ;Ackn. beendet
|
199 | ;clr daten
|
200 | ret
|
201 |
|
202 | einleseni2c_ohne_ack: ; kein Ack kündigt dem IC an, dass dies die letzte Wandlung war
|
203 | lcall lies8bit ;aktuelles Datenbyte lesen
|
204 | setb daten ;kein Acknowledge-Bit senden, dies ist das letzte Datenbyte
|
205 | lcall warte
|
206 | setb clock ;Ackn. gültig
|
207 | lcall warte
|
208 | clr clock ;Ackn. beendet
|
209 | lcall warte
|
210 | clr daten
|
211 | ret
|
212 |
|
213 | ;einleseni2c: ; alte Routine, wird nicht mehr gebraucht
|
214 | ; lcall einleseni2c_mit_ack ;DA-Wandlung startet
|
215 | ; lcall einleseni2c_ohne_ack ;Wert abholen und Ende des Zugriffs ankündigen
|
216 | ; ret
|
217 |
|
218 | lies8bit: ;8Bit seriell einlesen und im Akku ablegen
|
219 | push reg7
|
220 | setb daten ;Leitung freigeben (high) für Daten
|
221 | mov reg7,#08h ;Rundenzähler
|
222 | eloop:
|
223 | setb clock ;Daten sind gültig
|
224 | lcall warte
|
225 | mov c,daten ;lesen
|
226 | mov acc.7,c ;Datenbit in den Akku
|
227 | rl a ;Daten links schieben => nächstes Datenbit
|
228 | lcall warte
|
229 | clr clock ;Daten lesen ist beendet
|
230 | lcall warte
|
231 | djnz reg7,eloop
|
232 | pop reg7
|
233 | ret
|
234 |
|
235 | stoppDA:
|
236 | stoppi2c:
|
237 | setb clock ;Stoppbedingung
|
238 | lcall warte
|
239 | setb daten
|
240 | lcall warte
|
241 | ret
|
242 |
|
243 | warte : ;Zeitverzögerung
|
244 | $if (fast=1)
|
245 | ret
|
246 | $else
|
247 | push reg0
|
248 | mov reg0,#delay
|
249 | wloop:
|
250 | djnz reg0,wloop
|
251 | pop reg0
|
252 | ret
|
253 | $endif
|
254 |
|
255 | end
|