Forum: Mikrocontroller und Digitale Elektronik AVR NET-IO / ATMEGA32 JTAG/IO/PWM


von Dirk D. (sureai)


Angehängte Dateien:

Lesenswert?

Hallo,

ich benutze ein AVR NET-IO mit eigener Firmware. Ich bin dabei eine 
Motorregelung zu basteln. Diese Motorregelung bekommt Drehzahlsensoren 
und regelt damit den angeschlossenen Elektromotor. Anfangs habe ich 
meine Firmware mit ISP übertagen, jetzt mit JTAG. Verwendet wird der 
Atmel-ICE Debugger:
http://www.reichelt.de/?ARTICLE=143878&PROVID=2788&wt_mc=amc141526782519998&&gclid=CNiMvZTnzcYCFSb3wgod-2sOmA

Momentan beschäftige ich mich damit, auf Pins ein Outputsignal zu geben, 
in meinem Fall 5V oder 0V. Motor läuft/ Motor läuft nicht. Angeschlossen 
habe ich dafür folgenden Drehzahlsteller:
http://www.reichelt.de/?ARTICLE=47585&PROVID=2788&wt_mc=amc141526782519998&&gclid=CPf1xJjkzcYCFUL4wgodZPwELA
Später soll auf einem bestimmten Pin natürlich ein PWM Signal sein um 
den Motor zu steuern, aber ich fange erstmal damit an für eine bestimmte 
Zeit 5V auf einen Pin zu geben.

Zusätzlich zu dem AVR NET-IO Board verwende ich noch eine 
Anschlussplatine:
http://www.pollin.de/shop/dt/NDQ5OTgxOTk-/Bausaetze_Module/Bausaetze/Bausatz_SUB_D_Anschlussplatine.html
Auf der Anschlussplatine entsprechen die Pins Data0-Data7 dem PortC 
meines ATMEGA32. Auf einem Dieser Pins würde ich gerne 5V geben umd die 
Anschlussklemmen nutzen zu können. Deshalb habe ich einige Fragen zu den 
IO Pins:

Zum JTAG debuggen sind die gelb markierten Pins schon belegt. Kann ich 
die freien Pins von Port C jetzt nicht mehr als IO Pins benutzen? Oder 
später als PWM Pins? Ich habe mit einem Voltmeter die Pins nach dem 
Hochsetzen gemessen und keine Veränderung festgestellt.
Zum Testen habe ich auch mal alle Pins von Port B auf hoch gesetzt, da 
werden allerdings nur bestimmte(PB1,PB2 und noch ein paar) auf 5V 
gesetzt und manche bleiben 0V. Die Pins von PortC lassen sich gar nicht 
verändern. Das ist mein Code:
1
if(a=='1'){ //am Terminal wurde 1 eingegeben
2
  DDRB = 0xFF; //PortB als Output setzen
3
  
4
  PORTB |= (1 << PB0);  //PB0 im PORTB setzen
5
  PORTB |= (1 << PB1);
6
  PORTB |= (1 << PB2);
7
  PORTB |= (1 << PB3);
8
  PORTB |= (1 << PB4);
9
  PORTB |= (1 << PB5);
10
  PORTB |= (1 << PB6);
11
  PORTB |= (1 << PB7);
12
13
//   Analog für PortC:
14
//   PORTC |= (1<< PC0);
15
//  [...]  
16
  
17
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
18
}
19
20
if(a=='2'){ //am Terminal wurde 2 eingegeben
21
  DDRB = 0x00; //PortB als Input setzen
22
  
23
  PORTB &= ~(1 << PB0); //PB0 im PORTB löschen
24
  PORTB &= ~(1 << PB1);
25
  PORTB &= ~(1 << PB2);
26
  PORTB &= ~(1 << PB3);
27
  PORTB &= ~(1 << PB4);
28
  PORTB &= ~(1 << PB5);
29
  PORTB &= ~(1 << PB6);
30
  PORTB &= ~(1 << PB7);
31
32
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
33
34
}
35
36
if(a=='3'){ //am Terminal wurde 3 eingegeben
37
//Einzelne Pins von DDRC als Output setzen:
38
  DDRC = 0b00000011; // PC0 und PC1 werden als Output gesetzt. Der Rest als Input
39
//PC0 und PC1 auf high setzen
40
  PORTC |= (1<<PC0); 
41
  PORTC |= (1<<PC1);
42
  
43
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
44
}

