Probleme mit timer0

Gast #4669588
Lesenswert?

Hey Forum,

ich steh gerade vor einem Problem mit mein Timer0, bzw ich hab das 
gefühl erzählt bis 255 satt wie gewollt nur 72 bevor ein Interrupt 
auslöst, Vielleicht kann mal jemand drüber schauen, weil selber find ich 
den fehler nicht.

Handet sich um nen Mega16 16Mhz
1
void timer0_init()
2
{
3
  TCCR0 |= (1<<WGM01)|  (1<<CS01) |  (1<<CS00);    /* CTC Aktiv + Prescaller 1:64        */
4
  TCNT0 = 0;                      /* TCNT Register nicht aktiv          */
5
  OCR0 = 72;                      /* alle 288 us ein interrup */
6
  TIMSK |=(1<<OCIE0);                  /* Owerflow Interrups erlauben*/
7
}
8

9
ISR (TIMER0_COMP_vect)
10
{
11
  timer0++;
12
}

also im Moment sollte der timer0 alle 288us erhöht werden, doch im 
Moment hab ich das gefühl das die Erhöhung bei etwa 1,024ms.

die Berechnung ist ja richtig oder (ORC0*Prescaller)/F_CPU
#4669604
Lesenswert?

Bei 16MHz und einem Prescaler von 64 gibt es alle 4us einen Zaehlimpuls.
Und ja, wenn man auf 256 hoch zahlt ergibt das alle 1.024 ms einen 
Interrupt.

Und daraus lernt man, dass etwas mit dem Mode noch nicht stimmt. Lies 
das Kapitel CTC nochmals durch.

Allenfalls :

TIMSK |=(1<<OCIE0);   /* Owerflow Interrups erlauben*/

wird eben doch der Overflow und nicht der CTC interrupt benutzt.
Setz doch mal TCNT0 =72 und mach das im Interrupt selbst
immer wieder.
So, mit dem Overflow, wuerd's auch gehen.
Gast #4669661
Lesenswert?

also hab mir die Anleitung vom mega16 mehrmals durch gelesen aber auf 
den fehler komm ich einfach nicht.

WGM01 muss für CTC gesetzt sein ist

Presacaller 64 = gleich CS00 und 01 ist auch

ORC = 73-1 als Obergrenze ist gesetzt.

When the OCIE0 bit is written to one, and the I-bit in the Status 
Register is set (one), the
Timer/Counter0 Compare Match interrupt is enabled. The corresponding 
interrupt is executed if
a compare match in Timer/Counter0 occurs, that is, when the OCF0 bit is 
set in the Timer/Counter
Interrupt Flag Register – TIFR.

ist auch gemacht.

fehler ist immernoch da ....
Gast #4669740
Lesenswert?

1
#define F_CPU 16000000UL
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include <stdlib.h>
7
#include <stdio.h>
8
#include <stdint.h>
9

10
#define Baud    9600UL
11
#define UBBR_VALUE  ((F_CPU/(16*Baud))-1)
12

13

14
char UART_INPUT [255];
15
char UART_OUTPUT [255];
16
volatile unsigned char eingabe,counter,complete=0;  
17
volatile unsigned short timer=0,ctn=1,timer0=0,messung_start=0,messung_ende=0;
18
volatile float entfernung;
19

20
void uart_init()                    /*Inizialiserung von UART*/
21
{
22
  UBRRH = (UBBR_VALUE>>8);              /*Baudrate ins UBBR Register schreiben*/
23
  UBRRL = (UBBR_VALUE);
24
    
25
  UCSRB = (1<<TXEN) | (1<<RXEN)|(1<<RXCIE);      /* RX und TX Aktivieren , RX Interrupt aktiv*/
26
  UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);    /* Sendemodus: Synchron; 8 Bit;1 Stoppbit */
27
}
28

29
void timer0_init()
30
{
31
  TCCR0 |= (1<<WGM01)|  (1<<CS01) |  (1<<CS00);    /* CTC Aktiv + Prescaller 1:64        */
32
                        /* TCNT Register nicht aktiv          */
33
  OCR0 = 71;
34
                      /* alle 288 us ein interrup */
35
  TIMSK |=(1<<OCIE0);                  /* Owerflow Interrups erlauben*/
36

37
void uart_output(char * vektor)              /* Zeichen aus Array lesen und an Uart_senden weiterleiten */
38
{
39
  for (int a=0; a<255;a++)          /* Vektor Array um 1 erhöhen und senden*/
40
  {
41
    if(vektor[a] !=0)
42
    {
43
      uart_senden(vektor[a]);      /*Senden eines zeichen aus Vektor*/
44
    }
45
    else
46
    {
47
      break;      /*verlassen der for schleife*/
48
    }
49
  }
50
  
51
  
52
}          
53

54
char uart_empfang()                    /*abholung neuner daten vom BUS*/
55
{
56
  while(!(UCSRA & (1<<RXC)))
57
  ;
58
  return UDR;
59
}
60

61
void uart_speichern(char *pointer)            /* Speichert Zeichen in einem String*/
62
{
63
  eingabe = uart_empfang();
64
    
65
  if (complete == 0) /*Solange String nicht komplett oder zwischengespeichert*/
66
  {
67
      
68
    if (eingabe == 13)/* 13 = new line*/
69
    {
70
      
71
      pointer[counter] = 0;    /* wenn newline variable von vorne beginnen*/
72
      counter = 0;
73
      complete = 1;
74
                      /*unterbricht die while schleife*/
75
    }
76
      
77
    else
78
    {
79
    
80
      pointer[counter] = eingabe;  /*sonst nächstes zeichen scheiben*/
81
      counter++;
82
      complete = 0;
83
        
84
    }
85
  }
86
}
87

88
ISR(USART_RXC_vect)                    /* Interrupt wenn RX zeichen empfängt*/
89
{
90
  uart_speichern(UART_INPUT);  /* Zeichen in UART_INPUT speichern*/
91
}
92

93
ISR (TIMER0_COMP_vect)
94
{
95
  timer++;
96
}
97

98

99
int main(void)                      /*HAUPTPROGRAMM*/
100
{
101
  uart_init();                    /* Uart_Init ausführen*/
102
  
103
  int0_init();
104
  timer0_init();
105
  sei();                        /* Globale Interrups Aktivieren*/
106
     
107
   while (1)                      
108
    {
109
    if (complete == 1)
110
    {
111
    entfernung = (0.03434 * (messung_ende - messung_start) * 288.000)/2.000;    /* Entfernung in cm        */
112
    
113
    dtostrf(entfernung , 0 , 2 ,UART_OUTPUT);  /*float to array*/  
114
    uart_output(UART_OUTPUT);
115
    uart_output(" cm");
116
    uart_output("\r\n");
117
    utoa (messung_ende-messung_start,UART_OUTPUT,10);
118
    uart_output(UART_OUTPUT);
119
    uart_output("\r\n");
120
    utoa (timer,UART_OUTPUT,10);
121
    uart_output(UART_OUTPUT);
122
    uart_output("\r\n");
123
    
124
    complete = 0;
125
    }
126
      
127
  }
128
}
(Firma: Vescomp) #4669858
Lesenswert?

FreeMX schrieb:
> also im Moment sollte der timer0 alle 288us erhöht werden, doch im
> Moment hab ich das gefühl das die Erhöhung bei etwa 1,024ms.

> ne der fehler liegt komplett an der Hardware -.- die Erkennung der
> flanken über INT0 in us Bereich bekommt er nicht hin.

 Abgesehen davon, dass dies nicht stimmt - was hat das mit deiner Frage
 zu tun ?

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