Forum: Mikrocontroller und Digitale Elektronik Probleme mit C


von Florian S. (fuxreid)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich habe das Problem dass die LED an Port PB0 nicht leuchtet, wenn mein 
timer "in Betrieb" ist, obwohl ich denke, alles richtig gemacht zu 
haben.
Da ich noch recht neu in der Thematik bin, brauch ich bitte Eure Hilfe.

Hier ein Code-Auszaug:

char x=1;   // timer0 verwaltung
char a=0;   // minuten anzahl manuell
char sekunden=0;
char last=0;

int main(void)
{
  DDRB |= (1<<DDB0); // PORTB 0 als ausgang
  DDRD = 0xFF;       // PortD alles als Ausgang
  DDRC &= ~ (1<<DDC0) | (1<<DDC1) | (1<<DDC2);   // PORTC 0...2 als 
Eingang
  DDRC |= (1 << DDC3) | (1 << DDC4) | (1 << DDC5); // PortC 3..5 als 
Ausgang
  PORTC |= (1 << PC3) | (1 << PC4) | (1 << PC5);// PORTC 3..5 High = 
Digits aus

  // Timer 1 konfigurieren
  TCCR1A = (1<<WGM12);   // CTC Modus
  TCCR1B |= (1<<CS10);  // Prescaler 64
  OCR1AL = 125-1;       // ((8000000/64)/1000) = 125
  TIMSK |= (1<<OCIE1A); // Compare Interrupt erlauben
  TIFR |= (1<<OCF1A);   // Output Compare A Match Flag

  // Timer 0 konfigurieren
  TCCR0 = (1<<CS01) | (1<<CS00);
  TIMSK |= (1<<TOIE0);
  TIFR |= (1<<TOV0);
  sei();       // Global Interrupts aktivieren


  while (1)  // Endlos
  {

  if(last==1)  // Last einschalten
    {
    PORTB &= ~ (1<<PB0);
    }
  if(last==0)  // Last auschalten
    {
    PORTB |= (1<<PB0);
    }
  }
  return 0;
  }

ISR (TIMER1_COMPA_vect)

{
if (minute<a | sekunde<59)// Timerlaufzeit definieren
  {
  v=1;
  millisekunden++;
  if(millisekunden == 120)
    {
    sekunde++;
    millisekunden = 0;
    if(sekunde == 60)
      {
      minute++;
      sekunde = 0;
      }
      if(minute == 9)
      {
      minute = 0;
      }
    }
  }
  else
  {
  last=0;
  }
}


Wär super wenn ihr mir helfen könntet. Im Anhang ist noch der komplette 
Code.

GLG

von Hc Z. (mizch)


Lesenswert?

volatile (zumindest bei last, anderes nicht geprüft).

von Falk B. (falk)


Lesenswert?

Stichwort volatile, siehe Interrupt.

MfG
Falk

von Falk B. (falk)


Lesenswert?

Zu langsam :-0

von spess53 (Gast)


Lesenswert?

Hi

Gut. Dann beginnen wir erst mal mit dem lustigen Controller-Raten.

ATMEGA16? Wer bietet mehr?

MfG Spess

von Tom M. (tomm) Benutzerseite


Lesenswert?

Florian S. schrieb:
> if (minute<a | sekunde<59)// Timerlaufzeit definieren

Du willst ein logisches OR, schreibst aber binäres OR.

von Flo (Gast)


Lesenswert?

In deinem Programm wird eher dein ISR vom Timer0 blockieren als dein 
Timer1-Compare.

So nebenbei:

Florian S. schrieb:
> if (minute<a | sekunde<59)// Timerlaufzeit definieren

sollte wohl so gemeint sein:

if(minute<a || sekunde<59)  //logisches Oder statt bitweise Oder

Außerdem versteh ich deine Zeitzählung nicht:
120 Millisekunden ergeben dann 1 Sekunde ?? Da passt was nicht.

von Florian S. (fuxreid)


Lesenswert?

Also erst mal Danke für die schnellen Antworten!!!!

Den Fehler mit dem logischen || und mit dem volatile hab ich trotz 100 
mal lesen einfach ned gesehen! Danke!

@  spess53 (Gast):
Controller hab ich einen Atmega8 verwendet.

@ Flo (Gast):
die 120 statt 1000ms hab ich nur testweise eingesetzt, damit die Uhr 
während der Entwicklung ein bisschen schneller geht^^

Aber ich habe noch eine ganz andere Frage:

Wie kann ich einen Summer an meinen Atmega8 anschließen?
Die Ansteuerung wird ja dann über einen Timer mit der richtigen Frequenz 
laufen, oder?

Wär super wenn Ihr mir nochmal auf die sprünge helfen könntet!

LG

von Karl H. (kbuchegg)


Lesenswert?

Es gibt auch Summer, die ganz von sich aus 'Laut geben'. Einfach an 5V 
anhängen und das Teil quäkt vor sich hin.

von Florian S. (fuxreid)


Lesenswert?

@Karl Heinz

danke für die Info. Ich hab ein bisschen geschaut, aber die sind ja doch 
relativ teuer....

http://www.conrad.de/ce/de/product/751898/SUMMER-4-8-V-L/0235210