Ich hoffe es ist verständlich, was mein Problem ist und ihr könnt mir 
helfen.

von ich (Gast)


Lesenswert?

hi,
nein ist nicht dein (ganzer) code.
mfg
ich

von CRätselrater (Gast)


Lesenswert?

Goto sollte man aus dem C Standard verbannen.

von Dirk D. (sureai)


Lesenswert?

ich schrieb:
> hi,
> nein ist nicht dein (ganzer) code.
> mfg
> ich

Stimmt, ich benutze ein Codegerüst, in dem schon die serielle 
Schnittstelle implementiert ist.
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include "regler.h"
4
#include "erfassen.h"
5
#include "seriel.h"
6
#include "aktor.h"
7
#include "system.h"
8
#include "timer_f.h"
9
#include "da_wandlung.h"
10
#include <stdio.h>
11
12
static int uart_putchar(char c, FILE *stream);
13
static int uart_getchar(FILE *stream);
14
15
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);
16
static FILE mystdin = FDEV_SETUP_STREAM(NULL, uart_getchar,_FDEV_SETUP_READ);
17
18
int main(void)
19
{
20
GOTOMARKE1:
21
   da();
22
    int Anzahl_Messungen=2000;
23
    int i ,j,a=0;
24
    int sollwert;
25
  //char c ;
26
  int messsignal;
27
  int regelgroesse;
28
  int Te;
29
  //int summe=0;
30
  //int watch1;
31
  int watch2;
32
  int watch3;
33
  int ausgang;
34
  int ausgang0;
35
  int eingang0;
36
  int ausgang1;
37
  
38
  //int eingang;
39
  int Kr;
40
  //unsigned long Krbis;
41
  int Tn;
42
  //unsigned long Tv;
43
  int Tv;
44
  int error;
45
  //int Ta 2; //Abtastzeit von 2ms
46
    //char chain[6];
47
    
48
49
//cli(); clear interrupt
50
51
 USART_Init(16);
52
53
 stdout = &mystdout;
54
 stdin  = &mystdin;                     // Anschluss der low-level Routinen????
55
56
57
void menu(void){
58
    transmit_array_bis("XXX");
59
    transmit_array_bis("XXX");
60
    transmit_array_bis("XXX");
61
    transmit_array_bis("XXX");
62
}
63
64
65
66
67
68
69
  printf("XXX");
70
 
71
  printf("[1] Test1\n"
72
     "[2] Test2\n"
73
     "[3] Test3\n"
74
     "[4] X\n"
75
     "[5] X\n"
76
     "[6] X\n" 
77
     "[7] X\n"
78
     "[8] X\n"
79
     "[9] X\n"
80
     "[0] X\n") ;
81
82
  port_init();
83
  TIMER0_interrupt_init();
84
  dac_eingang(bar2int(0));
85
  while(1)
86
  {
87
   a=getchar();
88
 
89
   printf("\n");
90
   
91
   if(a == '1') break;
92
   if(a == '2') break;
93
   if(a == '3') break;
94
   if(a == '4') break;
95
   if(a == '5') break;
96
   if(a == '6') break;
97
   if(a == '7') break;
98
   if(a == '8') break;
99
  if(a == '9') break;
100
  if(a== '0') break;
101
  }
102
103
if(a=='1'){ //am Terminal wurde 1 eingegeben
104
  DDRB = 0xFF; //PortB als Output setzen
105
  
106
  PORTB |= (1 << PB0);  //PB0 im PORTB setzen
107
  PORTB |= (1 << PB1);
108
  PORTB |= (1 << PB2);
109
  PORTB |= (1 << PB3);
110
  PORTB |= (1 << PB4);
111
  PORTB |= (1 << PB5);
112
  PORTB |= (1 << PB6);
113
  PORTB |= (1 << PB7);
114
115
//   Analog für PortC:
116
//   PORTC |= (1<< PC0);
117
//  [...]  
118
  
119
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
120
}
121
122
if(a=='2'){ //am Terminal wurde 2 eingegeben
123
  DDRB = 0x00; //PortB als Input setzen
124
  
125
  PORTB &= ~(1 << PB0); //PB0 im PORTB löschen
126
  PORTB &= ~(1 << PB1);
127
  PORTB &= ~(1 << PB2);
128
  PORTB &= ~(1 << PB3);
129
  PORTB &= ~(1 << PB4);
130
  PORTB &= ~(1 << PB5);
131
  PORTB &= ~(1 << PB6);
132
  PORTB &= ~(1 << PB7);
133
134
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
135
136
}
137
138
if(a=='3'){ //am Terminal wurde 3 eingegeben
139
//Einzelne Pins von DDRC als Output setzen:
140
  DDRC = 0b00000011; // PC0 und PC1 werden als Output gesetzt. Der Rest als Input
141
//PC0 und PC1 auf high setzen
142
  PORTC |= (1<<PC0); 
143
  PORTC |= (1<<PC1);
144
  
145
  goto GOTOMARKE1; //Springt wieder ins Hauptmenu und wartet auf Eingabe
146
}
147
148
}
149
150
151
    static int uart_putchar(char c, FILE *stream)
152
    {
153
154
      if (c == '\n')
155
        uart_putchar('\r', stream);
156
      loop_until_bit_is_set(UCSRA, UDRE);
157
      UDR = c;
158
      return 0;
159
    }
160
161
162
static int uart_getchar(FILE *stream)
163
164
{
165
   char c;
166
   loop_until_bit_is_set(UCSRA, RXC);
167
    c = UDR;
168
    uart_putchar(c, stdout);
169
   
170
 if (c == '\r')
171
    return '\n';
172
173
    return(c);
174
}

Reicht dir das um den Code nachvollziehen zu können?

von Dirk D. (sureai)


Lesenswert?

CRätselrater schrieb:
> Goto sollte man aus dem C Standard verbannen.

Ich empfinde Goto auch als unsauber und werde es in meiner finalen 
Programmsturktur nicht mehr verwenden. Vielen Dank für deine hilfreiche 
Aussage

von Stefan F. (Gast)


Lesenswert?

Ich würde nie im Leben mit Goto in einen anderen Code-Block springen. 
Mich wundert, dass der Compiler das nicht schon verweigert.

von Stefan F. (Gast)


Lesenswert?

> Zum JTAG debuggen sind die gelb markierten Pins schon belegt.
> Kann ich die freien Pins von Port C jetzt nicht mehr als IO Pins
> benutzen? Oder später als PWM Pins?


Diese Pins kannst du per Fuse als I/O Port oder JTAG Anschluss 
konfigurieren. Entweder oder, beide Betriebsarten zugleich sind niocht 
möglich.

von Dirk D. (sureai)


Lesenswert?

Stefan U. schrieb:
>> Zum JTAG debuggen sind die gelb markierten Pins schon belegt.
>> Kann ich die freien Pins von Port C jetzt nicht mehr als IO Pins
>> benutzen? Oder später als PWM Pins?
>
>
> Diese Pins kannst du per Fuse als I/O Port oder JTAG Anschluss
> konfigurieren. Entweder oder, beide Betriebsarten zugleich sind niocht
> möglich.

Vielen Dank, das hatte ich befürchtet.

