Forum: Compiler & IDEs LED über Schalter ansteuern?


von Christian (Gast)


Lesenswert?

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;)?

von Stefan B. (Gast)


Lesenswert?

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
                       ^^^^^^

von Stefan B. (Gast)


Lesenswert?

Und daran denken: Dein Programm schaltet die einmal eingeschaltete LED 
niemals wieder aus! Willst du das?

von Christian (Gast)


Lesenswert?

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?

von Stefan E. (sternst)


Lesenswert?

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?

von Stefan B. (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

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

von Stefan B. (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?

von Christian (Gast)


Lesenswert?

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

von Christian (Gast)


Lesenswert?

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.

von Stefan B. (Gast)


Lesenswert?

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
}

von Christian (Gast)


Lesenswert?

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?

von Stefan B. (Gast)


Lesenswert?

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?

von Stefan B. (Gast)


Lesenswert?

Edit: Rösten intern ja, aber nicht unbedingt die Schutzdioden. Das war 
für den Fall gedacht Spannung am Pin > Vcc.

von Stefan B. (Gast)


Lesenswert?

> 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.

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

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); */ }

von Stefan B. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Stefan B. (Gast)


Lesenswert?

Korrektur: wie man den PC dazu bringt, an PB0 den 1 Zustand anzulegen.
                                            ^

von Christian (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Stefan B. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.