Binär UHR Programmcode in AVR-GCC

OP #840813
Lesenswert?
• ▲
▼
Hallo,

ich programmiere im moment eine Binär Uhr und habe jetzt das Uhren 
Script fertig :)

Ich weiß das es nicht genau ist, aber ich werde das ganze bei 
gelegenheit mit einem Quarz anpassen.


Nun weiß ich allerdings nicht ob der Quellcode so stimmt (ich kann ihn 
leider auch nicht testen).


Würde mich freuen wenn ihn mal jemand schnell durchlesen könnte und mir 
sagen könnte ob das so funktioniert.


Grüße
Sebastian
Angehängte Dateien:
Gast #840815
Lesenswert?
• ▲
▼
> _delay_ms(1000);
das wird je nach verwendetem quarz nicht klappen, du solltest lieber 
einen timer verwenden (max einstellbare zeit: 262.1 ms / F_CPU in MHz)
die abfragen benötigen ja auch zeit, du hast also deine 1000ms+zeit für 
abfragen, also definitiv mehr als 1s
#840817
Lesenswert?
• ▲
▼
Einige Anfängerfehler sind enthalten:
if (s2 = 6)
muss geändert werden auf
if (s2 == 6)
sonst wird der Wert 6 zu s2 zugewiesen und das ergibt immer "Wahr"
gleiches bei h2 und m2

[edit]
noch etwas:
if (h1 > 9) && (h2 < 2)
 sollte so aussehen
if ((h1 > 9) && (h2 < 2))  oder if (h1 > 9 && h2 < 2)

[edit]
Und Strichpunkte nicht vergessen
  h2 = h2 + 1
  h1 = 0
OP #840822
Lesenswert?
• ▲
▼
wow gleich so viele Fehler ^^

Ich werde sie mal berichtigen und dann nochmal den Code schicken.

Achja @Stefan Ernst:
   Ich find den Fehler in der Logic nicht. Meinst du das ich es
   so schreiben soll oder etwas anderes?
      -> if ((h1 == 5) &&(h2 == 2))

Achja und @ Gast:
   Wie soll ich das mit dem delay_ms(1000) dann anders schreiben?

Danke schonmal für eure Hilfe.
#840846
Lesenswert?
• ▲
▼
> Wie soll ich das mit dem Delay_ms(1000) anders schreiben damit die Uhr
> genauer wird?

Du konfigurierst einen der Timer so, dass er ein mal pro Sekunde einen 
Interrupt auslöst, und in der Interruptroutine machst du dann deine 
Berechnungen. Dann ist deine Uhr so genau, wie der Takt des AVR.
Falls der Timer sich nicht auf 1s konfigurieren lässt, kannst du ihn 
z.B. auch auf 10ms programmieren, und dann erst mal eine Variable bis 
100 zählen lassen, quasi als Vorstufe zu den Sekunden.
#840907
Lesenswert?
• ▲
▼
Kenne nur die Interrupts vom IAR Compiler, bei gcc müsstest du die 
Interrupt Routine anpassen

// Initialisieren des Timers und freichalten des Interrupts
void InitUhr(void)
{
  TIMSK2 = 0;        //TC2 Interrupt Ausschalten
  ASSR = (1<<AS2);   //Timer/counter2 auf asynchronous mode (32,768kHz)
  TCNT2 = 0x00;
  TCCR2A = ((1<<CS22)|(1<<CS20)); //prescaler setzen / 128
  //Einen Uhrenquarz-takt abwarten
  while(ASSR & ((1<<TCN2UB)|(1<<OCR2UB)|(1<<TCR2UB)));
  TIMSK2 = (1<<TOIE2); //8-bit Timer/Counter2 Overflow Interrupt 
aktivieren
}


//Hauptprogramm
void main(void)
{
  ...
  InitUhr();
  while(1)
  {
    ...
  }
}

// Interrupt

