Hallo, ich brauch dringend eure Hilfe. Ich versuche seit drei Tagen einen DS18B20 zum laufen zu bekommen und bleib schon beim Reset hängen. Na das kann ja noch witzig werden. Mein Aufbau: Atmega 32 Pin A0 an PIN 2 des DS... . Pin A1 und A2 Oszi. GND an Pin 1 des DS... . 5V an Pin 3 des DS... . Selbe Versorgung wie vom Atmega 32. Zischen Pin 2 und 3 des DS... befindet sich ein 4,7 k parallel. Atmega Takt: 4Mhz Qaurz. Was pasiert: Schalte ich die Spannungsversorgung ein liegt A0 auf GND und A2 auf High. Trenne ich die Datenleitung des DS... und starte neu ist A2 auch high. Auf der Datenleitung liegen dann 5V. Ich hab es auch schon mit einem anderen Probiert. Das selbe Problem. Was mach ich falsch? Danke für eure Hilfe. Gruß, Jürgen
holger schrieb: > #define Bus PA0 > > if (Bus == 0) > > PA0 ist immer Null. Bus damit auch. Versteh ich nicht. Was willst du mir damit sagen? Hängt das mit dem Fehler zusammen?
Ratemall schrieb: > Versteh ich nicht. Was willst du mir damit sagen? Hängt das mit dem > Fehler zusammen? Könnte man so sagen. Das entspricht ungefähr main() { if (1) printf("Fehler!"); else printf("OK!"); } mit der anschliessenden verblüfften Frage, weshalb das Programm immer nur Fehler! ausspuckt.
>Versteh ich nicht. Was willst du mir damit sagen?
PA0 ist ein #define aus einer Header Datei.
Du kannst nicht PA0 (was immer 0 ist) abfragen sondern das
Bit 0 (=PA0) aus dem PINA Register. Das ist dein Fehler.
Da ist ein Denkfehler von mir. Ich muß die Variable reset abfragen:
1 | reset = (Eingang & 1<<Bus); |
2 | |
3 | _delay_us(480); |
4 | BUSDDR_AUS(); |
5 | if (reset == 0) |
6 | {
|
7 | |
8 | PORTA |= (1<<ERRJA); |
9 | // lcd_string("Reset fehler");
|
10 | }
|
11 | else
|
12 | {
|
13 | PORTA |= (1<<ERRNEIN); |
14 | // lcd_string("Reset okay");
|
15 | }
|
Funktioniert drotzem nicht.
Oha, jetzt wirds interessant. Hab den Optimieren auf 00 gesetzt, funktioniert. Mit Datenleitung A1 High und ohne A2 high. Wie man im Code sieht wollte ich das ganze auf ein Display ausgeben. Das Display läuft aber nur bei 0S richtig. Was tun?
Okay, raus gefunden wo der Fehler ist. Der Fehler liegt bei der Display-Routine. Diese Fragt anscheinend das Busyflak nicht richtig ab. Im 0S funktioniert die Anzeige aber das Reset nicht. Im 00 funktioniert der Reset aber das Display zeigt nur Schrott. Es sieht so aus als würde das Display nicht nachkommen. Deshalb habe ich die Routine von so:
1 | void lcd_string(char *s) |
2 | {
|
3 | char c; |
4 | c=*s; |
5 | while (c != '\0') |
6 | {
|
7 | RS_S; |
8 | DISPLAY_PORT = c; |
9 | DISPLAY_EN(); |
10 | DISPLAY_BUSY(); |
11 | *s++; |
12 | c=*s; |
13 | }
|
14 | }
|
auf so:
1 | void lcd_string(char *s) |
2 | {
|
3 | char c; |
4 | c=*s; |
5 | while (c != '\0') |
6 | {
|
7 | RS_S; |
8 | DISPLAY_PORT = c; |
9 | DISPLAY_EN(); |
10 | DISPLAY_BUSY(); |
11 | _delay_ms(10); |
12 | *s++; |
13 | c=*s; |
14 | }
|
15 | }
|
geändert. Das macht das Display aber langsam. Aber das ist woll ein anderes Problem. Muss ich ein neues Thread aufmachen oder kannst Du mir da auch schnell helfen?
Wieso machst du nicht eins nach dem anderen? Bekomm doch erstmal deine LCD Routine in den Griff und frag das Busy Flag korrekt ab. Dein Code sieht allgemein ziemlich komisch aus. Wenn du einen String durchlaufen willst, dann musst du s++ schreiben und nicht *s++. Du willst ja die Adresse um 1 erhöhen und nicht den Buchstaben. Allerdings funktioniert es, wegen der Operatorreihenfolge. Trotzdem falsch und murks. Grundsätzlich so:
1 | void lcd_string(char *s) { |
2 | |
3 | while(*s) { |
4 | tuwas(*s); |
5 | s++; |
6 | }
|
7 | }
|
Und dann die unnötigen Zuweisungen zur Variable c. Warum schreibst du manche Funktionen klein (richtig) und andere wiederrum komplett groß? Der Code ist allgemein grausam.
Und fang als erstes damit an, die eine Funktion zu machen, die ein einzelnes Byte ausgibt. Das ist doch grausam, wenn du da jedesmal immer wieder den gleichen Ausgabecode in jeder einzelnen Funktion hast. Eine Stringausgabe ist dann ganz simpel
1 | void lcd_string(const char *s) |
2 | {
|
3 | while(*s) |
4 | lcd_character(*s++); |
5 | }
|
cyblord ---- schrieb: > Wieso machst du nicht eins nach dem anderen? Weil die Routine eigentlich schon längst fertig war. Das ist ja cool. Die Routine hab ich noch von der Ausbildung. Die hat ein Lehrer erstellt und ich habe sie nur an mein Board angepasst. cyblord ---- schrieb: > Warum schreibst du manche Funktionen klein (richtig) und andere > wiederrum komplett groß? Das hatte denn Hintergedanken das die kleingeschriebenen aus dem Hauptprogram aufgerufen werden und die großen nur intern in der Routine benötigt werden. Das heist wenn ich das:
1 | void lcd_string(char *s) |
2 | {
|
3 | char c; |
4 | c=*s; |
5 | while (c != '\0') |
6 | {
|
7 | RS_S; |
8 | DISPLAY_PORT = c; |
9 | DISPLAY_EN(); |
10 | DISPLAY_BUSY(); |
11 | *s++; |
12 | c=*s; |
13 | }
|
14 | }
|
zu dem: void lcd_string(char *s) { while (*s != '\0') { RS_S; DISPLAY_PORT = *s; DISPLAY_EN(); DISPLAY_BUSY(); s++; } } änder, müßte es auch mit der Optimierung 00 funktionieren? Werds heute abend mall ausprobieren. Danke für eure Mühe.
Hallo, wollte nur schnell bescheidgeben das es so funktioniert:
1 | void lcd_string(char *s) |
2 | {
|
3 | while (*s != '\0') |
4 | {
|
5 | RS_S; |
6 | DISPLAY_PORT = *s; |
7 | DISPLAY_EN(); |
8 | DISPLAY_BUSY(); |
9 | s++; |
10 | }
|
11 | }
|
Aber das mit dem Busy-Flag klappt noch nicht. Könnt ihr mir da auch noch helfen? Wie muss ich denn Code ändern:
1 | void DISPLAY_BUSY(void) |
2 | {
|
3 | uint8_t j; |
4 | j=0; |
5 | DDRC=0x00; |
6 | while (!(j==0)) |
7 | {
|
8 | RS_L; |
9 | RW_S; |
10 | asm("nop"); |
11 | EN_S; |
12 | asm("nop"); |
13 | |
14 | if (!(PINC &(1<<PIN7))) |
15 | {
|
16 | j=0; |
17 | }
|
18 | else
|
19 | {
|
20 | j=1; |
21 | }
|
22 | EN_L; |
23 | RW_L; |
24 | }
|
25 | DDRC=0xFF; |
26 | }
|
Guten abend. Muss den Thread doch noch mal zum Leben erwecken. Display funktioniert jetzt einwandfrei. Bastel schon seit Freitag wieder an dem Fühler rum und komme nicht weiter. Dachte eigentlich der Reset funktioniert und habe am auslesen weiter gemacht. Da es nicht funktioniert, habe ich denn Reset nochmals untersucht und festgestellt das es mich vera.....t hat. So sieht momentan der Code aus:
1 | void reset (void) |
2 | {
|
3 | uint8_t reset; |
4 | BUSDDR_AUSGANG(); |
5 | BUS_LOW(); |
6 | _delay_us(480); |
7 | BUSDDR_EINGANG(); |
8 | _delay_us(66); |
9 | |
10 | reset = (Eingang & 1<<Bus); |
11 | |
12 | _delay_us(480); |
13 | BUSDDR_AUSGANG(); |
14 | if (reset == 1) |
15 | {
|
16 | lcd_string("Reset fehler"); |
17 | }
|
18 | else
|
19 | {
|
20 | lcd_string("Reset okay"); |
21 | }
|
22 | }
|
Ist die Datenleitung eingesteckt und ich schalte das Bord an, zeigt das Display: "Fehler". Ist die Datenleitung getrennt und ich schalte ein, zeigt das Display "okay" an. Die Routine funktioniert demnach. Weil, würde der Reset funktionieren würde der Sensor die Datenleitung auf null ziehen das ja dem trennen der Leitung entspricht.? Jetzt hab ich an der Leitung gemessen was für ein Pegel anliegt wenn die Leitung nicht angeschlossen ist. Siehe da, 5V. Ist das Richtig?
Die Initialisieung sieht bei mie so aus. Vllt. hilft dir das weiter. // Initalisierung int DS18S20_Init(void) { uint8_t err=100; DS18S20_DDR |= 1 << DS18S20_wire; // 1-wire Leitung auf LOW schalten _delay_us(480); // mind. 480µs Low halten DS18S20_DDR &= ~(1<<DS18S20_wire); // 1-wire Leitung auf HIGH schalten _delay_us(60); // nach mind. 60µs wird der Precense-Impuls abgefragt err = (DS18S20_PIN & (1<<DS18S20_wire)) >> DS18S20_wire; // err = 0 Sensor ermittelt // Eine am Port D Pin 1 angeschlossene LED zeigt einen Fehler an wenn kein Sensor angeschlossen ist if (err == 1) { DS18S20_DDR |= ( 1 << LED_error); // Kein Sensor vorhanden oder Leitungs Unterbrechung } else { DS18S20_DDR &= ~( 1 << LED_error); // Mindestens ein Sensor ermittelt } _delay_us(480); return err; }
Sorry deine Frage vergessen >Die Routine funktioniert demnach. Weil, >würde der Reset funktionieren würde der Sensor die Datenleitung auf null >ziehen. Die Aussage ist richtig wenn der Sensor angeschlossen ist. > das ja dem trennen der Leitung entspricht.? Diese Ausage ist falsch! Warum? Weil der Pull-UP den BUS im Ruhezustand auf High-Signal zieht. Du hast doch hoffentlich einen Externen Pull-UP? > Siehe da, 5V. Ist das Richtig? Ja wenn externer PULL-UP auf High gechaltet ist
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.