Forum: Mikrocontroller und Digitale Elektronik ATmega resettet dauernd


von Mathias O. (m-obi)


Lesenswert?

Morgen,

ich hab mal wieder mein Pollin-Board rausgekramt um ein wenig zu 
"spielen".
Dabei will ich mich mal bei IRMP + ENC28J60 versuchen.
Ich hab nun ein seltsames Verhalten, dass sich anscheinend der µC 
dauernd resettet. Ich hab mal ein Beispielcode geschrieben, womit das 
reproduzierbar ist. Das schnelle Blinken was am Anfang ist, macht er 
dauernd und das langsame Blinken in der Schleife macht er garnicht, da 
bleibt konstant die LED an. Achja es ist ein ATmega16 @ 16Mhz. 
Wahrscheinlich seh ich wieder den Wald vor lauter Bäumen nicht.
1
#ifndef F_CPU
2
    #define F_CPU 16000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <avr/pgmspace.h>
8
#include <util/delay.h>
9
#include <stdlib.h>
10
#include <stdio.h>
11
#include "uart.h"
12
#include "irmpconfig.h"
13
#include "irmp.h"
14
15
#define BAUD 19200UL
16
17
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
18
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
19
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
20
21
#define US (1000000 / F_INTERRUPTS)
22
23
24
void timer1_init(void);
25
26
static int UARTsendstream(char c, FILE *stream);
27
28
static FILE uart_str = FDEV_SETUP_STREAM(UARTsendstream, NULL, _FDEV_SETUP_WRITE);
29
30
31
int main(void){
32
    IRMP_DATA irmp_data;
33
34
    uart_init(UART_BAUD_SELECT(BAUD, F_CPU));
35
    stdout = &uart_str;
36
37
    DDRD |= (1 << PD5)|(1 << PD6);
38
39
    PORTD |= (1 << PD5);
40
    _delay_ms(400);
41
    PORTD &= ~(1 << PD5);
42
    _delay_ms(200);
43
    PORTD |= (1 << PD5);
44
    _delay_ms(400);
45
    PORTD &= ~(1 << PD5);
46
    _delay_ms(1000);
47
48
    irmp_init();
49
    timer1_init();
50
    sei();
51
52
    while(1){
53
        PORTD |= (1 << PD6);
54
        _delay_ms(500);
55
        PORTD &= ~(1 << PD6);
56
        _delay_ms(500);
57
    }
58
}
59
60
void timer1_init(void){
61
    OCR1A = (F_CPU / F_INTERRUPTS) - 1;
62
    TCCR1B = (1 << WGM12)|(1 << CS10);
63
64
    TIMSK = 1 << OCIE1A;
65
}
66
67
static int UARTsendstream(char c , FILE *stream){
68
    uart_putc(c);
69
    return 0;
70
}
71
72
ISR(TIMER1_COMPA_vect){
73
    (void) irmp_ISR();
74
}

von Stefan F. (Gast)


Lesenswert?

Kommentier diese Zeilen mal aus:

    irmp_init();
    (void) irmp_ISR();

Wenn es dann geht, liegt der Fehler im Code dieser Library bzw. 
irgendwelche Voraussetzungen sind nicht erfüllt, die sie zum 
Funktionieren benötigt.

von Mathias O. (m-obi)


Lesenswert?

Ne immer noch nicht. Warum sollte auch die Lib ausgerechnet bei mir 
nicht funktionieren. Bei Anderen läuft sie ja.

Edit:
Wenn ich
1
timer1_init();
und
1
sei();
auskommentiere, funktioniert es.

: Bearbeitet durch User
von tictactoe (Gast)


Lesenswert?

Vielleicht compiliert der Compiler für den falschen Controller, sodass 
der Interruptvektor für COMPA am falschen Index steht?

Ist vielleicht der Watchdog eingeschaltet?

von Mathias O. (m-obi)


Lesenswert?

Also es ist -mmcu=atmega16, somit stimmt das.

Wo kann man denn den Watchdog ausschalten?

von kif (Gast)


Lesenswert?

Füg mal das am Ende ein:
1
ISR(BADISR_vect) { }

und kommentier das "sei()" und "timer1_init()" wieder ein!