Stefan U. schrieb:
> Ich würde nie im Leben mit Goto in einen anderen Code-Block springen.
> Mich wundert, dass der Compiler das nicht schon verweigert.

Warum sollte der Compiler syntaktisch korrekten Code verweigern? Muss 
Code zwingend gut und semantisch sein um kompilierbar zu sein?

Ich hatte bereits ein schlechtes Gewissen bei dem Goto, durch die lieben 
Antworten bekräftigt werde ich es beim nächsten Arbeiten an dem Code 
entfernen.

Wenn PortC durch das Setzen der Fuse Bits nicht mehr als IO Port 
verwendet werden kann, wieso können dann nicht alle Pins von PortB auf 
high gesetzt werden? So weit ich weiß ist der PortB durch die gesetzten 
Fuse Bits nicht betroffen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Dirk D. schrieb:

> Ich hatte bereits ein schlechtes Gewissen bei dem Goto, durch die lieben
> Antworten bekräftigt werde ich es beim nächsten Arbeiten an dem Code
> entfernen.

Wirf es gleich raus.
Vor allen Dingen, weil dein Code durch das goto so richtig mies geworden 
ist.


Die generelle Struktur eines AVR Programms sieht so aus
1
int main()
2
{
3
   Initialisierungen
4
   d.h. Variablen auf ihre Anfangswere setzen
5
   Hardware initialisieren, Anfangsbedingungen herstellen
6
7
   ev. ein sei() wenn mit Interrupts gearbeitet wird
8
9
   while( 1 ) {
10
11
      Hier steht dann die Programmlogik
12
13
   }
14
15
   // und hier kommt nichts mehr
16
}

D.h. wenn der Prozessor erst mal in der while Schleife (der sog. 
Hauptschleife) angekommen ist, dann kommt er da nie wieder raus! Die 
komplette Programmlogik spielt sich innerhalb dieser Hauptschleife ab 
(bis auf die Teile, die per Interrupt erledigt werden)

in deinem Fall schiesst du dir selbst von hinten durch die Brust ins 
Auge mit deinen GOto. Es gibt keinen Grund, sich aus der Hauptschleife 
mit einem break raus zu katapultieren um dann das Programm wieder von 
vorne (inklusive aller Initialisierungen) ausführen zu lassen.
1
int main()
2
{
3
4
   ...
5
6
   while( 1 ) {
7
8
     a = getchar();
9
10
     if( a == '1' ) {
11
       DDRB = 0xFF;
12
       PORTB = 0xFF;
13
     }
14
15
     else if( a == '2' ) {
16
        .... 
17
     }
18
   }
19
}

von Route_66 H. (route_66)


Lesenswert?

Dirk D. schrieb:
> Wenn PortC durch das Setzen der Fuse Bits nicht mehr als IO Port
> verwendet werden kann,

Nur die JTAG-Anschlüsse sind verloren, die übrigen an Port C kannst Du 
normal verwenden.

von Stefan F. (Gast)


Lesenswert?

> Warum sollte der Compiler syntaktisch korrekten Code verweigern?
Na wenn es korrekt ist, dann soll der Compiler das natürlich mitmachen.

Ich habe Goto in C nur ein einziges mal verwendet.
Diese spezielle Verwendung hat mich sehr überrascht. Ich habe intuitiv 
vermutet, dass das so nicht gehen kann.

Jetzt habe ich was zum dazu lernen - herausfinden, warum sowas möglich 
ist.

von Karl H. (kbuchegg)


Lesenswert?

Stefan U. schrieb:

> Jetzt habe ich was zum dazu lernen - herausfinden, warum sowas möglich
> ist.

Aus einem Block rauszuspringen ist nicht das grosse Problem.
Seine Struktur ist
1
int main()
2
{
3
  Label:
4
5
    ...
6
7
8
  if( ... ) {
9
    ...
10
    goto Label;
11
  }
12
}

syntaktisch kein Problem. Aber programmiertaktisch ein Desaster.

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.