#pragma vector=TIMER2_OVF_vect
void Time_Interrupt(void)
{
  // erhöhen der Urzeit
  ...
}
OP #840917
Lesenswert?
• ▲
▼
das mit dem delay_ms hab ich schneller gemacht, damit irgendwas passiert 
:)

Bei _delay_ms(1000) hat das ewig gedauert.


Werde dann mal alle so PORTA &= ~ ((1 << PA0)|(1 << PA1)|(1 << PA2)|(1 
<< PA3)); umschreiben. Hoffe das funktioniert dann.

Fals ihr noch mehr fehler findet unbedingt posten :)

Danke für eure Hilfe ich melde mich dann wieder, wenn ich das geändert 
hab.
OP #840964
Lesenswert?
• ▲
▼
naja s1 ist ja eine Variable in der immer + 1 Addiert wird ?

Vielleicht hab ich auch grad nen Denkfehler drin aber ich denke das wenn 
man das eingibt

PORTA = (s2 << 4) | s1;

dann wird als zweiter ausgang s1 ausgegeben (also zum beispiel 3) und 
das ist ja nicht binär :?

Fals ich mich jetzt irre bitte sagen :

Könnte mir vielleicht noch jemand einen Interruptbefehl mit einem 
externen Quarz (oder am besten den Internen Quarz eines ATMega 16) 
schreiben/schicken damit ich mir das mal anschauen kann (ich lerne sowas 
am besten wenn ich einen funktionierenden code vor mir habe) :)
OP #840995
Lesenswert?
• ▲
▼
#define fosc 80000000  //8 MHz Quarz zwischen XTAL 1 und XTAL 2
#define SEI __enable_interrupt()
#define CLI __disable_interrupt()

void init_Timer1(void)
{
  OCR1A = 0xBB7F;       // TOP = 47999
  TIMSK |= (1<<OCIE1A); // CTC-Interrupt zulassen
  TCCR1B = (1<<CS12) | (1<<WGM12); // Mode 4 (CTC; OCR), Timer starten 
PSC = 256
}
#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_Interrupt(void)
{
  //Hier dann das mit der Uhr rein schreiben
}

int main( void )
{
  // Variablen vereinbaren / initialisieren

  init_Timer1();

  // Interrupts freigeben
  SEI;

  while(1)
  {
  }
  return 0;
}


Würde das funktionieren ??

@Daniel: den code kapier ich nicht ^^
OP #841290
Lesenswert?
• ▲
▼
k cool :)

das wusste ich nicht :)

Da kann ich ja dann ganz schön viel code einsparen.

Was haltet ihr davon?


#define fosc 80000000  //8 MHz Quarz zwischen XTAL 1 und XTAL 2
#define SEI __enable_interrupt()
#define CLI __disable_interrupt()

void init_Timer1(void)
{
  OCR1A = 0xBB7F;       // TOP = 47999
  TIMSK |= (1<<OCIE1A); // CTC-Interrupt zulassen
  TCCR1B = (1<<CS12) | (1<<WGM12); // Mode 4 (CTC; OCR), Timer starten
PSC = 256
}
#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_Interrupt(void)
{
  //Hier dann das mit der Uhr rein schreiben
}

int main( void )
{
  // Variablen vereinbaren / initialisieren

  init_Timer1();

  // Interrupts freigeben
  SEI;

  while(1)
  {
  }
  return 0;
}
OP #841341
Lesenswert?
• ▲
▼
Also so?


#include <avr/interrupt.h>

#define fosc 80000000  //8 MHz Quarz zwischen XTAL 1 und XTAL 2

void init_Timer1(void) {

OCR1A = 0xBB7F;       // TOP = 47999
  TIMSK |= (1<<OCIE1A); // CTC-Interrupt zulassen
  TCCR1B = (1<<CS12) | (1<<WGM12); // Mode 4 (CTC; OCR), Timer starten
PSC = 256


}


ISR(TIMER1_COMPA_vect) {

  // Hier dein Uhr-Code
}


int main( void ) {

  init_Timer1();

  sei();

  while(1) {}

  return 0;
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren