www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik atmega32 Zähler


Autor: benny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin nicht fit in C und Mikrocontroller und wollte daher kurz fragen 
ob die Timer so gehen könnten.

Zum einen bekomme ich Warnungen, dass meine inline Funktionen declared 
but never defined sind. Woran liegt das?

Hier meine Dateien.
timer.h
#ifndef _TIMER_H_
  #define _TIMER_H_


#include <inttypes.h>



static volatile uint8_t ms = 0;


extern inline void init_timer0(void);

extern inline void start_timer0(void);

extern inline void stop_timer0(void);


#endif // _TIMER_H_

timer.c
#include <avr/io.h>
#include <avr/interrupt.h>

#include "timer.h"


inline void init_timer0(void)
{
  TCCR0 = (1 << WGM01);

  OCR0 = 250;

  TIMSK = (1 << OCIE0);


}

inline void start_timer0(void)
{
  TCCR0 |= (1 << CS01) | (1 << CS00);
}

inline void stop_timer0(void)
{
  TCCR0 &= ~((1 << CS01) | (1 << CS00));
}


ISR(TIMER0_COMP_vect)
{
  if(ms < 0xFF) {
    ++ms;
  }
}

main.c
#include <avr/interrupt.h>

#include "timer.h"



int main(void)
{
  init_timer0();
  sei();
  start_timer0();

  while(1) {
    if(ms > 10) {
      asm volatile("nop");
    }
  }
}

Im Simulator scheint das nicht richtig zu laufen (AVRStudio scheint 
hängen zu bleiben). Dazu kommt, dass der Simulator keine 16 MHz kann.

Das Ganze soll auf einem ATmega32 mit 16 MHz jede Millisekunden die 
Variable ms hochzählen, die dann in verschiedensten Dateien des 
Projektes zugreifbar sein soll.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
benny schrieb:
> Zum einen bekomme ich Warnungen, dass meine inline Funktionen declared
> but never defined sind. Woran liegt das?

Naja, es liegt daran, dass sie deklariert, aber nicht definiert sind...

Überleg mal: In dem Header steht quasi 'inline prototyp();', den 
Funktionsrumpf packst du in ein eigenes Modul ('C-Datei'). Nun übersetzt 
du das ganze.

Wenn du jetzt in einem anderen Modul diesen Header mit den 
Inline-Dingern einbaust und den übersetzt, woher soll der Compiler denn 
wissen, was er überhaupt 'inlinen' soll? Die Funktionsrümpfe sieht er 
doch garnicht!

Autor: benny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kennt der Compiler nicht alle Dateien? Oder warum kennt der die 
Funktionsdefinitionen nicht?
Muss ich für so kleine inline Sachen dann die Definition in die .h 
packen? Dachte genau das soll man nicht tun.

Stimmt den die Configuration des Timers oder habe ich da was vergessen?

Autor: benny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich nochmal.

Habe nun meinen Timer auf der Hardware getestet und nichts geht.

timer.h
#ifndef _TIMER_H_
  #define _TIMER_H_


#include <inttypes.h>



extern volatile uint8_t ms0;



void init_timer0(void);

void start_timer0(void);

void stop_timer0(void);


#endif // _TIMER_H_

timer.c
#include <avr/io.h>
#include <avr/interrupt.h>

#include "timer.h"

volatile uint8_t ms0 = 0;


void init_timer0(void)
{
  TCCR0 = (1 << WGM01);

  OCR0 = 250;

  TIMSK |= (1 << OCIE0);


}

void start_timer0(void)
{
  TCCR0 |= (1 << CS01) | (1 << CS00);
}

void stop_timer0(void)
{
  TCCR0 &= ~((1 << CS01) | (1 << CS00));
}


ISR(TIMER0_COMP_vect)
{
  if(ms0 < 0xFF) {
    ++ms0;
  }
}

main.c
#ifndef F_CPU
  #define F_CPU 16000000UL
#endif // F_CPU


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

#include "timer.h"


int main(void)
{
  DDRB |= (1 << DDB0);

  PORTB |= (1 << PB0);

  _delay_ms(1000);

  PORTB &= ~(1 << PB0);

  init_timer0();
  sei();
  start_timer0();

  while(1)
  {
    if(ms0 >= 1000)
    {
      PORTB ^= (1 << PB0);
      ms0 = 0;
    }
  }
}

Anscheinend funktioniert das mit der globalen volatile Variable in der 
timer.h nicht. Habe allerdings auch keine wirklichen C Erfahrungen, also 
bin mir auch nicht sicher ob das wirklich so geht.

Das IF scheint irgendwie wegoptimiert zu werden.

.lss
  init_timer0();
      aa:  0e 94 2f 08   call  0x105e  ; 0x105e <init_timer0>
  sei();
      ae:  78 94         sei
  start_timer0();
      b0:  0e 94 37 08   call  0x106e  ; 0x106e <start_timer0>

  while(1)
  {
    if(ms0 >= 1000)
      b4:  80 91 dc 01   lds  r24, 0x01DC
      b8:  fd cf         rjmp  .-6        ; 0xb4 <main+0x22>

Habe ich bei der globalen Variable und/oder beim Timer ansich etwas 
falsch gemacht? Ich denke schon, nur was?

An Port B0 hängt eine LED, die eigentlich jede Sekunden umschalten 
sollte.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>volatile uint8_t ms0 = 0;
>if(ms0 >= 1000)

Fällt dir da gar nichts auf? Wertebereich beachten.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> volatile uint8_t ms0 = 0;
> if(ms0 >= 1000)

Der COmpiler denkt sich wohl:
ms0 wird wohl immer kleiner als die 1000 sein, also wozu das if?

Autor: benny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Args ganz übersehen. Als uint16_t geht es natürlich.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der COmpiler denkt sich wohl:
>ms0 wird wohl immer kleiner als die 1000 sein, also wozu das if?

Das braucht der Compiler gar nicht zu denken. Der Programmierer
tut selbst alles daß es auch so ist ;)

  if(ms0 < 0xFF) {
    ++ms0;
  }

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.