Ich würde gerne einen einfachen Piezo-Signalgeber einbauen:

http://www.conrad.de/ce/de/product/541347/SIGNALGEBER-AL-60SP05HT/0235310


Was für eine Schaltung ist dafür notwendig??

Wäre super, wenn Du mir helfen könntest!!

MfG

von Florian S. (fuxreid)


Lesenswert?

Und ich habe noch ein weiteres Problem bei einem komplett anderen Code, 
wieder ATMEGA8 und die Hardware muss eigentlich richtig angeschlossen 
sein. Das Programm soll nichts anderes können, als bei Druck eines 
Tasters eine andere LED einzuschalten. Wie ein kleines "Menü".

Wär super wenn mir nochmal jemand einen Tipp geben könnte warum meine 
Taster in dem Programm keine Auswirkungen zeigen, also gar nichts 
machen!!

Danke schon Mal!!!!



#include <avr/io.h>
#include <util/delay.h>

volatile unsigned int modus=3;

void delay_ms (uint16_t ms)
{
  for(uint16_t t=0; t<=ms; t++)
  _delay_ms(1);
}

int main(void)
{
  DDRC &= ~ (1<<DDC4) | (1<<DDC5);
  DDRD |= (1<<DDD0) | (1<<DDD1) | (1<<DDD2) | (1<<DDD3) | (1<<DDD4) | 
(1<<DDD5);
  PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | 
(1<<PD5);

  while (1)
  {
  if (PINC & (1<<PINC4))
    {
    if (modus<5)
      {
      modus++;
      delay_ms(100);
      }
    }
  if (PINC & (1<<PINC5))
    {
    if (modus>1)
      {
      modus--;
      delay_ms(100);
      }
    }
  if(modus==1)
    {
    PORTD &= ~ (1<<PD0);
    PORTD |= (1<<PD1);
    }
  if(modus==2)
    {
    PORTD &= ~ (1<<PD1);
    PORTD |= (1<<PD0) | (1<<PD2);
    }
  if(modus==3)
    {
    PORTD &= ~ (1<<PD2);
    PORTD |= (1<<PD1) | (1<<PD3);
    }
  if(modus==4)
    {
    PORTD &= ~ (1<<PD3);
    PORTD |= (1<<PD4) | (1<<PD2);
    }
  if(modus==5)
    {
    PORTD &= ~ (1<<PD4);
    PORTD |= (1<<PD3);
    }
    return 0;
  }
 }

von Jonas M. (jonen)


Lesenswert?

return ?

von Karl H. (kbuchegg)


Lesenswert?

Da ist erst mal der return in der Schleife

Deine Taster werden höchst wahrscheinlich nach Masse schalten.
Daher sind deine Abfragen grundsätzlich falsch rum.

Aber:
Du musst unterscheiden zwischen
  mache etwas 'solange eine Taste gedrückt ist'
und
  mache etwas 'wenn eine Taste gedrückt wird'

Du willst höchst wahrscheinlich ersteres, hast aber letzteres 
programmiert.

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

von Florian S. (fuxreid)


Lesenswert?

Danke für die schnelle Antwort!

Es lag nur an dem return erstmal.
Für was steht das return?

Nach Entfernen des return "laufen die LEDs nacheinander geplant durch". 
Was müsste ich denn schreiben, damit erst wieder auf die nächste LED 
geschaltet wird, wenn ich den Taster losgelassen habe und erneut drücke?

MfG

von Klaus W. (mfgkw)


Lesenswert?

Florian S. schrieb:
> Für was steht das return?

Darauf willst du jetzt eine Antwort?

von Florian S. (fuxreid)


Lesenswert?

Tut mir leid, wenn die Frage so dumm klingt, aber ich habe vor diesem 
Projekt ein ähnliches Programm geschrieben in dem auch zum schluss 
return stand. Da hat aber alles funktioniert...

Nur desshalb frag ich, aber viel wichtiger wär mir wie ich das schreibe 
mit den Tastern.

MfG

von Karl H. (kbuchegg)


Lesenswert?

Florian S. schrieb:
> Tut mir leid, wenn die Frage so dumm klingt, aber ich habe vor diesem
> Projekt ein ähnliches Programm geschrieben in dem auch zum schluss
> return stand. Da hat aber alles funktioniert...

Dein return steht aber nicht zum Schluss :-)

in deinem anderen Projekt hattest du
1
...
2
int main()
3
{
4
  ...
5
6
  while( 1 ) {
7
    ...
8
  }
9
10
  return 0;
11
}

Hier hast du
1
...
2
int main()
3
{
4
  ...
5
6
  while( 1 ) {
7
    ...
8
9
    return 0;
10
  }
11
}

Und für die Frage, was der return macht: Bitte besorg dir ein C-Buch. Du 
wirst nicht glücklich werden ohne.

von Daniel (Gast)


Lesenswert?

Und was den Summer angeht:
Einfach an einen Portpin anschließen und den Pin mit der richtigen 
Frequenz (für maximale Lautstärke die Resonanzfrequenz des 
Piezolautsprechers) toggeln lassen.
Vielleicht noch einen kleinen Vorwiderstand von 100R davor.

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.