von Oliver S. (oliverso)


Lesenswert?

Mathias O. schrieb:
> Wo kann man denn den Watchdog ausschalten?

Da, wo man ihn auch einschaltet...

Überprüf mal die Fuses..

in 99% aller Fääle kommt das gezeigte Verhalten durch einen Interrupt 
ohne zugehörige ISR. Da es funktioniert, wenn du das sei 
auskommentierst, such halt mal, welche Interrupts alle freigegeben sind.

Oliver

von spess53 (Gast)


Lesenswert?

Hi

>Wo kann man denn den Watchdog ausschalten?

Hast du den denn eingeschaltet?

>Wenn ich
>timer1_init();
>und
>sei();
>auskommentiere, funktioniert es.

Dann hat es auch nichts mit dem WD zu tun.

MfG Spess

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mathias O. schrieb:
> Also es ist -mmcu=atmega16, somit stimmt das.
>
> Wo kann man denn den Watchdog ausschalten?

Ein ähnliches Problem hatte mal einer mit ATmega16 und STK500.

Schau mal hier:

  Beitrag "ATMega16: Interrupt mit Timer1"

Da war's jedenfalls der Watchdog, Lösung steht am Ende des (kurzen) 
Threads auch dabei.

Was mich aber wundert: Sobald Du timer1_init() und sei() rausnimmst, 
funktioniert es? Dann müsste es auch gehen, wenn Du nur sei() 
rausnimmst. Kannst Du das mal testen?

Bekommst Du beim Übersetzen irgendwelche Compiler-Warnungen?

Der Code ist ja nicht vollständig, es fehlen ja noch die uart-Routinen. 
Benutzen diese vielleicht Interrupts - eingeschaltet durch uart_init() - 
mit falschem Interrupt-Vektor? Dann solltest Du aber eine Warnung vom 
Compiler erhalten.

: Bearbeitet durch Moderator
von Mathias O. (m-obi)


Lesenswert?

Also mit dem disablen des Watchdogs ist es auch nicht besser.
Die Uart-Routinen sind von Fleury. Die haben sich auch schon mehfach 
bewährt.
Die Fuses sind 0xFE(low) 0xC9(high).
Warnungen bekomme ich keine.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Mathias O. schrieb:
> Warum sollte auch die Lib ausgerechnet bei mir
> nicht funktionieren. Bei Anderen läuft sie ja.

Na ja, das könnte man jetzt kommentieren...

Egal, häng halt mal eine kompletten kompilierbaren Code hier an.

Oliver

von kif (Gast)


Lesenswert?

Oliver S. schrieb:
> Mathias O. schrieb:
>> Warum sollte auch die Lib ausgerechnet bei mir
>> nicht funktionieren. Bei Anderen läuft sie ja.
>
> Na ja, das könnte man jetzt kommentieren...
>
> Egal, häng halt mal eine kompletten kompilierbaren Code hier an.
>
> Oliver

Wenn es einfach funktionieren soll, dann füg das in den Code ein:
ISR(BADISR_vect) { }

und es wird funktionieren.

Es wird irgendein Interrupt ausgelöst bei dem keine ISR definiert ist, 
dann springt das Programm jedesmal an den Anfang wenn das entsprechende 
Interrupt ausgelöst wird.

von Mathias O. (m-obi)


Angehängte Dateien:

Lesenswert?

So hier ist mal ein kompilierbarer Code.
1
#ifndef F_CPU
2
    #define F_CPU 16000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <util/delay.h>
8
#include "irmpconfig.h"
9
#include "irmp.h"
10
11
12
void timer1_init(void);
13
14
int main(void){
15
    DDRD |= (1 << PD5)|(1 << PD6);
16
17
    PORTD |= (1 << PD5);
18
    _delay_ms(400);
19
    PORTD &= ~(1 << PD5);
20
    _delay_ms(200);
21
    PORTD |= (1 << PD5);
22
    _delay_ms(400);
23
    PORTD &= ~(1 << PD5);
24
    _delay_ms(1000);
25
26
    timer1_init();
27
    sei();
28
29
    while(1){
30
        PORTD |= (1 << PD6);
31
        _delay_ms(500);
32
        PORTD &= ~(1 << PD6);
33
        _delay_ms(500);
34
    }
35
}
36
37
void timer1_init(void){
38
    OCR1A = (F_CPU / F_INTERRUPTS) - 1;
39
    TCCR1B = (1 << WGM12)|(1 << CS10);
40
41
    TIMSK = 1 << OCIE1A;
42
}
43
44
ISR(TIMER1_COMPA_vect){
45
    (void) irmp_ISR();
46
}

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

