mikrocontroller.net

Forum: Compiler & IDEs Timer1 Läuft nicht richtig


Autor: Richard Brose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich baue eine Uhr die Relativ genau gehen soll.
Mit dem Sourcecode ist eine Sekunde leider 16 Sekunden lang ;-(
Was mache ich falsch?
Benutze einen ATINY2313-20PU mit 16 Mhz extern Quarz.

Danke für die hilfe

Hier der Sourcecode:




#include <main.h>
#include <lcd.c>


 uint8_t second=0;
 uint8_t secled=0;
 uint8_t minute=0;
 uint8_t hour=0;

SIGNAL (SIG_OVERFLOW1)
{
   second ++;
   if(second == 60)
   {
      second = 0;
      minute ++;
   };
   if(minute == 60)
   {
      minute = 0;
      hour ++;
   };
   if(hour == 24)
   {
      hour = 0;
   };

};

//Hauptprogramm
int main (void)
{

  DDRD  = 0x00; /* alle Pins von Port D als Eingang */
  PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */

  //Initzialisierung des LCD - Displays
  LCD_Init();
  LCD_Print(1,0,"Clock");

   OCR1AL = 0x09;
   OCR1AH = 0x3d;
   TCNT1L = 0xf7;
   TCNT1H = 0xc2;
   TCCR1B |= (1<<CS10)|(1<<CS12); //1024
   TIMSK |= (1 << TOIE1);
   sei();

  unsigned char count;
  //Hauptprogramm läuft ständig in einer schleife
  while (1)
    {
    /*       if ( !(PIND & (1<<PIND4)) ) {
           count++;
         {
         if ( !(PIND & (1<<PIND5)) ) {
           count--;
         { */
        LCD_Print(0,1,"Time: %i:%i:%i",hour,minute,second);
    }
return (1);
};

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du die Fuses richtig programmiert?
Wenn nicht könnte es sein das Dein Tiny mit dem internen 1MHz Oszi
läuft.

Feadi

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den Prescaler richtig eingestellt? Versuch mal den Prescaler um
den Faktor 16 kleiner zu machen.

Autor: Richard Brose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Feadi: Die Fuses sind richtig Programmiert.

@Kai: Wie meinst du es den Prescaler um den Faktor 16 kleiner machen?
Ich habe die Werte für OCR1AL,OCR1AH,TCNT1L,TCNT1H mit dem AvrCalc
berechnet von Jack Tidwell:
http://www.electronics-lab.com/downloads/mcu/002/index.html

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke es muss so aussehen:

volatile uint8_t second=0;

Du musst alle Variablen die in einem Interrupt geändert werden mit
"volatile" deklarieren.

Sonst fällt mir noch das ein:

SIGNAL (SIG_OVERFLOW1)
{
  // Am ende von dem Signal diesen code plazieren
  // timer = overflow - cpufreq / prescaler
  TCNT1    = 0        - F_CPU   / 1024;
}

Feadi

Autor: Richard Brose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe nicht warum bei mir 1 Sekunde 10 Sekunde dauert :-(

Wie kann ich nachprüfen mit wieviel Mhz der AVR läuft? Kann man das
irgendwie messen das man 100% sicher ist?

Hab das so gemacht:

#include <main.h>
#include <lcd.c>
//#include <avr/delay.h>


 volatile uint8_t second=0;
 volatile uint8_t minute=0;
 volatile uint8_t hour=0;

SIGNAL (SIG_OVERFLOW1)
{
   second ++;
   if(second == 60)
   {
      second = 0;
      minute ++;
   };
   if(minute == 60)
   {
      minute = 0;
      hour ++;
   };
   if(hour == 24)
   {
      hour = 0;
   };
   TCNT1    = 0        - F_CPU   / 1024;
};

//Hauptprogramm
int main (void)
{

  DDRD  = 0x00; /* alle Pins von Port D als Eingang */
  PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */

  //Initzialisierung des LCD - Displays
  LCD_Init();
  LCD_Print(1,0,"Clock");

    OCR1AL = 0x09;
    OCR1AH = 0x3d;
    TCNT1L = 0xf7;
    TCNT1H = 0xc2;
    TCCR1B |= (1<<CS10)|(1<<CS12); //1024
    TIMSK |= (1 << TOIE1);
    sei();

  unsigned char count;
  //Hauptprogramm läuft ständig in einer schleife
  while (1)
    {
        LCD_Print(0,1,"Time: %i:%i:%i",hour,minute,second);
        //_delay_ms(100);
    }
return (1);
};





main.h


#ifndef MAIN_H
 #define MAIN_H

#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#include "lcd.h"

#define SYSCLK  16000000  //Quarz Frequenz in Hz
#define F_CPU 16000000

extern int main (void);

#endif //_MAIN_H_

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso beschreibst du das Timerregister TCNT1? Sollte das nicht bei 0
starten und bei erreichen des OCR1A einen ISR auslösen?

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ausserdem wäre es besser in der ISR nur das second++; zu machen und den
Rest im Main. Hat zwar hier keine Auswirkung, aber man sollte sich von
Anfang an so etwas nicht angewöhnen.

Hubert

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und im TCCR1B gehört auch noch das CTC1 Bit gesetzt

Autor: Richard Brose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir hier einer Codebeispiele zeigen? Bin noch ein Anfänger ist
nicht leicht die Tipps einzubauen.

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OCR1AL = 0x09;
OCR1AH = 0x3d;

TCCR1B |= (1<<CTC1)|(1<<CS10)|(1<<CS12); //1024
TIMSK |= (1 << TOIE1);
sei();

Initialisiere den Timer mal so. Die letzte Zeile (TCNT1=0....)in der
ISR lass weg. Den Rest aus der ISR kannst du später verlegen wenn es
mal grundsätzlich klappt.
Mit dem selben Takt kannst du auch das LCD ansteuern.

Autor: Richard Brose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der hat irgendwie probleme mit CTC1:

Compiling: main.c
avr-gcc -c -mmcu=attiny2313 -I. -g -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=main.lst  -std=gnu99 main.c -o main.o
main.c:19: warning: `SIG_OVERFLOW1' appears to be a misspelled signal
handler
main.c: In function `main':
main.c:52: error: `CTC1' undeclared (first use in this function)
main.c:52: error: (Each undeclared identifier is reported only once
main.c:52: error: for each function it appears in.)

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du noch einen älteren Compiler hast ist das WGM12

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.