www.mikrocontroller.net

Forum: Compiler & IDEs Anfängerproblem: Interner Zähler


Autor: Björn G. (feathyr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag,

Ich fange gerade an meine ersten Schritte mit Mikrocontrollern zu wagen. 
Für diese  ersten Versuche habe ich mir einen ATMEGA8535 zugelegt.

Nun habe ich versucht den internen Zähler zu benutzen um mir die 
vergangene Zeit auf einem Port per LEDs anzeigenzu lassen. Idee war den 
so lange zählen zu lassen bis eine Sekunde rum ist und ihn dann per 
Interrupt das Register des Port D zu inkrementieren lassen.

Das Program habe ich mir aber nicht selber ausgedacht sondern es stammt 
hier von der Seite aus dem GCC Tutorial.
Ich benutze AVR Studio 4.17 und einen AVRISP mkII. Sowohl beim 
Simulieren, als auch auf dem Mikroncontroller funktioniert das Programm 
aber nicht. Und ich bin Ratlos wieso.

Hier erstmal das programm:

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

volatile unsigned int  millisekunden=0;
volatile unsigned int  sekunde=0;
volatile unsigned int  minute=0;
volatile unsigned int  stunde=0;


main ()
{
  DDRD=0xFF;

     TCCR0 =(1<<WGM01) |(1<<CS01);
    OCR0=125;
    TIMSK|=(1<<OCIE0);
    sei();

     while(1){
    PORTD=sekunde;
    }
}

ISR (TIMER0_COMP_vect)
{
     millisekunden++;

     if(millisekunden==1000)
     {
      sekunde++;
       millisekunden=0;

      if(sekunde==60)
       {
           minute++;
         sekunde=0;
      }
      if(minute ==60)
        {
         stunde++;
          minute=0;
      }
   }
}


Ich habe beim Simulieren entdeckt, das am Anfang das Register OCR0 nicht 
geschrieben wird, aber später wird das Register ja mit dem Counter 
verglichen, ergo springt er nie in die Interruptroutine. Aber ich bin 
mit meinem bischen Latein am Ende wo es hier hängt.

Grüße Björn

Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmm. Bei mir (AvrSTudio16Build628, WinAvr09032009) funktioniert das 
Programm im Simulator 1. Bei 1Mhz Takt wird ein Breakpoint, der in der 
Zeile
sekunde++;
liegt, alle 1008ms aufgerufen. Wenn du die Zeile
OCR0=125;
zu
OCR0=124;
ändern würdest dann hättest du auch exakt 1000ms.

Dein Problem muss irgendwo anders sein. Hast du in den Projektoptionen 
alles richtig eingestellt? Die Kommandozeile beim Compilieren müsste 
etwa so aussehen:
avr-gcc  -mmcu=atmega8535 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test.o -MF dep/test.o.d  -c  ../test.c
avr-gcc -mmcu=atmega8535 -Wl,-Map=test.map test.o     -o test.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  test.elf test.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex test.elf test.eep || exit 0
avr-objdump -h -S test.elf > test.lss

Autor: Björn G. (feathyr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal deine Vermutung war richtig, ich hatte den Takt nicht in 
den Projektoptioinen eingestellt :)

Allerdings läuft das Programm immer noch nicht.
Beim Debugging ist mir aufgefallen, das das OCIE0 Bit im TIMSK Register 
nicht gesetzt wird, also springt er ja nicht in die Interrupt Routine. 
Der Zähler funktioniert jetzt richtig, er zählt hoch bis 124 und bricht 
dann ab, bzw beginnt von neuem Hochzuzählen. Allerdings wird die ISR nie 
aufgerufen. Das verstehe ich nicht, laut anweisungen soll er das Bit ja 
setzten, nur warum tut er es bei mir nicht?

Und bei Compilieren erhalte ich jetzt folgende Meldung:
Build started 10.8.2009 at 09:57:50
avr-gcc  -mmcu=atmega8535 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT Breadboard.o -MF dep/Breadboard.o.d  -c  ../Breadboard.c
../Breadboard.c:12: warning: return type defaults to 'int'
avr-gcc -mmcu=atmega8535 -Wl,-Map=Breadboard.map Breadboard.o     -o Breadboard.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  Breadboard.elf Breadboard.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex Breadboard.elf Breadboard.eep || exit 0
avr-objdump -h -S Breadboard.elf > Breadboard.lss

AVR Memory Usage
----------------
Device: atmega8535

Program:     298 bytes (3.6% Full)
(.text + .data + .bootloader)

Data:          8 bytes (1.6% Full)
(.data + .bss + .noinit)


Build succeeded with 1 Warnings...

c12 meint das Zeile 12 im Original c-code, oder bezieht sich das bereits 
auf das compilierte?

Und was für auswirkungen hat dieses Warnung, ich habe den verdacht, dass 
das vllt Teil des Problems sein könnte.

Gruß Björn

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Björn Gustäbel schrieb:

>
> c12 meint das Zeile 12 im Original c-code, oder bezieht sich das bereits
> auf das compilierte?

Das wäre ziemlich sinnlos.
Die Zeilennummer bezieht sich auf den Code, so wie du ihn geschrieben 
hast.

> Und was für auswirkungen hat dieses Warnung, ich habe den verdacht, dass
> das vllt Teil des Problems sein könnte.

Es geht um main()
main()
{
  ...
}

Auch main ist aus C-Sicht nichts anderes als eine Funktion. So wie jede 
andere Funktion auch, hat auch main() einen Returntyp. Gibst du nichts 
an, dann greifen die C-Default Regeln, welche vorschreiben, das der 
Returntyp einer Funktion int ist. Das kann richtig sein, kann aber auch 
völlig falsch sein. Daher warnt dich der Compiler.

In deinem Fall ist es das Richtige. Trotzdem ist es besser, wenn du dich 
nicht auf Default-Regeln verlässt, sondern die Dinge beim Namen nennst

int main( void )
{
  ...
}

Autor: Björn G. (feathyr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke sehr euch allen, jetzt habe ich keine Warnung mehr, und das 
Programm läuft, anscheinend hat er sich daran, dass ich nur main() 
geschrieben habe so sehr gestört, dass er das TIMSK Register nicht 
gesetzt hat. Warum auch immer :)

Jetzt funktioniert alles

Besten Dank

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Björn Gustäbel schrieb:
> Danke sehr euch allen, jetzt habe ich keine Warnung mehr, und das
> Programm läuft, anscheinend hat er sich daran, dass ich nur main()
> geschrieben habe so sehr gestört, dass er das TIMSK Register nicht
> gesetzt hat. Warum auch immer :)

