At Mega 16 Problem mit dem Toggeln von Ports

OP (Firma: TGM) #1638471
Lesenswert?
• ▲
▼
Hi!

Ich habe folgendes Problem, habe ein Probramm, dass einen Tisch in zwei 
Ebenen steuert und mit dem ATMega128 einwandfrei funktioniert.
Jetzt habe ich das Programm auf den AtMega16 überschrieben, natürlich 
mit den notwendigen Veränderungen, jedoch funktioniert die 
Richtungsänderung und der Enable nicht. Sprich er hupft in die 
for-Schleife von y in der Funktion zeilenscan gar nicht rein.

Könnt mir hier vl weiterhelfen?
Vielen dank schon im Voraus!

lg

1
include <util/delay.h>  
2
#define F_CPU 16000000UL   //Frequenz
3
#include <avr/io.h>     //Deklaration
4
#include <util/delay.h>
5
#include<avr/signal.h>    //fuer Interrupt
6
#include<avr/interrupt.h>
7

8
static int DURCHLAUFE=100; //sonst 255
9
static int DURCHLAUFEG=100; // = Frequenz nach dem Teiler / gewnschte Frequenz
10
static char SCHRITT=1;
11
static char enablex=0;
12
static char enabley=0;
13
static int SCHRITTG=50;    // entspricht ca. 1 cm bei unserem Tisch
14
static char richtungx;
15
static char richtungy;
16
static char flag=0;
17

18
ISR(SIG_OVERFLOW0)    //Timer fr die Motorsteuerung
19
{    
20
    if(richtungx==1) {PORTB = PORTB |(1 << PB1);}    //Richtungsabfrage x
21
    else  {PORTB = PORTB &~ (1 << PB1);}
22
    if(richtungy==1) {PORTB = PORTB | (1 << PB4);}    //Richtungsabfrage y
23
    else  {PORTB = PORTB &~ (1 << PB4);}
24
    if(enablex==1)  {PORTB = PORTB | (1 << PB2);}    //Enableabfrage x
25
    else  {PORTB = PORTB & ~( 1 << PB2 );}
26
    if(enabley==1)  {PORTB = PORTB | (1 << PB5);}    //Enableabfrage y
27
    else  {PORTB = PORTB &~ (1 << PB5);}
28
    
29
    
30
    PORTB ^= (1 << PB0) ;      //Toggeln fuer Takt
31
    PORTB ^= (1 << PB3) ;      //Toggeln fuer Takt
32

33
    TCNT0= 256 - DURCHLAUFE;     //Startwert von Timer0; ft=fp/DURCHLAUFE(=(256-Startwert))
34

35
    SCHRITT=SCHRITT + 1;      //Zählt einen Schritt dazu, fuer die Abfrage der getätigten Schritte
36
}
37

38
void delayms(int ms) 
39
{
40
  int id;
41
  for(id=0; id<=ms; id++)
42
    _delay_ms(1);
43
}
44

45

46
void zeilenscan(int laengex, int laengey)    //Steuert die zwei Motoren in einem Zeilenscannverfahren. Zeilen sind durch ez und iz vernderbar
47
{  
48
  int x;  
49
  int d;
50
  int y;
51

52
  for(y=1; y<=laengey; y++)      //Schleife für die Bewegung in der Y-Ebene (positive Richtung)
53
  {
54
  for(x=1; x<=laengex; x++)      //Schleife für die Bewegung in der X-Ebene (positive Richtung)
55
  {
56
    richtungx=1;
57
    enablex=1;
58
    SCHRITT=1;
59
    while(SCHRITT<=SCHRITTG)
60
    {
61
    }
62
    enablex=0;
63
    if(flag>0) return;
64
    for(d=1; d<=1000; d++)
65
    {
66
    _delay_ms(1);
67
    }
68
  }
69
  richtungy=1;
70
  enabley=1;
71
  enablex=1;
72
  SCHRITT=1;
73
  while(SCHRITT<=SCHRITTG)
74
  {
75
  }
76
  enabley=0;
77
  enablex=0;
78
  for(d=1; d<=1000; d++)
79
  {
80
  _delay_ms(1);
81
  }
82
  for(x=1; x<=laengex; x++)      //Schleife für die Bewegung in der X-Ebene (negative Richtung)
83
  {
84
    richtungx=0;
85
    enablex=1;
86
    SCHRITT=1;
87
    while(SCHRITT<=SCHRITTG)
88
    {
89
    }
90
    enablex=0;
91
    if(flag>0) return;
92
    for(d=1; d<=1000; d++)
93
    {
94
    _delay_ms(1);
95
    }
96
  }
97
  richtungy=1;
98
  richtungx=1;
99
  enablex=1;
100
  enabley=1;
101
  SCHRITT=1;
102
  while(SCHRITT<=SCHRITTG)
103
  {
104
  }
105
  enablex=0;
106
  enabley=0;
107
  for(d=1; d<=1000; d++)
108
  {
109
  _delay_ms(1);
110
  }
111
  if(flag>0) return;
112
  }
113
}
114

