Forum: Mikrocontroller und Digitale Elektronik Komisches Problem mit Portansprechung


von Draco (Gast)


Lesenswert?

Ich habe hier ein ganz doofes Problem im Grunde, und komme nicht 
dahinter was dies sein könnte, mein Programm mit dem ich einen Timer 
anspreche und LED's blinken lasse.:
1
const char _THRESHOLD = 64;
2
int counter = 0;
3
4
int flash_ps = 8;
5
6
int counter_small = 0;
7
int site = 1;
8
9
void Timer2Overflow_ISR() org IVT_ADDR_TIMER2_OVF {
10
11
  if (site == 1)
12
           {
13
           
14
           if (counter_small >= flash_ps)
15
                       {
16
                       PORTD = ~PORTD;
17
                       counter_small = 0;
18
                       }
19
           else
20
                       {
21
                       counter_small++;
22
                       }
23
           
24
           if (counter >= _THRESHOLD)
25
                       {
26
                       PORTD = 0;
27
                       counter = 0;
28
                       site = 2;
29
                       }
30
           else
31
                       {
32
                       counter++;
33
                       }
34
           }
35
  
36
  if (site == 2)
37
           {
38
39
           if (counter_small >= flash_ps)
40
                       {
41
                       PORTA = ~PORTA;
42
                       counter_small = 0;
43
                       }
44
           else
45
                       {
46
                       counter_small++;
47
                       }
48
49
           if (counter >= _THRESHOLD)
50
                       {
51
                       PORTA = 0;
52
                       counter = 0;
53
                       site = 1;
54
                       }
55
           else
56
                       {
57
                       counter++;
58
                       }
59
           }
60
  
61
}
62
63
void main() {
64
65
  delay_ms(2000);
66
67
  DDRD   = 0xff;
68
  DDRA   = 0xff;
69
70
  PORTA  = 0xaa;
71
  PORTD  = 0xaa;
72
73
  SREG_I_bit = 1;               // Interrupt einschalten
74
  TOIE2_bit  = 1;               // Timer2 overflow interrupt einschalten
75
76
  delay_ms(2000);
77
  
78
  TCCR2  = 7;                    // Start timer mit 1024 prescaler
79
  
80
  delay_ms(100);
81
  while (1);
82
}

So wie es dort steht, werden folgende Ports angesprochen:

4x PortA blinkt
...
4x PortD UND PortC blinkt

So und warum blinkt nun PortC bei PortD mit?!? Ich komme echt nicht 
dahint, wenn ich nun aber explizit angebe:
1
...
2
  DDRC   = 0xff;
3
  DDRD   = 0xff;
4
  DDRA   = 0xff;
5
6
  PORTA  = 0xaa;
7
  PORTD  = 0xaa;
8
  PORTC  = 0x00;
9
...

dann blinkt PortC nicht mit.

Aber warum ist das so?! Ich kann echt beim besten Willen kein Fehler in 
meinem Code feststellen?!

von Draco (Gast)


Lesenswert?

Achja...

µC ist ein ATmega16 - 16PU auf einem EasyAVR6 Testboard.

von Naja (Gast)


Lesenswert?

Wie wäre es mit "Strickung" oder "Kochung" als Hobby?

von Anja (Gast)


Lesenswert?

ist PORTD als "int" definiert?
ich würde mir mal den Assembler-Code anzeigen lassen.

von Flo (Gast)


Lesenswert?

also n timer interrupt sieht eigentlich so aus:

ISR(SIG_OVERFLOW0)
{
...
}

das
org IVT_ADDR_TIMER2_OVF ...
ist falsch. (so was macht man in assembler mit einem Sprungbefehl, aber 
keine ganze Codesammlung)


siehe: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

Du benötigst außerdem <avr/interrupts.h>

von Draco (Gast)


Lesenswert?

-.-

Lieber Gast "Naja"... mir ist durchaus bewußt das du mir in den 
Bereichen Stricken und Kochen weiter helfen könntest als sonst jemand 
anderes hier im Forum. Dennoch muß ich dein Angebot ablehnen dir deinem 
wunderschönen Hobby zu folgen. Ich kann dich auch leider nicht mit zum 
Ballett-Unterricht begleiten.

back to topic:

Ich habe nun das Problem ausfindig gemacht. Bei Rücksetzen der Ports A 
und D habe ich folgenden Fehler begangen:
1
...
2
PORTD = 0;
3
...

hab es nun natürlich zu folgendem geändert und es funktioniert tadellos:
1
...
2
PORTD = 0x00;
3
...

von Sven P. (Gast)


Lesenswert?

Wobei dann
1
PORTD = 0;
in jeder Hinsicht vollkommen äquivalent ist zu
1
PORTD = 0x00;

von Draco (Gast)


Lesenswert?

Im Grunde schon, aber der Fehler ist reproduzierbar :/

Genau das gleiche mit den Interrupts, was Flo angesprochen hat. Ich 
programmiere mit MicroC. Welche unter anderem keine Signal.h oder ebend 
die Interrupt.h mitliefert. Oder wie ebend das Problem mit den Hex 
werten.

Ich werde mal AVR-GCC anschauen, da scheint es mitunter leichter von der 
Hand zu gehen.

von (prx) A. K. (prx)


Lesenswert?

Sind alle übrigen Verbindungen des Board an Port C abgeschaltet, 
beispielsweise die Pullups/downs der Tastatur?

von Draco (Gast)


Lesenswert?

A. K. schrieb:
> Sind alle übrigen Verbindungen des Board an Port C abgeschaltet,
>
> beispielsweise die Pullups/downs der Tastatur?


Jep, das ist in solchen Fällen immer der erste Blick über das Brett :D

von Naja (Gast)


Lesenswert?

>Lieber Gast "Naja"... mir ist durchaus bewußt das du mir in den
>Bereichen Stricken und Kochen weiter helfen könntest als sonst jemand
>anderes hier im Forum. Dennoch muß ich dein Angebot ablehnen dir deinem
>wunderschönen Hobby zu folgen. Ich kann dich auch leider nicht mit zum
>Ballett-Unterricht begleiten.

Schon klar, Draco. ;-)

von Peter D. (peda)


Lesenswert?

Draco schrieb:
>
1
> ...
2
> PORTD = 0;
3
> ...
4
>
>
> hab es nun natürlich zu folgendem geändert und es funktioniert tadellos:
>
>
1
> ...
2
> PORTD = 0x00;
3
> ...
4
>

Was ist denn daran natürlich?

Du ersetzt einen C-Ausdruck durch einen vollkommen gleichwertigen und 
Dein Compiler reagiert anders?
Dann solltest Du einen Bugreport an den Compilerhersteller schicken, 
sowas darf ein Compiler nämlich nicht!
Denn dieser Bug wird Dir wieder und wieder Sorgen bereiten.

Ein Compiler muß Zahlen immer genau gleich bewerten, völlig egal, ob du 
sie dezimal, oktal, hexadezimal oder ASCII '\0' hinschreibst.


Peter

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.