1
> #ifndef F_CPU
2
>     #define F_CPU 16000000UL
3
> #endif

Das ist schon mal Käse. Damit kannst Du nicht gewährleisten, dass die 
anderen Module (uart, irmp) mit der gleichen F_CPU compiliert werden.

Setz dies als Compiler-Option im Makefile oder Projekt für alle 
C-Dateien.
1
> #include "irmpconfig.h"
2
> #include "irmp.h"

Du benutzt hier einen 2 Jahre alten IRMP. Hole Dir bitte die aktuelle 
Version, siehe IRMP. Bei aktuellen Versionen darfst Du auch nur noch 
irmp.h "includieren".

Woran erkennst Du eigentlich, dass der ATmega resettet wird? Fängt er 
(wie am Anfang) an zu blinken?

Folgende Fragen hast Du vergessen, zu beantworten:

Reicht auch das Auskommentieren von sei() alleine, damit der ATmege 
läuft?

Funktioniert das Programm mit
1
ISR(BADISR_vect)
2
{
3
}

auch bei eingeschaltetem sei()?


P.S.
Du schriebst, dass der Fehler auch ohne Aufruf von irmp_init() und 
irmp_ISR() auftritt.

Dann hast Du aber nicht das minimalste Programm gepostet. Das wäre 
nämlich ohne die beiden Aufrufe und ohne die irmp-Includes und ohne 
irmp-Source-Dateien gewesen. Teste das bitte nochmal.

: Bearbeitet durch Moderator
von Mathias O. (m-obi)


Lesenswert?

Minimalistisch sieht es so aus.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
//#include "irmp.h"
5
6
#ifndef F_CPU
7
#error F_CPU unkown
8
#endif
9
10
#define F_INTERRUPTS 15000
11
12
void timer1_init(void);
13
14
int main(void){
15
    DDRD |= (1 << PD5)|(1 << PD6);
16
17
    PORTD |= (1 << PD5);
18
    _delay_ms(400);
19
    PORTD &= ~(1 << PD5);
20
    _delay_ms(200);
21
    PORTD |= (1 << PD5);
22
    _delay_ms(400);
23
    PORTD &= ~(1 << PD5);
24
    _delay_ms(1000);
25
26
    //IRMP_DATA irmp_data;
27
28
    //irmp_init();
29
    timer1_init();
30
    sei();
31
32
    while(1){
33
        PORTD |= (1 << PD6);
34
        _delay_ms(500);
35
        PORTD &= ~(1 << PD6);
36
        _delay_ms(500);
37
    }
38
}
39
40
void timer1_init(void){
41
    OCR1A = (F_CPU / F_INTERRUPTS) - 1;
42
    TCCR1B = (1 << WGM12)|(1 << CS10);
43
44
    TIMSK = 1 << OCIE1A;
45
}
46
47
ISR(TIMER1_COMPA_vect){
48
    //(void) irmp_ISR();
49
}
Funktioniert auch nicht.
Wenn ich sei(); auskommentiere funktioniert es.

Das resetten merke ich daran, dass er das schnelle Blinken vom Anfang 
(PD5) macht.

Das
1
ISR(BADISR_vect)
2
{
3
}
ändert auch nix.

von Karl H. (kbuchegg)


Lesenswert?

> Also mit dem disablen des Watchdogs ist es auch nicht besser.

Wie jetzt?
War der aktiviert oder nicht?


> Wenn ich sei(); auskommentiere funktioniert es.

Dann bleibt nicht mehr viel.
Normalerweise würde ich jetzt sagen: du compilierst für den falschen 
Prozessor.

von Konrad S. (maybee)


Lesenswert?

Karl Heinz schrieb:
> Normalerweise würde ich jetzt sagen: du compilierst für den falschen
> Prozessor.

