Forum: Mikrocontroller und Digitale Elektronik Interrupt geht am Mega16 aber mit Mega 8 nicht


von Jörn A. (joerna)


Lesenswert?

Hy


Ich habe ein altes Programm an nem Mega16 benutzt, dass per RS232 Daten 
empfängt und diese per ISR verarbeitet hat.
Das gleiche Programm will jetzt an meinem Mega8 einfach keine ISR mehr 
auslösen und ich finde keinen Fehler..

Um es zu testen hab ich auch versucht, einfach mal was zu senden, wenn 
was ankommt, aber auch das funktioniert nicht.

DIE KOMMUNIKATION ansonsten funktioniert einwandfrei...

1
#define   F_CPU 8000000UL          // MP-Takt
2
#include  <avr/io.h>
3
#include  <stdio.h>
4
#include  <stdlib.h>
5
#include   <inttypes.h>
6
#include   <avr/interrupt.h>
7
8
#define BAUD     38400UL
9
#define UBRR_BAUD  ((F_CPU)/(16*(BAUD))-1)
10
11
int main (void) 
12
{
13
14
...
15
sei();
16
..
17
}
18
19
ISR(SIG_UART_RECV) 
20
{
21
/*
22
    Mode = UDR;
23
    while (!(UCSRA & (1<<RXC)));
24
    MPWMa = UDR;
25
    while (!(UCSRA & (1<<RXC)));
26
    MPWM = UDR;
27
*/
28
    while (!(UCSRA & (1<<UDRE)));
29
    UDR = 0xFF;
30
}

von 3348 (Gast)


Lesenswert?

Ja, ja das gibt es immer wieder. Bein einen AVR kann man ein register 
noch mit IN & OUT ansprechen, bein anderen muss dass LDS & STS sein. 
Muss man alles nachschauen und notieren.

von Michael U. (amiga)


Lesenswert?

Hallo,

aber nicht bei Mega8 und Mega16 in diesem Fall...

Ansonsten: merkt das der Compiler nicht?
Der Assembler merkt es doch auch...

Also nicht 3348, eher 0815.

Gruß aus Berlin
Michael

von Jörn A. (joerna)


Lesenswert?

also ich kann eucht nicht ganz folgen! was muss ich korrigieren oder 
suchen?

in der io.h ist die ISR SIG_UART_RECV gleich bei Mega8&16...

von Johannes M. (johnny-m)


Lesenswert?

Das Programm muss für den ATMega8 compiliert werden! Du kannst nicht 
einfach ein Programm, das für einen µC compiliert wurde, auf einen 
anderen schreiben. Zumal in diesem Fall noch hinzukommt, dass der Mega16 
über der "magischen Grenze" von 8 KiB Flash liegt und dementsprechend 
erstens längere Interrupt-Vektoren hat als der Mega8 und zweitens andere 
Sprungbefehle und calls verwendet (bei bis zu 8 KiB Flash reichen 
relative Jump- und Call-Befehle aus, bei größeren Speichern müssen 
absolute Sprünge her).

von Jörn A. (joerna)


Lesenswert?

Nein ich habe schon nen eigenes neues Projekt geöffnet mit nem Mega8 und 
nur den Code reinkopiert.

ich steuere nur zwei Ventile (Port C) und ein Motor mit PWM an


hier mal alles:
1
#define   F_CPU 8000000UL          // MP-Takt
2
#include  <avr/io.h>
3
#include  <stdio.h>
4
#include  <stdlib.h>
5
#include   <inttypes.h>
6
#include   <avr/interrupt.h>
7
8
#define BAUD     38400UL
9
#define UBRR_BAUD  ((F_CPU)/(16*(BAUD))-1)
10
11
long int   n    = 0;
12
long int   n1    = 0;
13
double      ni      = 0;
14
long int  i    = 0;
15
long int   MPWM   = 0;
16
long int   MPWMa   = 0;
17
int     Mode   = 0;
18
int     F    = 0;
19
int     Fs    = 0;
20
int     iF    = 0;
21
22
23
int main (void) 
24
{
25
26
  UCSRB   |= (1 << TXEN) | ( 1 << RXEN );  // UART TX, RX einschalten
27
   UCSRC   |= ( 1 << URSEL )|( 3<<UCSZ0 );  // Asynchron 8N1
28
   UBRRH  = (uint8_t) (UBRR_BAUD>>8);      // USART Baud
29
    UBRRL  = (uint8_t) UBRR_BAUD;
30
31
  ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS2);    
32
33
  sei();
34
35
  DDRC=0x0E;
36
  DDRB=0x03;
37
  
38
  TCCR1A= _BV(COM1A1) | _BV(WGM11)| _BV(WGM10);
39
  TCCR1B= _BV(CS11);
40
  OCR1AH= (unsigned int) (MPWM>>8); 
41
  OCR1AL= (unsigned int) (MPWM);
42
   PORTC=0x0F;
43
  
44
  for (;;) 
45
  {
46
47
    MPWM= (MPWMa)*256+(MPWM);
48
    
49
    
50
    F    = 0;
51
    Fs    = 0;
52
    iF    = 0;
53
    i    = 0;
54
55
  if (Mode == 0)  
56
  {
57
  MPWM = 0;
58
  OCR1AH= (unsigned int) (MPWM>>8); 
59
  OCR1AL= (unsigned int) (MPWM);  
60
61
  PORTC= 0x00;  
62
  }
63
64
65
  if (Mode == 1)    
66
  {
67
  PORTC= 0x0C;  
68
      
69
  OCR1AH= (unsigned int) (MPWM>>8); 
70
  OCR1AL= (unsigned int) (MPWM);
71
  }
72
73
74
  while (i < 40)
75
  {
76
  ADMUX = _BV(REFS1) | _BV(REFS0) ;        // AD Kanal A.0
77
  ADCSRA |= _BV(ADSC);              // AD Messung starten
78
  while (ADCSRA & _BV(ADSC))            // bis ein Wert eingelesen ist warten
79
  {}
80
  F = ADCW;
81
  Fs=Fs+F;
82
  i++;
83
    wait();
84
  }
85
  F=Fs/39;
86
87
    while (!(UCSRA & (1<<UDRE)));
88
    UDR = Mode;  
89
    while (!(UCSRA & (1<<UDRE)));
90
    UDR = (F>>8);  
91
    while (!(UCSRA & (1<<UDRE)));
92
    UDR = F;
93
  }
94
      
95
}
96
97
ISR(SIG_UART_RECV) 
98
{
99
    Mode = UDR;
100
    while (!(UCSRA & (1<<UDRE)));
101
    UDR = 0xFF;  
102
    while (!(UCSRA & (1<<RXC)));
103
    MPWMa = UDR;
104
    while (!(UCSRA & (1<<RXC)));
105
    MPWM = UDR;
106
107
}

von Daniel C. (cecky)


Lesenswert?

Hi,

wenn du schon den Interrupt verwenden möchtest, solltest du vielleicht 
auch das RXCIE Bit im UCSRB-Register setzen.

von Jörn A. (joerna)


Lesenswert?

oh vielen dank das hab ich vergessen. genau das hatte ich natürlich 
nicht aus dem alten Programm kopiert :-(

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.