Forum: Mikrocontroller und Digitale Elektronik ATMega 64, ALL AVR, Anfänger Problem


von eRay (Gast)


Lesenswert?

Hey Leute,
ich habe in der Schule ein µC Projekt bekommen. (Da wir nun schon einige 
Zeit in C programiert haben). Ich und mein Partner wollen ein Lego 
Kettenfahrzeug steuern.

Blablabla....


Da wir mit den Schulboards nur Probleme haben haben wir uns ein eigenes 
Baord angeschafft. 
(http://www.steitec.net/AVR-Boards/BASE-AVR-ATMEGA64.html)

Mit dem ALL AVR von Reichelt kommen wir auch aufs Baord drauf (Laut 
Status Meldungen von AVR Studio 4)
WinAVR2010 ist instaliert und die avr-gcc file und makefile sind 
eingebunden.

Folgender Programmcode:
1
#include<avr/io.h>
2
3
int main(void)
4
{
5
6
DDRA=0xFF;
7
8
while(1)
9
{
10
PORTA=0xFF;
11
}
12
return 0;
13
}


Trozdem können wir keine Spannung an den Ausgangspins am Controller 
messen.

Hoffe ihr könnt mir helfen.

Grüße

von Hubert G. (hubertg)


Lesenswert?

Bestätigung daß das Programmieren OK ist?
VCC gemessen?
Spannung am Reset-Pin gemessen?

von eRay (Gast)


Lesenswert?

Hey,
kein Fehler beim übertragen des Programms (lauf AVR Studio).
Spannung am Resetpin 4,9V.
9Volt(Metzteil), Spannugnsregler 4,9V.

Hab es wieder ausprobiert der Controller setzt den Port nicht!....


Grüße

von eRay (Gast)


Angehängte Dateien:

Lesenswert?

Hey nochmal,
entweder ich habe falsch gemessen oder zu blöd zum Lesen. Das 
Testprogramm läuft jetzt.

Nun habe ich versucht das richtige Programm zu testen aber da wie 
erwartet nichts kann jemand helfen ich Poste den Programmcode mal als 
Anhang.

Ich vermute das ich den ADC Wert falsch auslese und davon ist nunmal das 
gesamte Progamm abhänig.


Grüße

von Hubert G. (hubertg)


Lesenswert?

So wie ich das im Schaltplan sehe kannst du keine interne 
Referenzspannung einstellen, AREF ist mit ext.VCC verbunden.
Du musst auch ADCH abfragen oder Ausgabe linksbündig und nur ADCH. 
Ansonst wird das Register nicht erneut beschrieben. Datenblatt lesen:
When ADCL is read, the ADC Data Register is not updated until ADCH is 
read. Consequently,
if the result is left adjusted and no more than 8-bit precision is 
required, it is
sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.

von eRay (Gast)


Angehängte Dateien:

Lesenswert?

Hey hab ma nur ein AD Programm versucht zu schreiben aber es scheint so 
als ob er den AD Wert nur einmalig ausliest und ausgibt. Veränder ich 
den ADWert ändert sich nichts an der Ausgabe. Code im Anhang

von Hubert G. (hubertg)


Lesenswert?

Was ich vorher geschrieben habe hast du nicht gelesen?
ADMUX = ADMUX | 0b11111;
k = i & 0b00011111;
k = k|0b11100000;
ADMUX = ADMUX & k;

Kannst du mal dazuschreiben was du hier machen willst.

von Hubert G. (hubertg)


Lesenswert?

Was ich vorher geschrieben habe hast du nicht gelesen?
ADMUX = ADMUX | 0b11111;
k = i & 0b00011111;
k = k|0b11100000;
ADMUX = ADMUX & k;

Kannst du mal dazuschreiben was du hier machen willst.
Für einen ADC-Test wäre etwas einfacheres besser.

von eRay (Gast)


Lesenswert?

Doch Linksbündig mit dem Adlar und dan nur das ADCH auslesen. Hat 
irgentwie nicht funktioniert.

Hab den Code falsch kopiert eig sollte da das hier stehn.

1. ADMUX = ADMUX | 0b00011111;
2. k = i & 0b00011111;
3. k = k|0b11100000;
4. ADMUX = ADMUX & k;


1. Die 5 LSB sind zum Channel auswählen. Ich will erstmal alle auf 1 
Setzen.

2. In dert Variable k speicher ich dan den Channel indem ich i mit 
0x00011111 verknüpfe. i wird in der forschleife hochgezählt um jedes mal 
einen Channel höher zu wählen.

3. Ich verknüpfe k mit 0b1110000 um k auf 0b111+Channel bits von i 
setze.

4. Ich verknüpfe das ADMUX mit k damit im ADMUX der Channel steht UND 
die vorher gesetzen Bits (Die 3 MSB) (Um die Ref spannung und das ADLAR 
nicht zurückzusetzen).


grüße

von Hubert G. (hubertg)


Lesenswert?

Solange du hier while(1); den ; hast wird es nie funktionieren
Die interne Referenz hast du immer noch drinnen.
Warum alles auf 1 setzen?

von eRay (Gast)


Lesenswert?

Ja das mit der While(1) hab ich schon geändert das war nur zum test nun 
steht es so


while(1)
{
ADC_Funktiion();
}

von eRay (Gast)


Lesenswert?

die interne referenz hab ich geändert....wasrum alles auf 1 damit ich 
den channel wählen kann wegen der und verknüpfung

von Hubert G. (hubertg)


Lesenswert?

Hab das mal simuliert, da funktioniert es.
Allerdings machst du einige Sachen die nicht gut sind.
Mach nach dem ADC_Main(); noch ein delay, sonst läuft das so schnell 
durch das du ohnehin nichts siehst.
Register die sich nicht ändern setzt man nicht immer wieder neu, das 
macht man im main vor der while. Wie das hier:
ADMUX   = 0;      //Zurücksetzen der Register
ADCSRA   = 0;    //Zurücksetzen der Register

ADMUX |=  (0<<REFS1) | (1<<REFS0);    //Interne AVCC als Referenz 
einstellen
ADMUX |= (1<<ADLAR);        //AD-Werte werden Rechtsbündig gespeichert

ADCSRA |= (1<<ADEN);        //AD Enable
ADCSRA |= 0b00000111;        //Frequenzteiler einstellen (fOsc/128)

von Hubert G. (hubertg)


Lesenswert?

1
#include <avr/io.h>
2
3
void ADC_Main(void)
4
{  
5
  /*int low =0;
6
  int high=0;*/
7
  int Auslesen=0;  
8
9
  char ADCEND=0;
10
//  char k   =  0;            //Variable als Zwischenspeicher
11
  char i   =  0;            //Variable zum Channel wählen
12
//  ADMUX   = 0;            //Zurücksetzen der Register
13
//  ADCSRA   = 0;            //Zurücksetzen der Register
14
15
//  ADMUX |=  (0<<REFS1) | (1<<REFS0);    //Interne AVCC als Referenz einstellen
16
//  ADMUX |= (1<<ADLAR);        //AD-Werte werden Rechtsbündig gespeichert
17
  
18
//  ADCSRA |= (1<<ADEN);        //AD Enable
19
//  ADCSRA |= 0b00000111;        //Frequenzteiler einstellen (fOsc/128)
20
  
21
22
     for(i=0; i<4; i++)
23
  {
24
    Auslesen=0;
25
    ADCEND=0;
26
//    ADMUX = ADMUX | 0b11111;
27
//    k = i & 0b00011111;
28
//    k = k|0b11100000;
29
//    ADMUX = ADMUX & k;
30
    ADCSRA |= (1<<ADSC);      //AD-Wandlung Starten
31
  
32
    while(ADCSRA & (1<<ADSC))    //Warten auf Abschluss der AD-Wandlung
33
    {  
34
      ;          
35
    }
36
    /*high=ADCH<<6;
37
    high=high&&0b11000000;
38
    low=ADCL>>2;
39
    low=low&&0b00111111;*/
40
    Auslesen=ADCL;
41
    ADCEND=ADCH;
42
      
43
    ADMUX++;            //MUX um eins erhöhen
44
    /*PORTC=0;*/
45
    
46
    
47
    if(i==0)
48
    {
49
       PORTC=ADCEND;
50
    }
51
    if(i==1)
52
    {
53
      PORTA=ADCEND;
54
    }
55
    if(i==2)
56
    {
57
      PORTA=ADCEND;
58
    }
59
    if(i==3)
60
    {
61
      PORTA=ADCEND;
62
    }
63
64
  }
65
  ADMUX &=~((1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0)); //MUX auf 0 setzen
66
}
67
68
69
int main(void)
70
{
71
  DDRA= 0xFF;
72
  DDRC= 0xFF;
73
  PORTA=0x00;
74
  PORTC=0x00;
75
  /*DDRF= 0x00;
76
  PORTF=0x00;*/
77
  ADMUX   = 0;            //Zurücksetzen der Register
78
  ADCSRA   = 0;            //Zurücksetzen der Register
79
80
//  ADMUX |=  (0<<REFS1) | (1<<REFS0);    //Interne AVCC als Referenz einstellen
81
  ADMUX |= (1<<ADLAR);        //AD-Werte werden Rechtsbündig gespeichert
82
  
83
  ADCSRA |= (1<<ADEN);        //AD Enable
84
  ADCSRA |= 0b00000111;        //Frequenzteiler einstellen (fOsc/128)
85
  
86
87
  while(1)
88
  {
89
    ADC_Main();
90
  }
91
92
return 0;
93
}
So wäre es besser, zumindest im Simulator funktioniert es.

von eRay (Gast)


Lesenswert?

Ich schau mal drüber. In der Simulation funktionierter mein Programm ja 
auch nur aufem Controller konte ich es nicht messen das er den Port 
ändert bzw anpasst.

von Hubert G. (hubertg)


Lesenswert?

Ich habe das jetzt mal auf meinem Testboard aufgebaut, funktioniert 
einwandfrei.
Allerdings kannst du auf PortA keine Leds hängen, das ist der ADC-Port.

von eRay (Gast)


Lesenswert?

Sry ich war ein paar Tage leider verhindert. Ich versuche das heute 
nocheinmal.

Bei meinem ATMega64 ist der PortF der ADC Port.

von Hubert G. (hubertg)


Lesenswert?

Das mit PortF ist klar, ich teste es auf einem Mega32. Der ist in dem 
Bereich kompatibel.
1
  ADMUX |= (1<<ADLAR);        //AD-Werte werden Rechtsbündig gespeichert
Der Kommentar ist falsch. Hier wird der Wert linksbündig gespeichert, 
sonst würde das ADCH auslesen keinen Sinn machen.
In die for-Schleife noch ein _delay(500): einfügen. Wenn es sich sonst 
ergibt das alle Leds einmal aufleuchten, hat es den Anschein als ob 
immer alle leuchten würden.

von eRay (Gast)


Angehängte Dateien:

Lesenswert?

In der Simulation fliegt der bei dem Delay immer raus. Auf dem Boiard 
funktioniert die AD Wandlung nur im Testprogramm hier der Aktuelle code.

Mal eine Frage, oben bei den deklarationen für die Zuweisung der Ports 
ist das richtig wenn man PC0,PC1,PC2...etc. schreibt oder ist das der 
fehler?

Grüße

von spess53 (Gast)


Lesenswert?

Hi

>Bei meinem ATMega64 ist der PortF der ADC Port.

Und du weisst auch, das dort das JTAG-Interface liegt, das im 
Auslieferzustand eingeschaltet ist?
PF4...PF7 sind damit nicht nutzbar.

MfG Spess

von eRay (Gast)


Lesenswert?

Wie schalte ich das denn ab? (Andereseits benutzen wir PF4 bis PF7 
nicht)

von spess53 (Gast)


Lesenswert?

Hi

>Wie schalte ich das denn ab?

JTAG-Fuse.

>(Andereseits benutzen wir PF4 bis PF7 nicht)

Dann stört es auch nicht.

MfG Spess

von Christian F. (cmf) Benutzerseite


Lesenswert?

1
void PWM_T1(void)
2
{
3
    TCCR1A = (1 << WGM10)|(1 << COM1A1)|(1 << COM1A0);      // Bit WGM10 des Registers TCCR1A High setzen
4
    TCCR1B = (1 << CS11) | (1 << CS10);               // Bit CS11 und CS10 des Register TCCR1B High setzen    
5
}
Ein Beispiel für unnötige / schlechte Kommentare. Auch ohne erkennt 
Jeder, dass da Bits gesetzt werden. Viel sinnvoller wäre es zu 
schreiben, was das bringt.
Also zum Beispiel: Prescaler 256, CTC Match aktiv (Ich habe nicht im 
Datenblatt geguckt, ist nur ein Beispiel)

eRay schrieb:
> In der Simulation fliegt der bei dem Delay immer raus.

Ist bei mir (zumindest ín AVR-Studio 5) auch so.

von eRay (Gast)


Lesenswert?

Ok wenn es nicht stört zurück zum Problem. Ich verstehe nicht welche 
Adressen die einzelnen Portbits haben. Im Datenblatt steht PROTC 0x35 
aber für DDRC 0x34.

Moemntan scheitert es daran das ich die PortBITS nicht einzeln setzen 
kann
1
PORTC0 = V1_1;
2
PORTC1 = V1_2;
3
PORTC2 = V2_1;
4
PORTC3 = V2_2;
5
PORTC4 = V3_1;
6
PORTC5 = V3_2;
7
PORTC6 = Kranz_an;
8
PORTC7 = Kranz_LR;
9
        
10
PORTA0 = ML_Z; 
11
PORTA1 = MR_Z;

Muss ich da statt PORTC0, PC0 schreiben?


grüße

von Christian F. (cmf) Benutzerseite


Lesenswert?

eRay schrieb:
> Mal eine Frage, oben bei den deklarationen für die Zuweisung der Ports
> ist das richtig wenn man PC0,PC1,PC2...etc. schreibt oder ist das der
> fehler?
Das ist falsch. In den Defines für PC0, PCx steht nur 0, x drin. Also 
schreibst du hier:
1
int V1_1 = PC0;    //--> entspricht int V1_1 = 0;    //Ventil Ausleger hoch
2
int V1_2 = PC1;    //--> entspricht int V1_2 = 1;    //Ventil Ausleger runter
3
int V2_1 = PC2;        //Ventil Löffelarm hoch
4
int V2_2 = PC3;        //Ventil Löffelarm runter
5
int V3_1 = PC4;        //Ventil Löffel rein
6
int V3_2 = PC5;        //Ventil Löffel raus
7
[/]
8
------------------
9
[c]
10
V1_1 = 0; //--> entspricht: 0 = 0;
11
V1_2 = 0; //entspricht 1 = 0;

von eRay (Gast)


Lesenswert?

Ja die Sinnlosenkommentare werden noch geändert..... Nur leider 
programiert man nicht mit Kommentare :/

von eRay (Gast)


Lesenswert?

Danke Christian F. ...das habe ich eben auch gemerkt. Nun hab ich die 
alle erst auf 0 gesetzt. Nun will ich die Varibalen aber auf einen 
einzelnen Portbit legen (Die Variablen enthalten nur 0 oder 1).

von Christian F. (cmf) Benutzerseite


Lesenswert?

eRay schrieb:
> Ok wenn es nicht stört zurück zum Problem. Ich verstehe nicht welche
> Adressen die einzelnen Portbits haben. Im Datenblatt steht PROTC 0x35
> aber für DDRC 0x34.
>
> Moemntan scheitert es daran das ich die PortBITS nicht einzeln setzen
> kann
> PORTC0 = V1_1;
> PORTC1 = V1_2;
> PORTC2 = V2_1;
> PORTC3 = V2_2;
> PORTC4 = V3_1;
> PORTC5 = V3_2;
> PORTC6 = Kranz_an;
> PORTC7 = Kranz_LR;
>
> PORTA0 = ML_Z;
> PORTA1 = MR_Z;
>
> Muss ich da statt PORTC0, PC0 schreiben?
>
>
> grüße

Es muss zum setzen heißen:
1
PORTC |= (1<<PC0);
Zum löschen:
1
PORTc &=~(1<<PC0);
;
Siehe auch AVR-GCC-Tutorial

von eRay (Gast)


Lesenswert?

Also wenn ich es von einer Variable abhänig machen will muss ich das so 
schreiben?


1
if(V1_1 == 1)
2
{
3
PORTC |= (1<<PC0);
4
}
5
else
6
{
7
PORTC &= ~(1<<PC0);
8
}

von Christian F. (cmf) Benutzerseite


Lesenswert?

eRay schrieb:
> Danke Christian F. ...das habe ich eben auch gemerkt. Nun hab ich die
> alle erst auf 0 gesetzt. Nun will ich die Varibalen aber auf einen
> einzelnen Portbit legen (Die Variablen enthalten nur 0 oder 1).
Wenn ich dich richtig verstehe, müsstest du es so machen:
1
#define LOEFFELARM_PORT PORTC
2
#define LOEFFELARM_AUSFAHREN_PIN PC0
3
#define LOEFFELARM_EINFAHREN_PIN PC1
4
5
#define LOEFFELARM_AUSFAHREN_AN LOEFFELARM_PORT |=(1<<LOEFFELARM_AUSFAHREN_PIN);
6
#define LOEFFELARM_AUSFAHREN_AUS LOEFFELARM_PORT &=~(1<<LOEFFELARM_AUSFAHREN_PIN);
7
8
#define LOEFFELARM_EINFAHREN_AN LOEFFELARM_PORT |=(1<<LOEFFELARM_EINFAHREN_PIN);
9
#define LOEFFELARM_EINFAHRE_AUS LOEFFELARM_PORT &=~(1<<LOEFFELARM_EINFAHREN_PIN);
10
11
if(J1_VZ_V == 0)        //Löffelarm Stillstand
12
    {
13
      LOEFFELARM_EINFAHREN_AUS;
14
      LOEFFELARM_AUSFAHREN_AUS;
15
    }
16
    if(J1_VZ_V == 1)        //Löffelarm ausfahren
17
    {
18
       LOEFFELARM_AUSFAHREN_AN;
19
       LOEFFELARM_EINFAHREN_AUS;
20
    }
21
    if(J1_VZ_V == 2)        //Löffelarm einfahren
22
    {
23
       LOEFFELARM_EINFAHREN_AN;
24
       LOEFFELARM_AUSFAHREN_AUS;
25
    }

von Christian F. (cmf) Benutzerseite


Lesenswert?

eRay schrieb:
> Also wenn ich es von einer Variable abhänig machen will muss ich das so
> schreiben?
>
>
> if(V1_1 == 1)
> {
> PORTC |= (1<<PC0);
> }
> else
> {
> PORTC &= ~(1<<PC0);
> }

Ja.

von eRay (Gast)


Lesenswert?

danke Christian....das man das extra difinen muss wusste ich nichgt 
zumindest hat er beim ersten mal immer nen fehler rausgeschmissen ich 
probier das aus danke =)

von Peter D. (peda)


Lesenswert?

Warum einfach, wenn es auch kompliziert geht.

Ich mags lieber einfach:
Beitrag "Re: Problem mit Befehl SET"


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.