Offensichtlich ist mein Problem so trivial, dass ich nichts darüber finde. Der Temperaturfühler TSic 506 sendet in Abständen von ca. 3ms seine 2 Bytes langen Daten seriell auf einer Datenleitung. (mit 8kHz). Die Datenleitung soll bei mir an P2.5 des MSP430 angeschlossen sein. Und jetzt mein Problem: Wie kriege ich die ankommenden Nullen und Einsen seriell in einen Puffer, um dann diese weiterverarbeiten zu können. Als Ansatz hatte ich mir gedacht, ich definiere eine Variable, und schiebe den Inhalt der Variablen nach jedem Takt um eine Stelle nach links. Aber wie kann ich P2.5 abfragen, ob dort eine Null oder Eins steht und diesen Wert mit der Variablen so verknüpfen, dass die kompletten Daten nach Empfang von 2 Bytes in der Variablen stehen? Oder wie macht man es richtig? Programmierung in C. MfG Wolfgang
Hmm...da haste dir ja einen Sensor ausgesucht. 11 Bit Single Wire Output für State of the Art µControllers. Ohje. Eventuell lässt sich was über die UART machen, die irgendwie missbrauchen. Aber das wird alles schwierig. Du musst ja den Takt auch irgendwie rückgewinnen. Gibts da nen komplettes Datenblatt irgendwo? Kannst du mal verlinken?
Eine Möglichkeit ist die von dir beschriebene. Das heißt, einzeln im Takt von 8kHz den Pinzustand abfragen und immer ein weiter nach links schieben. Nach 16 Takten hast du dann dein fertigen Wert stehen. Wenn du noch frei in der Pinanordnung bist, würde ich persönlich eine Hardware-SPI Schnittstelle verwenden. Dann übernimmt der MSP für dich das schieben und zusammensetzen. Viele Grüße Michael
Hier geht es zum Datenblatt http://www.zmd.biz/temp.php?group=temp&content=products den TSic 506 habe ich mir als „Referenznormal“ beschafft. Die Fehler soll bei < 0,1° liegen. Es muss P2.5 als Eingang für den seriellen Datenstrom verwendet werden, da meine Leiterplatte als Datenschreiber fertig ist und der Temperaturfühler nur angeschlossen werden soll. Da eine serieller Anschluss häufiger mal gebraucht wird (z.B. 1wire) , möchte ich gleichzeitig auch noch etwas dazulernen Von ZMD gibt es ein Programmbeispiel in C für einen 8051, welches ich leider nicht richtig verstehe. Deshalb würde ich noch mal meine Kernfrage in den Raum stellen: Wie fragt man den Eingang P2.5 ab, ob dort eine logische 1 oder Null steht und wie verknüpft man das Ergebnis mit einem Puffer? Oder wie kann man es unter den vorgegeben Bedingungen besser machen? Mit freundlichen Grüßen Wolfgang
Im Wesentlichen würde das so aussehen: Messwert = Messwert << 1; if (P2IN&0x20) Messwert |= 0x01; Diesen Code müsstest du im 8 kHz Takt aufrufen. Viele Grüße Michael
Naja, das ist doch kein komplettes Datenblatt. Da steht nix zum Timing usw. drin. Schon ein seltsames Teil. Seh ich das richtig, dass er alle 3ms einfach so seine 11 Bit rausfeuert? Ohne extra Takt, ohne Kodierung ohne alles? Was soll´n das für ein Unsinn sein. Du müsstest dich ja irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig. Wenn man das erste Bit hat, kann man mit einem Timer-Int abtasten, keine Frage. Die Synchronisierung ist halt tricky. Gibts da kein richtiges Datenblatt? In dem 6-Seiten-Wisch steht ja nix drinne....
Hmmm, hab mal bei dem Link gesucht, unter http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Digital%20Output_17-Oct-06.pdf steht die Beschreibung zum Protokoll. Ist schon etwas abartig, aber mit dem MSP wohl machbar. Also, wie in der Beschreibung mal folgendes testen: 1. Einen Timer mit 125kHz takten 2. Das Ausgangssignal auf einen interruptfähigen Eingang führen und so konfigurieren, dass bei negativer Flanke die ISR ausgeführt wird. 3. Timerwert (T1) beim Einsprung merken 4. In der ISR solange den Eingang pollen, bis er auf high geht. Timerwert (T2) merken und Differenz zu T1 bilden. Dabei kommt dT heraus. 5. Damit hast Du die "Strobe" Time beim Startbit ermittelt 6. Beim nächsten Einsprung in die ISR Timerwert (T3) wieder merken, T4 = T3+dT berechnen. Warten, bis der Timer T4 erreicht hat 7. In diesem Moment auf den Eingang schauen (am besten dreimal mit Majoritaetsenscheidung). Ist er high, hat der Sensor eine 1 ausgegeben, ist er 0, dann hat er eine 0 ausgegeben. 8. Nacheinander in dieser Art und Weise die Bits aufsammeln. Nach 21 Bits (inclusive Startbit) ist ein Telegramm komplett und Du fängst wieder bei 1. an Was die ISR-Last betrifft, er ist bei einem Telegramm (2,65ms) die Hälfte dieser Zeit in der ISR (1,3ms) beschäftigt. Bei einem Zyklus von 100ms ist das eine CPU-Belastung von ca. 1,3%. Geht also noch (ich hoffe mal ich hab mich nicht arg verrechnet). In der Beschreibung kommen die auf Doppelte. Weiss allerdings nicht, warum. Probiere es halt mal aus. Schoene Aufgabe, würde ich auch gerne machen, sicherlich interessant.
Christian R. wrote: > Ohne extra Takt, ohne Kodierung > ohne alles? Was soll´n das für ein Unsinn sein. Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso, nur schneller, 8KHz statt 1Hz. > Du müsstest dich ja > irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man > ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig. 125µs lang high: Startbit folgt. 125µs lang low: Startbit isses. Hat man einen capture-fähigen Timer, der auf beide Flanken reagieren kann, oder den man entsprechend umschaltet, ist das problemlos so nebenher zu erledigen. Aber bei dem dezenten Timing tut's ggf. auch ein externer Interrupt, wie oben beschrieben. Nur sollte die Interrupt-Latenzzeit dann unbedingt angenehm kurz bleiben.
Zunächst einmal an alle vielen Dank. Ich denke mal, dass ich jetzt ein Stück weiterkomme und werde zunächst mal mit Supa Michas Programmschnipsel beginnen, falls dies der dafür gängige und einzige Weg ist, einen seriellen Datenstrom an einem Eingang zu erfassen. @szimmi Wenn ich es richtig verstanden habe, wird in dem von Dir zitierten Artikel eine weitere Möglichkeit beschrieben. Der Fühler wird über einen µC Ausgang zu- und abgeschaltet. Nach dem Zuschalten des Fühlers wartet man auf die fallende Flanke des Starbits auf der Datenleitung und hat somit den Anfang des Telegramms. Mal sehen, ob das so geht. Mit freundlichen Grüßen Wolfgang
Nein,da habe ich mich wohl missverständlich ausgedrückt. Der Sensor wird nur über eine Signalleitung mit einem Eingang des µC verbunden. Der Sensor wird nicht zu- oder abgeschaltet.
Andreas Kaiser wrote: > Christian R. wrote: > >> Ohne extra Takt, ohne Kodierung >> ohne alles? Was soll´n das für ein Unsinn sein. > > Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert > hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso, > nur schneller, 8KHz statt 1Hz. Jo, is schon recht. Da kannte ich das vollständige Datenblatt noch nicht.
@szimmi Wahrscheinlich noch ein Missverständnis. Ich meinte den angehängten Artikel. Lt. Abschnitt 1.4.2 erfolgt hier die Stromversorgung des Fühlers vom µC aus. Der Stromverbrauch ist so gering, dass er von einem Ausgang des µC versorgt werden kann. 65ms bis 85ms nach dem Zuschalten des Fühlers beginnt der Fühler mit dem Senden des ersten Temperaturtelegramms. So habe ich es verstanden. Mit freundlichen Grüßen Wolfgang Gröbel
Wo ist denn da jetzt eigentlich das Problem? Ein C-Code wird von ZMD ja schon zur verfügung gestellt. Einfach passend anwandeln und gut. Ein Source Code für den TSic für MSP430 hab ich mal in den Anhang gepackt.
Here is a sample code, based on the C++ code from the datasheet mentioned above. Works well with atmega8 and avr-gcc compiler.
Du könntest über capture-and-compare so weine Art Software-UART implementieren. Beispielcodes dafür gibts jede Menge.
Hallo, Habe mal versucht den Code für einen PIC 16F876A umzustricken. Leider ist bei dem zweiten Byte der ParityCheck immer FAIL und die Temperatur wird um 10,00°C zu wenig angezeigt. Allersings verstehe ich dieses Verhakten absolut nicht!! Hat jemand eine Idee???? Bin am Verzweifeln martin
vielleicht hast Du 10° zweimal abgezogen lt. Datenblatt: Temp.= DigitalSignal/2047*70 -10
Welchen TSic hast du? Der 506er hat ein anderes Datenformat als die kleineren.
Guten Abend. Ich versuche z.Z einen TSIC 306 zum laufen zu bringen. atm verwende ich dazu das von Robert K. gepostete programm (zwei drei posts über meinem) folgendes verstehe ich aber nicht. temperatur ist eine 16bit unsigned integer variable...was bedeutet das float davor? in diese variable wird der tempsensor output geladen bei 25°C sind das 0x2FF der sensor sendet immer 11bit pakete
1 | Temp_celsius = ((float)temperatur / 2047 * 200) - 50; |
temper hier das ganze im kontext.
1 | int main (void) { |
2 | |
3 | uint16_t temperatur; // 11-bit temperature value |
4 | uint8_t returnvalue; // return value of getTSicTemp(*temp); |
5 | uint8_t Temp_celsius; // converted temperature in °C |
6 | |
7 | TSIC_INIT(); // set data direction of IO-Pins |
8 | |
9 | |
10 | while(1){ |
11 | |
12 | returnvalue = getTSicTemp(&temperatur); // pull the TSIC-Sensor |
13 | |
14 | // conversion equation from TSic's data sheet |
15 | Temp_celsius = ((float)temperatur / 2047 * 200) - 50; |
>temperatur ist eine 16bit unsigned integer variable...was bedeutet das >float davor? Das von unsigned int auf float "gecastet" (gewandelt) wird.
gut, die rechnung läuft dann mit nachkommastellen ab... aaaber: was passiert dann? dann wird eine kommazahl auf ein uint8_t variable geschrieben? oder wirkt sich der cast auch irgendwie auf die Temp_celsius aus?
> dann wird eine kommazahl auf ein uint8_t variable geschrieben? Ja >oder wirkt sich der cast auch irgendwie auf die Temp_celsius aus? Nein
und wie sieht das im klartext aus, wenn eine kommazahl auf einen integer geschrieben wird? wird die kommazahl einfach abgerundet? mich wundert das es überhaupt möglich ist und der compiler keinen terror schiebt :/
danke jörg habs jetzt am laufen :) die angezeigte temp. macht mich zwar etwas stutzig (ich glaube 1 bis 2°C zuviel) aber das sollte nur ein kleines problem sein
Guten Abend, wenn ich hier einfach mal Anknüpfen darf. Bin nun schon seit einiger Zeit am probieren, den TSIC 306 zum laufen zu bringen, allerdings zeigt dieser mir nur Scheiße auf dem LCD an :( Erstmal die Codeschnipsel: Hauptprogramm:
1 | // Definitionen
|
2 | // lcd-anschlussbelegung
|
3 | #define LCD_PORT PORTC
|
4 | #define LCD_DDR DDRC
|
5 | |
6 | #define LCD_DB PC0
|
7 | #define LCD_E PC4
|
8 | #define LCD_RS PC5
|
9 | |
10 | // INCLUDE
|
11 | #include <avr/io.h> |
12 | #include <avr/interrupt.h> |
13 | #include <util/delay.h> |
14 | #include <stdint.h> |
15 | #include "lcd_steuerung.h" |
16 | #include "tempsensor_ansteuerung.h" |
17 | |
18 | // MAIN
|
19 | void main (void) |
20 | |
21 | {
|
22 | lcd_init(); |
23 | |
24 | // Temperturmessung mit TSIC ausführen und Daten auf dem LCD ausgeben
|
25 | while(1) |
26 | {
|
27 | unsigned char parity = 0; // referenz für 2. übergabewert |
28 | uint16_t wert = 0; |
29 | lcd_string("WERT:;"); |
30 | wert = temp_messung(&parity); //temp_byte = übergabe |
31 | lcd_zahl_16(wert); |
32 | lcd_cursor(0,2); |
33 | lcd_string("parity:;"); |
34 | lcd_zahl_8(parity); |
35 | _delay_ms(500); |
36 | lcd_befehl(1); |
37 | |
38 | //ende while
|
39 | //33246 bei 20°C
|
40 | }
|
41 | |
42 | |
43 | |
44 | while(1){}; |
45 | |
46 | |
47 | }
|
LCD-Ansteuerung:
1 | // LCD_FUNKTIONEN
|
2 | /* ansteuerung eines LC-Displays im 4bit modus.
|
3 | Wartezeiten nach Datenblatt, Pinbelegung einsellbar.
|
4 | |
5 | |
6 | // Definitionen
|
7 | // lcd-anschlussbelegung
|
8 | #define LCD_PORT PORTC
|
9 | #define LCD_DDR DDRC
|
10 | |
11 | #define LCD_DB PC0
|
12 | #define LCD_E PC4
|
13 | #define LCD_RS PC5
|
14 | */
|
15 | |
16 | // lcd-Befehle
|
17 | |
18 | // clear display----------------0b00000001
|
19 | #define lcd_display_löschen 0x01
|
20 | |
21 | // cursor bewegen
|
22 | #define LCD_CURSOR_HOME 0x02
|
23 | |
24 | // DDRAM - Adresse festelgen
|
25 | #define LCD_DDRAM 0x80
|
26 | |
27 | /* lcd-adressen für die Zeilen
|
28 | angaben sind für ein 4x20 Zeichen lcd.
|
29 | bei anderen auflösungen müssen die werte angepasst werden.
|
30 | */
|
31 | #define lcd_cursor_1zeile 0x00
|
32 | #define lcd_cursor_2zeile 0x40
|
33 | #define lcd_cursor_3zeile 0x14
|
34 | #define lcd_cursor_4zeile 0x54
|
35 | |
36 | ///////////////////////////////////////////
|
37 | // LCD-INITIALISIEREN
|
38 | void lcd_init(void) |
39 | |
40 | {
|
41 | unsigned char zaehler = 1; |
42 | LCD_DDR = 0xff; // PORTC = ausgang |
43 | _delay_ms(15); // 15 ms warten |
44 | LCD_PORT = 0x3; // PORTC = 0x03 |
45 | while(zaehler <= 3) // 3-mal enable |
46 | {
|
47 | lcd_enable(); //enable |
48 | zaehler++; //Zähl-Variable +1 |
49 | }
|
50 | // 4-bit modus
|
51 | LCD_PORT = 0x2; |
52 | lcd_enable(); |
53 | |
54 | // 4-bit, 2-Zeilig, 5x8 matrix
|
55 | lcd_befehl(0x28); |
56 | |
57 | // display ein, cursor aus, blinken aus
|
58 | lcd_befehl(0x0f); |
59 | |
60 | //cursor inkrement, kein scrollen
|
61 | lcd_befehl(0x06); |
62 | |
63 | //lcd löschen
|
64 | lcd_befehl(0x01); |
65 | |
66 | }
|
67 | |
68 | ///////////////////////////////////////////
|
69 | // LCD_ENABLE
|
70 | void lcd_enable(void) |
71 | |
72 | {
|
73 | LCD_PORT |= ( 1 << LCD_E ); //E-Setzen |
74 | _delay_us(50); //50µS warten |
75 | LCD_PORT &= ~( 1 << LCD_E ); //E-rücksetzen |
76 | _delay_ms(5); //5ms warten |
77 | }
|
78 | |
79 | ///////////////////////////////////////////
|
80 | // LCD DATEN senden
|
81 | void lcd_daten(uint8_t data) |
82 | |
83 | {
|
84 | LCD_PORT |= (1 << LCD_RS); //RS setzen |
85 | uint8_t u_nibble = data & 0x0f; //unteres nibble |
86 | data &= 0xf0; //nur die obersten 4 bit maskieren |
87 | LCD_PORT &= ~(0xf0 >> (4-LCD_DB)); //untere 4 bits löschen |
88 | LCD_PORT |= (data >> (4-LCD_DB)); //obere 4 bits ausgeben |
89 | lcd_enable(); //enable |
90 | LCD_PORT &= ~(0xf0 >> (4-LCD_DB)); //untere 4 bits löschen |
91 | LCD_PORT |= u_nibble; //untere 4 bit ausgeben |
92 | lcd_enable(); //enable |
93 | }
|
94 | |
95 | ///////////////////////////////////////////
|
96 | // LCD BEFEHL senden
|
97 | void lcd_befehl(uint8_t data) |
98 | |
99 | {
|
100 | |
101 | LCD_PORT &= ~( 1 << LCD_RS); //RS löschen |
102 | uint8_t u_nibble = data & 0x0f; //unteres nibble |
103 | data &= 0xf0; //nur die obersten 4 bit maskieren |
104 | LCD_PORT &= ~(0xf0 >> (4-LCD_DB)); //untere 4 bits löschen |
105 | LCD_PORT |= (data >> (4-LCD_DB)); //obere 4 bits ausgeben |
106 | lcd_enable(); //enable |
107 | LCD_PORT &= ~(0xf0 >> (4-LCD_DB)); //untere 4 bits löschen |
108 | LCD_PORT |= u_nibble; //untere 4 bit ausgeben |
109 | lcd_enable(); |
110 | |
111 | }
|
112 | |
113 | ///////////////////////////////////////////
|
114 | // LCD_STRING ausgeben
|
115 | void lcd_string(const char *data) |
116 | |
117 | {
|
118 | while( *data != ';' ) |
119 | lcd_daten( *data++ ); |
120 | }
|
121 | |
122 | ///////////////////////////////////////////
|
123 | // lcd-cursor postition; x = zeile/horizont, y = spalte/vertikal
|
124 | void lcd_cursor(uint8_t x, uint8_t y) |
125 | |
126 | {
|
127 | uint8_t zeile; |
128 | switch(y) |
129 | {
|
130 | case 1: // 1 Zeile |
131 | lcd_befehl(LCD_CURSOR_HOME); |
132 | zeile = LCD_DDRAM + lcd_cursor_1zeile + x; |
133 | lcd_befehl(zeile); |
134 | break; |
135 | |
136 | case 2: // 2 Zeile |
137 | lcd_befehl(LCD_CURSOR_HOME); |
138 | zeile = LCD_DDRAM + lcd_cursor_2zeile + x; |
139 | lcd_befehl(zeile); |
140 | break; |
141 | |
142 | case 3: // 3 Zeile |
143 | lcd_befehl(LCD_CURSOR_HOME); |
144 | zeile = LCD_DDRAM + lcd_cursor_3zeile + x; |
145 | lcd_befehl(zeile); |
146 | break; |
147 | |
148 | case 4: // 4 Zeile |
149 | lcd_befehl(LCD_CURSOR_HOME); |
150 | zeile = LCD_DDRAM + lcd_cursor_4zeile + x; |
151 | lcd_befehl(zeile); |
152 | break; |
153 | |
154 | default: // eine falsche angabe. |
155 | return; |
156 | }
|
157 | }
|
158 | |
159 | ///////////////////////////////////////////
|
160 | // 8-bit Zahl in ASCII umwandel und gleich auf dem LCD ausgeben
|
161 | void lcd_zahl_8(uint8_t zahl) |
162 | {
|
163 | if(zahl < 0) |
164 | {
|
165 | uint8_t zaehler; |
166 | //100er
|
167 | while( zahl > -99) |
168 | {
|
169 | zahl += 100; |
170 | zaehler++; |
171 | }
|
172 | if(zaehler != 0) |
173 | {
|
174 | zaehler += 0x30; |
175 | lcd_daten(zaehler); |
176 | }
|
177 | zaehler = 0; |
178 | |
179 | //10er
|
180 | while( zahl > -9) |
181 | {
|
182 | zahl += 10; |
183 | zaehler++; |
184 | }
|
185 | if(zaehler != 0) |
186 | {
|
187 | zaehler += 0x30; |
188 | lcd_daten(zaehler); |
189 | }
|
190 | |
191 | //einer
|
192 | zahl += 0x30; |
193 | lcd_daten(zahl); |
194 | }
|
195 | uint8_t zaehler; |
196 | //100er
|
197 | while( zahl > 99) |
198 | {
|
199 | zahl -= 100; |
200 | zaehler++; |
201 | }
|
202 | if(zaehler != 0) |
203 | {
|
204 | zaehler += 0x30; |
205 | lcd_daten(zaehler); |
206 | }
|
207 | zaehler = 0; |
208 | |
209 | //10er
|
210 | while( zahl > 9) |
211 | {
|
212 | zahl -= 10; |
213 | zaehler++; |
214 | }
|
215 | if(zaehler != 0) |
216 | {
|
217 | zaehler += 0x30; |
218 | lcd_daten(zaehler); |
219 | }
|
220 | |
221 | //einer
|
222 | zahl += 0x30; |
223 | lcd_daten(zahl); |
224 | }
|
225 | |
226 | ///////////////////////////////////////////
|
227 | // 16-bit Zahl in ASCII umwandel und gleich auf dem LCD ausgeben
|
228 | void lcd_zahl_16(uint16_t zahl) |
229 | {
|
230 | uint8_t zaehler; |
231 | //10000er
|
232 | while( zahl > 9999) |
233 | {
|
234 | zahl -= 10000; |
235 | zaehler++; |
236 | }
|
237 | if(zaehler != 0) |
238 | {
|
239 | zaehler += 0x30; |
240 | lcd_daten(zaehler); |
241 | }
|
242 | zaehler = 0; |
243 | |
244 | //1000er
|
245 | while( zahl > 999) |
246 | {
|
247 | zahl -= 1000; |
248 | zaehler++; |
249 | }
|
250 | if(zaehler != 0) |
251 | {
|
252 | zaehler += 0x30; |
253 | lcd_daten(zaehler); |
254 | }
|
255 | zaehler = 0; |
256 | |
257 | //100er
|
258 | while( zahl > 99) |
259 | {
|
260 | zahl -= 100; |
261 | zaehler++; |
262 | }
|
263 | if(zaehler != 0) |
264 | {
|
265 | zaehler += 0x30; |
266 | lcd_daten(zaehler); |
267 | }
|
268 | zaehler = 0; |
269 | |
270 | //10er
|
271 | while( zahl > 9) |
272 | {
|
273 | zahl -= 10; |
274 | zaehler++; |
275 | }
|
276 | if(zaehler != 0) |
277 | {
|
278 | zaehler += 0x30; |
279 | lcd_daten(zaehler); |
280 | }
|
281 | |
282 | //einer
|
283 | zahl += 0x30; |
284 | lcd_daten(zahl); |
285 | }
|
und die wohl wichtigste Datei, Sensoransteuerung:
1 | // TSIC 306
|
2 | #define steigende_flanke (PINB & (1 << PB2)) // steigende Flanke bzw. high
|
3 | #define fallende_flanke !(PINB & (1 << PB2)) // fallende Flanke bzw. low
|
4 | #define tsic_on PORTB |= (1 << PB1) // Sensor einschalten
|
5 | #define tsic_off PORTB &= ~(1 << PB1) // Sensor ausschalten
|
6 | #define tsic_delay_us 1 // Flankenzeit des TSIC
|
7 | |
8 | unsigned int temp_messung(unsigned char *parity_byte) |
9 | {
|
10 | |
11 | uint16_t temp_byte = 0; |
12 | //tempsensor ansteuerung
|
13 | //Sensor starten und auf fallende flanke warten
|
14 | DDRB = ((1 << PB1) | (1 << PB0)); // PB0, PB1 = eingang |
15 | |
16 | tsic_on; |
17 | _delay_ms(40); // Sensor einschalten |
18 | |
19 | while (fallende_flanke); // warte auf fallende Flanke |
20 | |
21 | while (steigende_flanke); // auf steigende Flanke warten |
22 | |
23 | for (uint8_t i = 0; i < 8; i++) // hier nun Bits auswerten |
24 | {
|
25 | while (fallende_flanke); // warten bis zum ersten bit. |
26 | _delay_us(tsic_delay_us); // 60µSekunden warten |
27 | if (steigende_flanke) // wenn eingang 1, |
28 | temp_byte |= 1 << (15-i); // dann bit schreiben |
29 | else // wenn nicht, |
30 | while (steigende_flanke); // dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1. |
31 | }
|
32 | |
33 | // parity auswerten bzw. erstmal abwarten
|
34 | while (fallende_flanke); // Parity_bit |
35 | _delay_us(tsic_delay_us); // 60µs warten |
36 | if (steigende_flanke) |
37 | *parity_byte |= 1 << 1; // wenn parity = 1, dann eine 1. eine stelle nach links schieben |
38 | else while (steigende_flanke); // wenn parity_byte = 0, dann warten bis flanke wieder steigt |
39 | |
40 | // stoppbit absitzen
|
41 | while (fallende_flanke); // stop bit |
42 | |
43 | // startbit absitzen
|
44 | while (steigende_flanke); // start bit |
45 | |
46 | // 2 byte LSB
|
47 | for (uint8_t i = 0; i < 8; i++) // hier nun Bits auswerten |
48 | {
|
49 | while (fallende_flanke); // warten bis zum ersten bit. |
50 | _delay_us(tsic_delay_us); // 60µSekunden warten |
51 | if (steigende_flanke) // wenn eingang 0, |
52 | temp_byte |= 1 << (7-i); // dann bit schreiben |
53 | else // wenn nicht, |
54 | while (steigende_flanke); // dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1. |
55 | }
|
56 | // parity auswerten bzw. erstmal abwarten
|
57 | while (fallende_flanke); // Parity_bit |
58 | _delay_us(tsic_delay_us); // 60µs warten |
59 | if (steigende_flanke) |
60 | *parity_byte |= 1 << 0; // wenn parity = 1, dann eine 1. 0 stellen nach links schieben |
61 | |
62 | tsic_off; // Sensor ausschalten |
63 | |
64 | return temp_byte; // gemessenen Wert zurückgeben |
65 | }
|
Ich verwende aktuell im "main"-Abschnitt die direkte Wert-Ausgabe, d.h. er zeigt mir den eingelesenen Wert direkt an. Da kommt aber absoluter Mist raus. Verändere ich die T-strobe Zeit auf 1 µS, so zeigt er mir 65471 an, wobei nach meinem Verständnis hier 0 angezeigt werden sollte. Allgemein kommt mit jeder anderen Wartezeit ein anderer Wert raus und ich kapier einfach nicht warum. Der Code ist stark an den im Datenblatt angegebenen angelehnt. Vielleicht kann ja mal jemand schnell drüber schauen ob er einen Fehler findet. Oder besser jemand hat mal ein Digitaloszi an den Sensor gehangen und kann mir beschreiben, wie der genaue Ablauf zwischen dem 1. und 2. Byte mit Stop/Start-Bit vonstatten geht. Die LCD-Funktionen funktionieren einwandfrei, der Fehler muss in der letzten Datei liegen, irgendwo bei der einleserei. Ich find einfach keinen Fehler. Ich Danke Euch schonmal für die Hilfe.
Es gibt in Beitrag "AVR TSIC Auswertung => riesen Programm" eine verbesserte Fassung des Codes aus Beitrag Beitrag "Re: wie Daten an MSP430F1611 seriell einlesen?" für AVR (allerdings mit ein paar Fehlern).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.