115

116

117

118
int main(void)
119
{
120
  TCCR0 = (/*0<<CS00)|(1<<CS01)|(*/1<<CS02) ; // (Teiler) Register richtig setzen fuer den Timer0, dzt. Frequenz = f/128
121
  TIFR = (1<<TOV0);             // Timer Interrupt Flag Register --> enable
122
  TIMSK = (1<<TOIE0);
123
  TCNT0= 256 - DURCHLAUFE;         //Startwert von Timer0; ft=fp/DURCHLAUFE(=(256-Startwert))
124
sei();  //Interrupts aktivieren
125

126
  DDRB=0xFF;
127
  DDRD=0x00;
128

129
  while (1)
130
  {
131
    zeilenscan(10,5);
132
  }  
133
}
Persönliche Seite #1638512
Lesenswert?
• ▲
▼
1
include <util/delay.h>  
2
#define F_CPU 16000000UL   //Frequenz
3
#include <avr/io.h>     //Deklaration
4
#include <util/delay.h>
5
#include<avr/signal.h>    //fuer Interrupt
6
#include<avr/interrupt.h>

besser
1
#infndef F_CPU
2
   #warning F_CPU definiere F_CPU neu
3
   #define F_CPU 16000000UL   //Frequenz
4
#endif
5

6
#include <avr/io.h>     //Deklaration
7
#include <util/delay.h>
8
#include<avr/interrupt.h>

So bekommst du eine Warnung wenn F_CPU schon irgendwo anders definiert 
ist z.B. im Makefile

signal.h sollte man nicht mit interrupt.h mischen....
Gast #1638543
Lesenswert?
• ▲
▼
1.)
Alle Variabeln die Du innerhalb und auch ausserhalb einer ISR verwendest 
musst Du volatile deklarieren:
1
static volatile int DURCHLAUFE=100; //sonst 255
2
static int DURCHLAUFEG=100; 
3
static volatile char SCHRITT=1;
4
static volatile char enablex=0;
5
static volatile char enabley=0;
6
static volatile int SCHRITTG=50;
7
static volatile char richtungx;
8
static volatile char richtungy;
9
static char flag=0;

2.)
Alle Variabeln die Du innerhalb einer ISR änderst und auch ausserhalb 
der ISR verwendest und zudem grösser als 1 Byte sind (z.B. int) musst du 
ausserhalb der ISR atomic zugriffe sicherstellen (ISR gesperrt)
Gast #1638548
Lesenswert?
• ▲
▼
... ... schrieb:
> So bekommst du eine Warnung wenn F_CPU schon irgendwo anders definiert
> ist z.B. im Makefile
>
> signal.h sollte man nicht mit interrupt.h mischen....

Die Warnung wirft der Compiler auch ohne das #define-Geraffel, und 
signal.h stört sich auch nicht an interrupt.h. Trotzdem wäre es 
natürlich gut, die ISR-Vektoren mal auf die aktuellen Namen zu ändern.

Das Programm dürfte in dieser Form mit einer eingermassen aktuellen 
Version von avr-gcc auf einem Mega128und auf einem Mega16 nur ohne 
Optimierung laufen. Wie schon gesagt wurde, fehlen da einige volatiles. 
Die älteren gcc-Versionen ( < 2003 ???) waren da toleranter, und 
signal.h lässt darauf schliessen, daß das alles schon älter ist.

Alle Variablen, die im Hauptprogramm UND in der ISR gelesen bzw. 
geschrieben werden, brauchen den volatile-Qualifier.

Oliver

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.