Oder evtl. unterschiedliche µCs für Kompilieren und Linken angegeben?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mathias O. schrieb:
> Minimalistisch sieht es so aus.

Bin jetzt auch ratlos. Das Ding müsste auch mit sei() laufen.

Kannst Du mal die Kommandos kopieren und hier einfügen, die beim 
Kompilieren bzw. Linken durchgeführt werden?

: Bearbeitet durch Moderator
von Oliver S. (oliverso)


Lesenswert?

"Hängen bleiben" würde das wohl auch, wenn der Prozessor nicht mit 
16Mhz, sondern nur mit 1MHz laufen würde. Die oben genannten Fuses sind 
aber auch richtig.

Oliver

von Mathias O. (m-obi)


Lesenswert?

Na toll. Hab es jetzt geschafft. In Code::Blocks gibt man den mmcu in 
den Buildoptions an. Ich hab ihn allgemein beim Projekt angegeben, dann 
kann man ihn aber auch noch angeben bei debug und release. Ich hab ihn 
jetzt mal release auch noch angegeben, sowie F_CPU.
Und siehe da es funktioniert.
Der Output sieht nun so aus.
1
avr-gcc.exe -mmcu=atmega16 -DF_CPU=16000000UL  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c main.c -o obj\Release\main.o

Danke nochmal an alle für die Hilfe. Ich kam mir echt schon bescheuert 
vor.
Wenn es ne Kaffekasse geben würde, würde ich da jetzt was reinschmeissen 
;)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mathias O. schrieb:
> Hab es jetzt geschafft.

Gratulation.

Fällt Dir hier was auf?
1
  -mmcu=atmega16 -DF_CPU=16000000UL  -mmcu=atmega16 -Os -DF_CPU=16000000UL

Da ist was doppelt gemoppelt.

> Wenn es ne Kaffekasse geben würde, würde ich da jetzt was reinschmeissen
> ;)

Ich hol mir den Kaffee auch ohne Kasse.... nämlich jetzt! :-)

: Bearbeitet durch Moderator
von Konrad S. (maybee)


Lesenswert?

Es wäre noch interessant zu wissen, wie die Aufrufe vorher aussahen, 
einmal beim Kompilieren von main.c und einmal beim Linken des Programms.

von Mathias O. (m-obi)


Lesenswert?

Guten Morge,

so langsam fühle ich mich echt verarscht. Ich wollte jetzt den UART 
ansprechen und wollte die Lib von Fleury verwenden. Sobald ich wieder 
sei(); drin habe, macht er nur das Blinken vom Anfang und geht nicht in 
die Schleife rein.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
7
#include "uart.h"
8
9
#define UART_BAUD_RATE 9600UL
10
11
12
int main(void){
13
    DDRD |= (1 << PD5)|(1 << PD6);
14
15
    PORTD |= (1 << PD5);
16
    _delay_ms(100);
17
    PORTD &= ~(1 << PD5);
18
    _delay_ms(300);
19
    PORTD |= (1 << PD5);
20
    _delay_ms(100);
21
    PORTD &= ~(1 << PD5);
22
    _delay_ms(300);
23
    PORTD |= (1 << PD5);
24
    _delay_ms(100);
25
    PORTD &= ~(1 << PD5);
26
    _delay_ms(800);
27
28
    uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
29
30
    sei();
31
32
    uart_puts_P("Hallo\n");
33
34
    while(1){
35
        uart_puts_P("Test\n");
36
        PORTD |= (1 << PD6);
37
        _delay_ms(500);
38
        PORTD &= ~(1 << PD6);
39
        _delay_ms(500);
40
    }
41
}
Ich frage mich warum das so ein Krampf ist. Als ich das zuletzt vor 
Monaten mit einem mega8 gemacht habe funktionierte alles.
Ich hab jetzt auch nochmal einen anderen mega16 genommen, aber der zeigt 
das selbe Verhalten.
Ich bin echt ratlos.

von tictactoe (Gast)


Lesenswert?

Mathias O. schrieb:
>     uart_puts_P("Hallo\n");

Wahrscheinlich sollte das

      uart_puts_P(PSTR("Hallo\n"));