Das kann nicht sein.
Dem Debugger ist es egal, ob du beim Compilieren Warnungen hast oder 
nicht. Der simuliert den Code, so wie ihn der Compiler erzeugt. Und auch 
bei mir läuft der Simulator völlig korrekt durch. Selbst wenn die 
Warnung da ist.

Autor: Björn G. (feathyr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann haben heute Nacht irgendwelche Heinzelmännchen meinen Code 
Repariert, weil ich habe da nichts weiter geändert, außer main() zu int 
main (void), achja und den Takt habe ich in den Projektoptionen 
eingestellt, das waren die Unterschiede zu gestern Abend.

Nachdem ich den Takt einstellte lief das Programm immer noch nicht, erst 
als ich die änderung an der main vornahm lief das Programm durch.

Vllt liegts ja auch daran, dass ich AVR Studio 4.17 verwende, das stammt 
ja von der Beta Seite aus Norwegen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Björn Gustäbel schrieb:
> Dann haben heute Nacht irgendwelche Heinzelmännchen meinen Code
> Repariert, weil ich habe da nichts weiter geändert, außer main() zu int
> main (void), achja und den Takt habe ich in den Projektoptionen
> eingestellt, das waren die Unterschiede zu gestern Abend.
>
> Nachdem ich den Takt einstellte lief das Programm immer noch nicht, erst
> als ich die änderung an der main vornahm lief das Programm durch.
>
> Vllt liegts ja auch daran, dass ich AVR Studio 4.17 verwende, das stammt
> ja von der Beta Seite aus Norwegen.

Ich habe 4.13

Und ja, höchstwahrscheinlich gab es noch eine Änderung:
Du hast den Rechner rebootet oder zumindest deine Entwicklungsumgebung 
neu gestartet.
Lach jetzt nicht. Manchmal verklemmt sich tatsächlich der 
Make-Mechanismus und dann werden notwendige Updates nicht gemacht. 
Sollte nicht vorkommen, kommt aber in jeder Entwicklungsumgebung 
manchmal vor. Zb. Microsofts Dev-Studio war zumindest früher berühmt 
dafür, dass ein komplettes Löschen der Generierverzeichnisse so manchen 
seltsamen/unerklärlichen Fehler behoben hat.

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.