Forum: Mikrocontroller und Digitale Elektronik Sekundenzeiger läuft zu schnell


von Hain (Gast)


Lesenswert?

Hallo,

wieso läuft meine Uhr zu schnell? Atmega328P mit externen 16MHz Quarz.
Die Daten werden viel zu schnell geschickt.
1
BODLEVEL = 2V7
2
RSTDISBL = [ ]
3
DWEN = [ ]
4
SPIEN = [X]
5
WDTON = [ ]
6
EESAVE = [ ]
7
BOOTSZ = 1024W_3C00
8
BOOTRST = [X]
9
CKDIV8 = [ ]
10
CKOUT = [ ]
11
SUT_CKSEL = EXTXOSC_8MHZ_XX_16KCK_14CK_65MS
12
13
EXTENDED = 0xFD (valid)
14
HIGH = 0xDA (valid)
15
LOW = 0xFF (valid)
1
/*
2
* USART.c
3
*
4
* Erstellt: 17.07.2014 03:08:12
5
*   Author: sschultewolter
6
*/
7
8
9
#define F_CPU 16000000UL
10
#include <avr/io.h>
11
#include <avr/interrupt.h>
12
#include <util/delay.h>
13
#include <stdlib.h>
14
15
#define BAUDRATE 9600
16
#define BAUD_PRESCALLER (((F_CPU/(BAUDRATE*16UL)))-1)
17
18
volatile unsigned int ms;
19
volatile unsigned int s;
20
volatile unsigned int min;
21
volatile unsigned int h;
22
23
void USART_init(void);
24
unsigned char USART_receive(void);
25
void USART_send( unsigned char data);
26
void USART_putstring(char* StringPtr);
27
28
void TIMER_init(void);
29
30
char String[] = "Hello world\n\r";
31
32
int main(void)
33
{
34
  USART_init();
35
  TIMER_init();
36
  
37
  while(1)
38
  {
39
    if(s%2 == 0)
40
    {      
41
      USART_putstring(String);
42
    }
43
  }
44
}
45
46
void USART_init(void)
47
{
48
  UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
49
  UBRR0L = (uint8_t)(BAUD_PRESCALLER);
50
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
51
  UCSR0C = (3<<UCSZ00);
52
}
53
54
unsigned char USART_receive(void)
55
{
56
  while(!(UCSR0A & (1<<RXC0)));
57
  return UDR0;
58
}
59
60
void USART_send( unsigned char data)
61
{
62
  while(!(UCSR0A & (1<<UDRE0)));
63
  UDR0 = data;
64
}
65
66
void USART_putstring(char* StringPtr)
67
{
68
  while(*StringPtr != 0x00)
69
  {
70
    USART_send(*StringPtr);
71
    StringPtr++;
72
  }
73
}
74
75
void TIMER_init(void)
76
{
77
  TCCR0A = (1<<WGM01);
78
  TCCR0B |= (1<<CS01);
79
  OCR0A = 125-1;
80
  TIMSK0 |= (1<<OCIE0A);
81
  sei();
82
}
83
84
ISR (TIMER0_COMPA_vect)
85
{
86
  ms++;
87
  if(ms == 1000)
88
  {
89
    s++;
90
    ms = 0;
91
    if(s == 60)
92
    {
93
      min++;
94
      s = 0;
95
    }
96
    if(min == 60)
97
    {
98
      h++;
99
      min = 0;
100
    }
101
    if(h == 24) h = 0;
102
  }
103
}

von spess53 (Gast)


Lesenswert?

Hi

Du hast dich verrechnet.

>  TCCR0B |= (1<<CS01);
>  OCR0A = 125-1;

ergibt einen Timerinterrupt alle 62,5µs

Die 1ms bekommst du mit Prescaler=64 und OCR0A=249.

MfG Spess

von Stefan S. (sschultewolter)


Lesenswert?

Danke,
sieht nun richtig aus
1
  TCCR0B |= (1<<CS01 | 1<<CS00);
2
  OCR0A = 249;

von spess53 (Gast)


Lesenswert?

Hi

>sieht nun richtig aus

Wie es aussieht ist egal. Hauptsache es funktioniert jetzt richtig.

MfG Spess

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.