lauten, oder täusch ich mich?

von Mathias O. (m-obi)


Lesenswert?

dafür gibts ja
#define uart_puts_P(__s)       uart_puts_p(PSTR(__s))
im header.

von Ellen Moore (Gast)


Lesenswert?

Mal ne Frage. Welches Board ist das? Beim AVR Net-IO gabs Versionen mit 
Problemen mit der Spannungsversorgung ... nur so als Anregung.

von MWS (Gast)


Lesenswert?

Mathias O. schrieb:
> uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));

Schreib doch mal 16000000UL statt des F_CPU rein.

von Mathias O. (m-obi)


Lesenswert?

Ich hab das normale Pollin-Board. 4,82V mess ich am mega.
Auch mit 16000000UL direkt klappt es nicht. Wenn F_CPU nicht stimmen 
würde, würde es doch auch nicht im richtigen Takt blinken oder?

von MWS (Gast)


Lesenswert?

Mathias O. schrieb:
> würde es doch auch nicht im richtigen Takt blinken oder?

Auch richtig. Kannst Du den Code simulieren und die Register 
untersuchen? So wie jetzt stocherst Du im Nebel.

In der uart.c der Fleury Lib sind conditional defines drin, um auf die 
verschiedenen µCs anzupassen. Wenn da das Symbol des Prozessors (s.o.) 
nicht klar ist, könnt's zu Problemen kommen.

Da sollten aber Meldungen vom Compiler kommen, was steht in der Ausgabe?

von lmao (Gast)


Lesenswert?

Mathias O. schrieb:
> Guten Morge,
>
> so langsam fühle ich mich echt verarscht.

Das Problem sitzt meist vorm Rechner

von Mathias O. (m-obi)


Lesenswert?

lmao schrieb:
> Mathias O. schrieb:
>> Guten Morge,
>>
>> so langsam fühle ich mich echt verarscht.
>
> Das Problem sitzt meist vorm Rechner
Soweit bin ich auch schon gekommen.


Ausgabe sieht so aus:
1
-------------- Build: Release in IRMP (compiler: GNU AVR GCC Compiler)---------------
2
3
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c main.c -o obj\Release\main.o
4
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c uart.c -o obj\Release\uart.o
5
avr-g++.exe -LD:\opencv\build\x86\mingw\lib  -o bin\Release\IRMP.elf obj\Release\main.o obj\Release\uart.o   -Wl,-Map=bin\Release\IRMP.map,--cref  
6
Output size is 2.98 KB
7
Running project post-build steps
8
cmd /c "avr-objdump -h -S bin\Release\IRMP.elf > bin\Release\IRMP.lss"
9
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex bin\Release\IRMP.elf bin\Release\IRMP.hex
10
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.eep
11
avr-objcopy --no-change-warnings -j .lock --change-section-lma .lock=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.lock
12
avr-objcopy --no-change-warnings -j .signature --change-section-lma .signature=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.sig
13
avr-objcopy --no-change-warnings -j .fuse --change-section-lma .fuse=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.fuse
14
srec_cat bin\Release\IRMP.fuse -Intel -crop 0x00 0x01 -offset  0x00 -O bin\Release\IRMP.lfs -Intel
15
srec_cat: bin\Release\IRMP.fuse: 1: file contains no data
16
Process terminated with status 1 (0 minutes, 0 seconds)
17
0 errors, 0 warnings (0 minutes, 0 seconds)

von Oliver S. (oliverso)


Lesenswert?

Mathias O. schrieb:
> avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c main.c -o
> obj\Release\main.o
> avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c uart.c -o
> obj\Release\uart.o
> avr-g++.exe -LD:\opencv\build\x86\mingw\lib  -o bin\Release\IRMP.elf
> obj\Release\main.o obj\Release\uart.o
> -Wl,-Map=bin\Release\IRMP.map,--cref

Für einen avr ist der Lib-Pfad völlig unsinnig, dafür fehlen da ein paar 
der sonst üblichen Optionen. Bist du sicher, daß deine IDE auch 
tatasächlich AVR-Programme erezugen kann, und dafür richtig eingestellt 
ist?

