mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfängerfragen


Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

beschäftige mich in der Schule und jetzt auch ein bissin privat mit der 
programmierung eines Microcontrollers. Programmiersprache is CPP und der 
Controller dürfte ein ATmega8 sein.

Jetzt kommen wir mal zu meiner Frage, unzwar:
A) Ich schaffe es einfach nicht ein Lauflicht zu realisieren, eine 
einzele LED kann ich blinken lassen (Dank eines Tuts hier). Aber wenn 
ich das selbe einfach nochmal schreibe und die Pins abändere, klappt es 
nicht (Ausgänge usw habe ich beachtet).

Und da das mein erste Beitrag ist hoffe ich mal ich benute auch die 
Syntax vom Forum richtig:
#include <avr/io.h>
#include <util/delay.h>  
#include <stdint.h>   

const uint8_t LEDrot_B    = PB0;  
const uint8_t LEDgelb_B    = PB1;
const uint8_t LEDgruen_B  = PB2;

void long_delay(uint16_t ms) 
{
    for(; ms>0; ms--) _delay_ms(1);
} 

int main(void)
{
  DDRB = (1<<LEDrot_B);
  DDRB = (1<<LEDgelb_B);
  DDRB = (1<<LEDgruen_B);        
 
  while( 1 ) 
  {               
    PORTB ^= ( 1 << LEDgruen_B );
    PORTB ^= ( 1 << LEDgelb_B );  
    long_delay(1000);           
  }
  return 0;
}

Meiner Meinung nach müsste der Controller doch jetzt immer die gelbe und 
die gruene LED an und ausschalten, oder?  Den nur die gruene LED blinkt, 
und die gelbe nicht oder diese flakert nur ganz schwach.

B) Noch eine Frage: Kann mir jemand Schritt für Schritt die Funktion 
(ist doch eine, oder?) void long_delay erklären? Verstehe was sie macht, 
aber nicht wie.

C) Dann noch eine Frage, was wäre die kleinste erkennbare Umschaltzeit 
die ich erkennen kann mit dem Auge? Mir sind die 50Hz vom TV usw 
bekannt, aber wie wäre eine genaue ms Zeit?

Noch als Zusatz: Richtig gelötet sind alle LEDs, wenn ich diese über 
einen Taster oder über den HIGH-PIN ansteuer leuchten alle normal und 
gleich stark.

Hoffe einer kann mir helfen, mfG Mole

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mole schrieb:


>   DDRB = (1<<LEDrot_B);
>   DDRB = (1<<LEDgelb_B);
>   DDRB = (1<<LEDgruen_B);

überleg erstmal, was du hier machst...

Autor: Thomas Burkhart (escamoteur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> C) Dann noch eine Frage, was wäre die kleinste erkennbare Umschaltzeit
> die ich erkennen kann mit dem Auge? Mir sind die 50Hz vom TV usw

1 Hz = 1/s also s= 1/Hz

Gruß
Tom

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  DDRB = (1<<LEDrot_B);
>  DDRB = (1<<LEDgelb_B);
>  DDRB = (1<<LEDgruen_B);

Musst du entweder so schreiben:
  DDRB = (1<<LEDrot_B);
  DDRB |= (1<<LEDgelb_B);
  DDRB |= (1<<LEDgruen_B);  
{/c]

oder so:
[c]
  DDRB = (1<<LEDrot_B) | (1<<LEDgelb_B) | (1<<LEDgruen_B);  

zu B): Man nehme eine Schleife, die man "ms"-lang laufen lässt und in 
dieser Schleife wird eine Pause von 1ms gemacht. Nichts anderes als die 
Multiplikation einer Millisekunde mit einer Vatiablen.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:

> zu B): Man nehme eine Schleife, die man "ms"-lang laufen lässt und in
> dieser Schleife wird eine Pause von 1ms gemacht. Nichts anderes als die
> Multiplikation einer Millisekunde mit einer Vatiablen.

wobei da aber vermutlich nicht die erwartete Sekunde Pause rauskommwn 
wird durch den Overhead der for-schleife...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Justus Skorps (jussa)

>> dieser Schleife wird eine Pause von 1ms gemacht. Nichts anderes als die
>> Multiplikation einer Millisekunde mit einer Vatiablen.

>wobei da aber vermutlich nicht die erwartete Sekunde Pause rauskommwn
>wird durch den Overhead der for-schleife...

Die paar Mikrosekunden kann man problemlos in den Skat drücken, für 
diese "Anwendung" erst recht!

MFG
Falk

Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal danke an euch, das ich das ODER nicht geschrieben habe verwirrt 
mich auch grade. Sehe aber das es in dem Tut (Mit nur einer LED) auch 
ohne ist, kann mir einer erklären warum es mit einer geht aber bei 
mehreren der ODER gebraucht wird?

Dann nochmal zu B) ich verstehe ja was die Schleife macht, sie sagt ja 
das man solange durchlaufen soll wie ms größer wie 0 ist, dann bei jedem 
Durchlauf immer ms um eins verringern und ms wird ja am Anfang auf 1000 
gesetzt, also 1000 Durchläufe.
Aber was bedeutet: _delay_ms(1); ist das die delay funktion die einfach 
1ms dauert ? (diese wird ja dann 1000 mal wiederholt) und ist diese auf 
1 beschränkt oder warum sagt man nicht _delay_ms_(1000)?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mole schrieb:
> Erstmal danke an euch, das ich das ODER nicht geschrieben habe verwirrt
> mich auch grade. Sehe aber das es in dem Tut (Mit nur einer LED) auch
> ohne ist, kann mir einer erklären warum es mit einer geht aber bei
> mehreren der ODER gebraucht wird?
>


