Hallo zusammen, ich hoffe Ihr könnt mit weiterhelfen. Ich bin grad erst dabei mich in die Microcontrollerprogrammierung einzuarbeiten und habe mir deshalb mal das Lernpaket von Franzl besorgt. Ist ja auch soweit ganz schön, nur steht da recht wenig über C drin. Da ich aber C schonmal in der Schule hatte möchte ich auch dabei bleiben und nicht auf Assembler umswitchen. Nun zu meinem ersten Problem: Die Ports 0,1,2 sollen Eingänge (mit eingeschalteten Pull-up Widerständen) und 4,5 Ausgänge sein. Bei anliegender Masse an Port 0 soll nun eine LED an Port 3 zum leuchten gebracht werden. Aus dem GCC-Tutorial habe ich mir dafür folgende Befehle hereuasgesucht, aber die LED bleibt bisher dunkel. #include <avr/io.h> void main (void) { PORTB = ((0<<PB4) |(0<<PB3) |(1<<PB2) |(1<<PB1) |(1<<PB0)); DDRB = ((1<<DDB4)|(1<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0)); while (1) { if ( !(PINB & (1<<PINB0))) { PORTB |= (1<<PB3); } } return 1; } Weiß irgendwer was ich falsch gemacht habe? Ich habe schon stundenlang alles mögliche ausprobiert :-S Vielen Dank schonmal!!! P.S. Ist die obligatorische Endlosschleife, um das fehlende Betriebssystem zu kompensieren so in Ordnung (while (1) { ... } return 1;)?
Da stimmt was nicht: > Die Ports 0,1,2 sollen Eingänge (mit eingeschalteten Pull-up > Widerständen) und 4,5 Ausgänge sein. Bei anliegender Masse an Port 0 ^^^^^^^^^^^^ > soll nun eine LED an Port 3 zum leuchten gebracht werden. Aus dem ^^^^^^
Und daran denken: Dein Programm schaltet die einmal eingeschaltete LED niemals wieder aus! Willst du das?
Hallo Stefan, nein natürlich will ich das eigentlich nicht. Mir geht es momentan nur darum mal dahinterzusteigen ob wie ich einzelne Ports ein- und ausschalten kann. Das Programm hier soll ja nur ein erster Test sein. Danach geht's dann ans verkomplizieren der Bedingungung, aber ich dachte mir das ich das ganze lieber Stück für Stück aufbaue, weil ich halt noch blutiger Anfänger bin. Köntest du mir bitte sagen wo genau ich den oder die Fehler gemacht habe?
Christian schrieb: > Köntest du mir bitte sagen wo genau ich den oder die Fehler gemacht > habe? Den von meinem Namensvetter angekreideten Fehler hast du nirgendwo gemacht. Das ist nämlich nur ein sprachlicher Fehler, der sich im Code nicht widerspiegelt. Erst mal was grundlegendes: welcher AVR?
Das Programm passt ja nicht zur Beschreibung. Vielleicht passt auch die Schaltung nicht zum Programm? Das Programm könnte funktionieren, wenn eine LED korrekt an Pin 3 von PORTB angeschlossen ist. Korrekt heisst hier active-high Beschaltung (s. AVR-GCC-Tutorial Abschnitt IO) mit richtiger Polung der LED und richtigem Wert für den Vorwiderstand (s. http://www.mikrocontroller.net/articles/LED#Vorwiderstand) Vorwiderstand LED PB3 )-------####---- -------->|-----( GND
Oh da hab ich mich wohl vertippt. Sind natürlich die Ausgänge 3 und 4 gemeint. Der Quellcode ist aber richtig und passt somit auch. Der MC ist ein ATtiny13, programmiert mit AVR Studio 4. Richtig angeschlossen ist die LED auch
Und der Taster? Taster Attiny13 ==== PB0 )-----+---o o---( GND | +----------( MOSI ISP Anschluss Hast du den Attiny13 auf der Franzis-Platine? http://www.elo-web.de/franzis-media/655159/CNS_CONTENT_PAGE/LPmikroSoft.jpg
Christian schrieb: > Der MC ist ein ATtiny13, programmiert mit AVR Studio 4. Richtig > angeschlossen ist die LED auch Nur um sicher zu gehen * wie hast du festgestellt, dass die Programmierung geklappt hat? * wie hast du festgestellt, dass die LED richtig rum drinnen ist?
Weil wenn ich das Programm so laufen lasse (LED manuell & dauerhaft eingeschaltet), die LED leutet: #include <avr/io.h> void main (void) { PORTB = ((0<<PB4) |(1<<PB3) |(1<<PB2) |(1<<PB1) |(1<<PB0)); DDRB = ((1<<DDB4)|(1<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0)); while (1) { } return 1; } Erst wenn ich die If-Bedingung ins Spiel Bringe und die LED erst nach dem Kontakt von PB0 und GND anfangen dürfte zu leuchten, tritt das Problem auf (die LED bleibt aus): #include <avr/io.h> void main (void) { PORTB = ((0<<PB4) |(0<<PB3) |(1<<PB2) |(1<<PB1) |(1<<PB0)); DDRB = ((1<<DDB4)|(1<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0)); while (1) { if ( !(PINB & (1<<PINB0))) { PORTB |= (1<<PB3); } } return 1; } P.S.: Ja ich benutze die Franzis-Platine
Moment, es lag noch ein Wckelkontakt vor! Die LED leuchtet zwar in auch in der zweiten Version des Programms (mit der If-Schleife). Allerdings auch ohne vorher PB0 an GND zu legen. Logischer Hintergrund: PB0 soll an Masse liegen --> der Wert von PINB0 muss = 0 sein --> /* Fuehre Aktion aus, wenn Bit Nr. 0 (das "nullte" Bit) in PINB geloescht (0) ist */ if ( !(PINB & (1<<PINB0)) ) { /* Aktion */ } ... Der Fehler muß also in der Wenn-Bedingung ( !(PINB & (1<<PINB0)) ) { ... } liegen. Diese habe ich jedoch 1:1 aus dem GCC-Tutorial übernommen.
Versorgst du die Platine über den RS232 Port deines PCs oder über eine Batterie an RTS (+ Pol) und GND (- Pol)? Wenn über den RS232 Port deines PCs: Wenn DTR ausgeschaltet ist, können bis zu -12V dort auf der Leitung sein. -12V zerren über den 100K Widerstand den logischen Pegel an dem PB0 auch ganz gut in Richtung LOW. Es ist die Frage, ob der interne Pullup an PB0 dann genug Strom nachliefern kann. Noch besser wäre es, wenn du ein Multimeter hast und die Spannung auf DTR gegen GND messen kannst. Vergiss nicht: Wenn in deinem Programm die LED einmal angeschaltet wurde, dann bleibt die bei deinem if-Anweisungsblock an. Spekulation: Das einmalige Umschalten könnte beim Übergang ISP-Programmierung zur Stromversorgung der Platine über RS232 geschehen, wenn die RS232 vom PC aus uminitialisiert wird. Ich würde auf jeden Fall den else-Anweisungsblock ergänzen, der die LED ggf. auch abschaltet.
1 | #include <avr/io.h> |
2 | |
3 | int main (void) |
4 | {
|
5 | // PB3 Ausgang, PB0 Eingang
|
6 | DDRB = ((1<<DDB3) | (0<<DDB0)); |
7 | |
8 | // Start: LED aus, interner Pullup PB0 ein
|
9 | PORTB = ((0<<PB3) | (1<<PB0)); |
10 | |
11 | while (1) |
12 | {
|
13 | if ( !(PINB & (1<<PINB0)) ) |
14 | {
|
15 | // Taster zu GND geschlossen
|
16 | PORTB |= (1<<PB3); // LED an |
17 | }
|
18 | else
|
19 | {
|
20 | // Taster zu GND offen
|
21 | PORTB &= ~(1<<PB3); // LED aus |
22 | }
|
23 | }
|
24 | |
25 | return 1; |
26 | }
|
Ja die Stromversorgung läuft über rs232, abe aber kein Multimeter zur Hand. Habe die else Aweisung entsprechend ergänzt (s.o.). Ergebnis: Die LED leuchtet nach wie vor von Beginn an. Unterschied zu Vorher: Lege ich VCC auf PB0 geht sie aus (GND an Masse ändert nichts). Ist ja schonmal ein Fortschritt. Ich kann jetzt die LED schonmal über PB0 beeinflussen. Zwar nicht so wie ich es will aber immerhin :) Aber wie kann das sein? Stimmen die Befehle im Tutorium etwa nicht? Wie schaffe ich es jetzt das die Lampe erst bei PB0 gegen GND angeht?
Hänge die HEX-Datei mal an. Ich möchte das gerne im AVR Studio Simulator sehen. Wenn du einen Digifotoknips hast: Mache mal ein Bild von deiner Schaltung so wie du das Programm laufen lässt. Bildformate beachten. > Lege ich VCC auf PB0 geht sie aus Vorsicht bei solchen Versuchen. Du musst 110% sicher sein, dass der Pin auf Eingang steht. Wenn nicht, röstest du u.U. den Pin genauer die Schutzdiode(n) intern. Bei solchen Versuchen (Logikpegel an Pin legen) besser Vcc mittels Pull-up-Widerstand zur Strombegrenzung abgreifen. Pull-up- widerstand ca. 10K Pin )------####----- ( Vcc Die LED könnte ausgehen, weil der Attiny13 in den RESET Zustand fällt. Der AVR wird in den RESET Zustand fallen, wenn seine Versorgungsspannugn einbricht. Die Versorgungsspannung kann einbrechen, wenn du eine Schaltung mit zu hoher Stromaufnahme produziert hast - im Extremfall durch einen Kruzschluss. Die Stromversorgung aus der RS232 ist nicht soooo belastbar (paar mA) und wenn zu viel entnommen wird, sackt Vcc ab. > GND an Masse ändert nichts. GND an was?
Edit: Rösten intern ja, aber nicht unbedingt die Schutzdioden. Das war für den Fall gedacht Spannung am Pin > Vcc.
> Stimmen die Befehle im Tutorium etwa nicht? Das Tutorial hier im Wiki? Das ist nicht für das Franzis-Lernpaket bzw. dessen Hardware geschrieben. Wenn du also das Tutorial wortwörtlich übernimmst, kommt ein Programm für eine andere Hardware raus. Das auf deiner Hardware funktioniert nicht. Man muss also Änderungen machen. Die Änderungen betreffen u.U. den Anschluss der Hardware (Widerstand, LED, Taster), das Kompilieren des Programms (Einstellungen) und das Flashen des Programms. Die Änderungen sind im Prinzip nicht schwer. Aber eine Unsicherheit bei mir ist die Beeinflussung der Schaltung durch die RS232-Verbindung zum PC. Ich kenne das Handbuch des Franzis-Lernpakets nicht. Keiner der vier Punkte ist bisher 100% sicher abgeklärt. Daher meine Frage nach dem Foto (Hardware), dem Hexfile (Programm). Offen ist noch, ob das Programm tatsächlich im Attiny13 ist. Ich vermute nicht, denn die LED leuchtet, wie du schreibst, egal ob zu Beginn PB3 auf LOW oder HIGH initialisiert wird! Wenn du den Attiny13 AUSLESEN kannst, hänge das ausgelesene HEXfile an.
Alles klar dann lass ich das mal lieber mit dem VCC :-S Ich meinte natürlich GND an PB0 ändert nix. Im Franzis-Handbuch steht nur wenig über C sondern das meißte in Assembler. Was drin steht ist aber, das ein geöffneter Schalter den Wert Null ins PINB-Register übergibt. Daraufhin hab habe ich folgenden Befehl aus dem Tutorial herausgesucht um Port 3 einzuschalten wenn Port 0 an GND liegt: --> if ( PINB & (1<<PINB0) ) { PORTB |= (1<<PB3); } Ich denke schon das das Programm wirklich auf den ATtiny13 geschrieben wird, da wenn ich innerhalb der if-Bedingung den Teil zum einschalten des PB3 weglasse, die LED nicht an geht. if ( PINB & (1<<PINB0) ) { /* PORTB |= (1<<PB3); */ }
Das Bild ist gemäß Bildformate viel zu groß für den Inhalt. Es geht kleiner siehe Anhang. Dein HEXfile sieht im Simulator OK aus. Jetzt die Frage: Ist das auch im Attiny13 drin? Das kann man beantworten, wenn man ein Programm einspielt, welches mehrere Aktionen macht. Z.B. das Blinkprogramm im Anhang. Ich habe die Source und das HEXfile hochgeladen. Bei richtiger Funktion sollte die LED mehrmals blinken und dann erst auf den Taster reagieren. Das Blinken zeigt: PB3 funktioniert grundsätzlich als Ausgabepin und das Flashen funktioniert. Bei deiner Schaltung wäre der Taster eine Drahtbrücke zwischen PB0 und GND, die entweder gesteckt (LED an) oder nicht gesteckt (LED aus) ist. > Aber eine Unsicherheit bei > mir ist die Beeinflussung der Schaltung durch die RS232-Verbindung zum > PC. Ich kenne das Handbuch des Franzis-Lernpakets nicht. In der Online-Beschreibung des Franzis-Lernpaketes steht: "Außerdem kann die Verbindung zwischen PC und Controller auch statisch genutzt werden. Zwei Leitungen dienen dann als Eingänge des Mikrocontrollers. Der PC legt 1- oder 0-Zustände an, die ein Controllerprogramm über die Anschlüsse PB0 und PB2 lesen kann." http://www.elo-web.de/elo/mikrocontroller-und-programmierung/avr-grundlagen/experimente-mit-dem-attiny13 Du solltest im Handbuch nachsehen, wie man den PC dazu bringt, an PB1 den 1 Zustand anzulegen. Wenn du das nicht findest, ist es einen Versuch Wert, statt PB0 mit seinem Pull-Up einen anderen Pin mit seinem Pull-Up zu benutzen, der nicht vom PC aus kontrolliert wird: Vorschlag PB4.
Korrektur: wie man den PC dazu bringt, an PB0 den 1 Zustand anzulegen. ^
Hab den Schalter einfach auf PB4 gelegt und es hat endlich geklappt! Dann das Ganze nochmal auf PB0 jedoch nicht mit RS232 sondern mit externer Stromversorgung & es klappt auch! Endlich... ... und ich war schon fast am verweifeln. Das mir der RS232 da einen Strich durch die Rechnung gemacht hat hätt ich nie gedacht. DANKE DANKE DANKE Stefan B. 1000 Dank für den SUPER - TIP !!! Kannst du mir vielleicht noch verraten wie genau du den hex-file getestet hast? Gibt es bei Studio 4 oder anderswo, eine Option die Schaltung nachzustellen und dann verschiedene MC zu simulieren? Das würde mir auf jeden Fall weiterhelfen weil ich den ATtiny bestimmt jetzt schon 100 mal beschreiben mußte um verschiedene Programmänderungen zu testen. Geht das so weiter kann ich ihn bald weg schmeißen.
Christian schrieb:
> Geht das so weiter kann ich ihn bald weg schmeißen.
Mach Dir keine Sorgen, mindestens 10.000 mal Proggen ist doch
garantiert.
Peter
Klasse, dass du weiter gekommen bist! Leider kann man im nackten AVR Studio nur auf Registerebene debuggen und simulieren aber keine Schaltungen eingeben. Man muss also wissen, welche Signale in welchen Registern was in der Schaltung bewirken und umgekehrt. Auch deswegen ist es enorm wichtig, bei der Ferndiagnose und beim Ferndebuggen die Schaltung leicht zugreifbar zu haben. Leider unterschätzen viele Fragesteller diesen Punkt. Im Artikel AVR-Simulation sind weitere Simulationstools genannt. Persönlich habe ich keine Erfahrung damit.
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.