Lass dir mal mit MFile ein makefile erezugen, und compiler damit. Oder 
pack deine Sourcen ins AVR-Studio, und lass das mal kompilieren.

Oliver

von Mathias O. (m-obi)


Lesenswert?

Habs es entfernt. Hab nun
1
-------------- Build: Release in IRMP (compiler: GNU AVR GCC Compiler)---------------
2
3
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c main.c -o obj\Release\main.o
4
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c uart.c -o obj\Release\uart.o
5
avr-g++.exe  -o bin\Release\IRMP.elf obj\Release\main.o obj\Release\uart.o   -Wl,-Map=bin\Release\IRMP.map,--cref  
6
Output size is 2.78 KB
7
Running project post-build steps
8
cmd /c "avr-objdump -h -S bin\Release\IRMP.elf > bin\Release\IRMP.lss"
9
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex bin\Release\IRMP.elf bin\Release\IRMP.hex
10
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.eep
11
avr-objcopy --no-change-warnings -j .lock --change-section-lma .lock=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.lock
12
avr-objcopy --no-change-warnings -j .signature --change-section-lma .signature=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.sig
13
avr-objcopy --no-change-warnings -j .fuse --change-section-lma .fuse=0 -O ihex bin\Release\IRMP.elf bin\Release\IRMP.fuse
14
srec_cat bin\Release\IRMP.fuse -Intel -crop 0x00 0x01 -offset  0x00 -O bin\Release\IRMP.lfs -Intel
15
srec_cat: bin\Release\IRMP.fuse: 1: file contains no data
16
Process terminated with status 1 (0 minutes, 0 seconds)
17
0 errors, 0 warnings (0 minutes, 0 seconds)
Wenn er keine AVR-Programme erzeugen würde, warum blinkt dann die Led 
wie im Programm vorgegeben?
Irgendwas scheint mit dem Interrupt im UART nicht zu funktionieren.

Wenn ich statt
1
void uart_putc(unsigned char data)
2
{
3
    unsigned char tmphead;
4
5
6
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
7
8
    while ( tmphead == UART_TxTail ){
9
        ;/* wait for free space in buffer */
10
    }
11
12
    UART_TxBuf[tmphead] = data;
13
    UART_TxHead = tmphead;
14
15
    /* enable UDRE interrupt */
16
    UART0_CONTROL    |= _BV(UART0_UDRIE);
17
18
}/* uart_putc */
das so verwende
1
void uart_putc(unsigned char data)
2
{
3
    while
4
    (!(UCSRA & (1<<UDRE)))
5
    {
6
    }
7
    UDR = data;
8
9
}/* uart_putc */
funktioniert es.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mathias O. schrieb:
>     UART0_CONTROL    |= _BV(UART0_UDRIE);

Das sieht so aus, als ob der Interrupt zu UART0_UDRIE nicht passt. Der 
müsste eigentlich so aussehen:

ISR(USART_UDRE_vect)
{
  ....
}

Aber: Wenn er denn wirklich falsch wäre, dann müsste der Compiler auch 
eine Warnung ausgeben, dass der Interrupt-Handler-Name falsch wäre (so 
ähnlich jedenfalls). Ausserdem glaube ich nicht, dass ein derartiger 
Schnitzer im Fleury-Source ist.

Sehr merkwürdig das ganze.

: Bearbeitet durch Moderator
von MWS (Gast)


Lesenswert?

Wenn Du das Hex-File postest, schau' ich mal rein, was los ist.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

MWS schrieb:
> Wenn Du das Hex-File postest, schau' ich mal rein, was los ist.

Die ersten paar Zeilen aus der lss-Datei (Interrupt-Vektor-Tabelle) 
wären lesbarer und deshalb interessanter ;-)

: Bearbeitet durch Moderator
von Mathias O. (m-obi)


Angehängte Dateien:

Lesenswert?

Danke schonmal

von MWS (Gast)


Lesenswert?

Frank M. schrieb:
> Die ersten paar Zeilen aus der lss-Datei (Interrupt-Vektor-Tabelle)
> wären lesbarer und deshalb interessanter ;-)