Weil im Tut wahrscheinlich nur EINE Zuweisung an DDRx gemacht wird.

Eine Zuweisung überschreibt immer alle Bits und nicht nur einzelne.
  i = 9;
  i = 3;

Du würdest dich schön bedanken, wenn nach der 2.ten Zuweisung noch das 
eine gesetzte Bit von der 9 in i stehen würde.

> Aber was bedeutet: _delay_ms(1); ist das die delay funktion die einfach
> 1ms dauert ? (diese wird ja dann 1000 mal wiederholt) und ist diese auf
> 1 beschränkt oder warum sagt man nicht _delay_ms_(1000)?

Weil es früher mal eine Beschränkung für die _delay_ms Funktion gab. Die 
Zeit konnte eine gewisse Grenze, die durch die Taktfrequenz des µC 
vorgegeben war, nicht überschreiten.

Wenn du willst, kannst du heute auch _delay_ms(1000) schreiben. Die 
Beschränkung wurde vor einiger Zeit aufgehoben.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:

> Die paar Mikrosekunden kann man problemlos in den Skat drücken, für
> diese "Anwendung" erst recht!

schon klar, aber lieber sagt man ihm das am Anfang, bevor er was sich 
was ungenaues merkt und dann später damit mal 100 µs genau einstellen 
will..

Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann noch eine Frage, ich habe jetzt alles an einen Taster geschlossen, 
also erst sollen sie nacheinandere angehen wenn der Taster1 gedrückt 
wird und wenn dieser wieder losgelassen wird, in umgekehrter Reihenfolge 
auch wieder aus. Klappt auch soweit alles gut, aber ich habe Taster1 an 
einen PullUP angeschlossen und möchte diesen einfach vorher wieder 
umlegen. Wie genau müsste meine Variable und meine Abfrage dafür 
aussehen?
const uint8_t Taster1_D_PullUP  = PD2;

uint8_t Taster1_D;

if (PIND&(1<<Taster1_D_PullUP))
{
  Taster1_D=0
}
else
{
  Taster1_D=1
}

Habe ich da einen Denkfehler?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mole schrieb:
> Dann noch eine Frage, ich habe jetzt alles an einen Taster geschlossen,
> also erst sollen sie nacheinandere angehen wenn der Taster1 gedrückt
> wird und wenn dieser wieder losgelassen wird, in umgekehrter Reihenfolge
> auch wieder aus. Klappt auch soweit alles gut, aber ich habe Taster1 an
> einen PullUP angeschlossen und möchte diesen einfach vorher wieder
> umlegen.

Was mag das wohl heissen?

Autor: Thomas Burkhart (escamoteur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist auch nicht ganz klar, ob er den PullUp erschießen oder erdolchen 
will ;-)

Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry für den unklaren Text, aber in Kurzform:

Habe meinen Taster1 an einem PullUP, weil mir das aber immer Probleme 
gibt beim umdenken (Wenn gedrückt = 0) möchte ich das vorher ändern mit 
meiner Abfrage wie oben beschrieben.

Das praktisch meine Variable "Taster1_D_PullUP" den Wert von PD2 hat, 
aber dieser in meiner Variable Taster1_D genau umgedreht ist, bedeutet 
das Taster1_D eine 1 hat wenn der Taster gedrückt ist.

Immer noch schwer zu verstehen aber ich weiß nicht wie ich es besser 
beschreiben soll... Hoffe einer versteht es und kennt die Lösung oder 
kann es den anderen näher bringen.

Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay scheinbar steigt keiner durch die Frage durch... schade.

Aber kann mir jemand sagen wie ich eine Frequenz einen Summer zuweise?
Müsste doch auch funktionieren wenn ich ihn ein- und ausschalte, wäre 
eine rechteckige Frequenz, und durch den delay kann man die Zeit 
bestimmen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mole schrieb:
> Sorry für den unklaren Text, aber in Kurzform:
>
> Habe meinen Taster1 an einem PullUP, weil mir das aber immer Probleme
> gibt beim umdenken (Wenn gedrückt = 0) möchte ich das vorher ändern mit
> meiner Abfrage wie oben beschrieben.

Gewöhn dich daran.

   if( PIND & ( 1 << PD2) )

...  Abfrage ob der Pin High ist

   if( !( PIND & ( 1 << PD2) ) )

... Abfrage ob der Pin Low ist.

Der einzige Unterschied ist das der Ausdruck in Klammern steht und ein ! 
davor ist.

Wenn dir das Probleme macht, dann mach dir ein Makro dafür
#define IS_KEY_PRESSED( port, pin )    ( !( port & ( 1<<(pin) ) ) )

...


   if( IS_KEY_PRESSED( PIND, PD2) )
   {
      ...
   }

und schon ist das alles in der Verwendung lesbar.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Deine Taster-Umschaltung müsste so funktionieren.

2. Um welche Sorte Summer handelt es sich?

Autor: Mole (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann ich dir leider nicht genau sagen, aber das hier ist mein Board:
http://shop.myavr.de/Systemboards/myAVR%20Board%20...

Hoffe das hilft weiter, und wegen dem Makro. Danke klappt :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.