Die Tabelle seh' ich auch so und die ist Murks, da stehen an den 
Vektoren RJMPs statt JMPs drin, der letzte Teil der IVT ist Müll. Der 
Stackpointer wird auf 0x025F initialisiert, müsste beim ATM16 auf 0x045F 
sein. Da stimmt das Target nicht.

von Mathias O. (m-obi)


Lesenswert?

D.h. was genau? Wo muss ich was ändern? Ich arbeite mit Code::Blocks.

von Karl H. (kbuchegg)


Lesenswert?

?
1
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c main.c -o obj\Release\main.o
2
avr-gcc.exe  -mmcu=atmega16 -Os -DF_CPU=16000000UL     -c uart.c -o obj\Release\uart.o
3
avr-g++.exe -LD:\opencv\build\x86\mingw\lib  -o bin\Release\IRMP.elf obj\Release\main.o obj\Release\uart.o   -Wl,-Map=bin\Release\IRMP.map,--cref

einmal avr-gcc und dann avr-g++ ?
Auch fehlt mir in der Linker Anweisung die Angabe vom Mega16

Poste doch mal dein makefile. Da scheint ein ordentlicher Wurm drinnen 
zu sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mathias O. schrieb:
> avr-g++.exe  -o bin\Release\IRMP.elf obj\Release\main.o
> obj\Release\uart.o   -Wl,-Map=bin\Release\IRMP.map,--cref

Bei mir steht da immer noch mindestens ein "-mmcu=xxxxxx".

Außerdem wundere ich mich, warum zum Linken avr-g++ statt avr-gcc 
aufgerufen wird.

Edit: Karl Heinz war schneller :-)

: Bearbeitet durch Moderator
von Mathias O. (m-obi)


Lesenswert?

Code::Blocks generiert es selber, ich finde keins.

von kif (Gast)


Lesenswert?

Hast du mal von Atmel Studio gehört?

Kostet nichts.

von Mathias O. (m-obi)


Lesenswert?

Super endlich. Hab in den Linker settings noch -mmcu=atmega16 angegeben 
und nun funktioniert es endlich richtig alles.
Ihr seid einfach klasse und sooooo geduldig.

: Bearbeitet durch User
von MWS (Gast)


Lesenswert?

Mathias O. schrieb:
> Ich arbeite mit Code::Blocks.

Das hab' ich gelesen, kenn' mich mit Codeblocks aber nicht aus.

Vielleicht compilierst Du auch etwas anderes, als dass Du auf den µC 
brennst, vergleich' dich mal die Erstellungs-/Änderungszeiten der 
beteiligten Dateien. Im Hex-Code werden Befehle ausgeführt, die nicht im 
C-Code wie oben zu finden sind:
1
in  r24,p11
2
ori  r24,k60
3
out  p11,r24 --> DDRD |= (1 << PD5)|(1 << PD6);
4
5
cbi  p11,b3 --> ? (löscht Bit3 in DDRD)
6
7
sbi  p12,b5 --> PORTD |= (1 << PD5);
8
9
ldi  r24,kFF
10
ldi  r25,kE1
11
ldi  r26,k04
12
L002E:
13
subi  r24,k01
14
sbci  r25,k00
15
sbci  r26,k00
16
brne  L002E --> _delay_ms(100);

von Konrad S. (maybee)


Lesenswert?

Mathias O. schrieb:
> Super endlich. Hab in den Linker settings noch -mmcu=atmega16 angegeben
> und nun funktioniert es endlich richtig alles.

Das hättest du schon gestern haben können. :-)

Konrad S. schrieb im Beitrag #3601753:
> Oder evtl. unterschiedliche µCs für Kompilieren und Linken angegeben?

Konrad S. schrieb im Beitrag #3602476:
> Es wäre noch interessant zu wissen, wie die Aufrufe vorher aussahen,
> einmal beim Kompilieren von main.c und einmal beim Linken des Programms.

von Mathias O. (m-obi)


Lesenswert?

@MWS: Ich hatte zwischeinzeitlich nochwas geändert/hinzugefügt. Wollte 
das er erst was sendet per UART wenn ich einen Taster drücke.

@Konrad: Ja ja. Im nachinein ist man immer schlauer ;). Aber ich 
verspreche Besserung.

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.