Forum: Mikrocontroller und Digitale Elektronik atmega 1284p interrupt fehler?


von Fabian H. (fabian_hoh)


Lesenswert?

Hallo zusammen,
ich habe ein Problem und zwar habe ich eine Platine mit nem 1284p 
darauf. und will zwei sachen machen:

- über zwei interrupts servomotoren ansteuern

- über ne fotodiode die helligkeit einer hintergrundbeleuchtung steuern


einzeln funktioniert alles super, aber wenn ich beides zusammenschreibe 
und einfüge funktioniert es nicht. bzw wenn ich die interrupts 
einschalten (sei), bekomm ich mein rechteck signal für meine servos, 
aber die adc wandlung funktioniert nicht mehr. da das problem nur 
auftritt wenn ich die interrupts einschalte, denke ich dass es daran 
liegt. habe auch jetzt schon alle interrupts reingeschrieben, um 
auszuschließen, dass sich das programm da aufhängt, war aber leider auch 
ohne erfolg.

fusebits für high und ext. sind jeweils FF. Für low undefiniert.


anbei mein code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/delay.h>
4
5
6
7
8
      int main (void){
9
10
11
12
        //Port deklaration
13
        DDRC = 0xff;   //Port C als Ausgang
14
        DDRA |= (1<<PA1)|(1<<PA2); 
15
        DDRD |= (1<<PD7);
16
17
        //Deklaration für hintergrundbeleuchtung
18
19
        TCCR2A |= (1<<COM2A1) | (1<<WGM21) | (1<<WGM20);
20
        TCCR2B |= (1<<CS20); //clk no prescaling
21
22
23
24
25
26
27
        // Deklaration für servomotoren
28
        TCCR3A |=  (1<<WGM31);  // fast pwm mit höchstgrenze von icr3
29
        TIMSK3 |= (1<<OCIE3A) | (1<<OCIE3B) ;
30
        TCCR3B |=(1<<CS30)|(1<<WGM33) | (1<<WGM32) ; // clk mit prescaler 1
31
        ICR3H = 0x4E; //Counter für Servo auf 20000 µs obere Grenze
32
        ICR3L = 0x20; //Counter für servo auf 20 000  µs obere grenze
33
        OCR3AH = 0x23; // counter 1
34
        OCR3AL = 0x28;
35
        OCR3BH = 0x29; // counter 2 unterschied bis maximal 2000
36
        OCR3BL = 0x04;
37
38
39
40
41
        //ADC deklarieren
42
        ADCSRA |= (1<<ADEN); // ADC eingeschaltet, kein Prescale
43
        ADMUX |= (1<<ADLAR); // linksseitige formatierung
44
45
46
        PORTC = 0x00;
47
48
        sei();  // interrupts global einschalten
49
50
        while(1)
51
        {
52
53
54
55
56
57
58
          ADCSRA |= (1<<ADSC);  //single conversion mode ein
59
            _delay_ms(10);  //warten bis konvertierung abgeschlosen
60
61
62
          PORTC = ADCH;
63
64
          if (ADCH <50){    // Begrenzung des Registers OCR2A
65
66
            OCR2A=50;
67
68
          }
69
          else {
70
            OCR2A = ADCH;
71
          }
72
73
        }
74
75
76
      }
77
      ISR(TIMER3_COMPA_vect)
78
      {
79
        PORTA |= (1<<PA1) | (1<<PA2);
80
      }
81
82
      ISR(TIMER3_COMPB_vect)
83
      {
84
        PORTA &= ~((1<<PA1) | (1<<PA2));
85
      }

Wär klasse, wenn ihr mir helfen könntet.

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>          if (ADCH <50){    // Begrenzung des Registers OCR2A
>          OCR2A=50;

Was macht Timer2?

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Letzten Beitrag ignorieren

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

>ADCSRA |= (1<<ADEN); // ADC eingeschaltet, kein Prescale

Der ADC-Takt soll im Bereich 50...200kHz liegen. Deiner läuft mit 
500kHz.

>          ADCSRA |= (1<<ADSC);  //single conversion mode ein
>          _delay_ms(10);  //warten bis konvertierung abgeschlosen

Passt nicht zusammen. Einerseits lässt du den ADC mit maximalen Takt 
laufen (Conversation Time 26µs) andererseits wartest du 10ms.

Aber ich tippe eher auf deine Hardware:

- Beide VCC mit Kondensator angeschlossen?
- wie wird die Spannung an ADC0 erzeugt?
- Kondensator an AREF?

MfG Spess

von Fabian (Gast)


Angehängte Dateien:

Lesenswert?

Mh gute getippt würd ich mal sagen. Also die Spannung am ADC0 kommt 
direkt von nem längsspannungswandler.
Am aref ist kein kondensator, könnte das problem sein aber welche vcc's 
meinst du noch anbei mal mein layout

von spess53 (Gast)


Lesenswert?

Hi

>könnte das problem sein aber welche vcc's meinst du noch anbei mal mein >layout

Die drei VCC (links oben) und AVCC. Die 5V an VREF sind unnötig. VCC als 
VREF lässt sich auch über die REFSn-Bits einstellen. Da reicht für alle 
möglichen Fälle ein 100n-Kondensator von AREF nach Masse.

Hast du schon mal den R8 (wesentlich) kleiner gemacht? Dein 
Sensorkonstrukt ist für den ADC viel zu hochohmig. Das wird zwar durch 
C22 abgemildert, aber ich vermute, das durch das Schalten der 
benachbarten Portpins der ADC gestört wird.

MfG Spess

von Fabian H. (fabian_hoh)


Lesenswert?

gerade versucht mit 480k und 330k gleiche sache wie vorher... man sagt 
ja das man die photodioden hochohmig in reihe schalten soll. was ist 
denn dann hochohmig...

vielleicht interessant: wenn der andere widerstand angelötet wurde 
funktionieren die signale der servos nicht mehr. die anzeige an den leds 
(an denen ich normal auch das signal des adc's ausgebe füllt sich 
kontinuierlich - unabhängig von lichteinfall; die hintergrundbeleuchtung 
ist aus...

aref hab ich jetzt so gelassen oder istd as auch ein problem, wenn ich 
dahingehend nichts einstelle. den vorteiler habe ich mit 8 probiert, 
ändert auch nichts.

wird der adc relativ einfach gestört? ist das wenn nur der adc selber im 
prozessor oder auch die signalleitung selbst?

vielen Dank!

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>gerade versucht mit 480k und 330k gleiche sache wie vorher... man sagt
>ja das man die photodioden hochohmig in reihe schalten soll. was ist
>denn dann hochohmig...

Das ist richtig, aber je hochohmiger desto störungsempfindlicher. Dein 
C22 nutzt auch nur etwas, wenn er so nah wie möglich am Pin sitzt. Warum 
hast du eigentlich eine Fotodiode und keinen Fotowiderstand genommen. 
Wäre wesentlich entspannter. Außerdem ist die BP104 für den Zweck 
ungeeignet. Das ist eine Infrarot-Diode mit Tageslichtfilter.

>vielleicht interessant: wenn der andere widerstand angelötet wurde
>funktionieren die signale der servos nicht mehr.

Welcher Widerstand?

> die anzeige an den leds
>(an denen ich normal auch das signal des adc's ausgebe füllt sich
>kontinuierlich - unabhängig von lichteinfall; die hintergrundbeleuchtung
>ist aus...

??? Ich glaube da liegt einiges im Argen. Hast du das auf einer 
Leiterplatte? Wenn ja, poste mal das Layout. Das oben ist der 
Schaltplan, nicht das Layout.

Warum willst du eigentlich die Pins im Interrupt wackeln lassen?

Timer3 im PWM-Mode 14. ICR auf 0x4E1F setzen (20ms) und OCR3A/B im 
Bereich zwischen 0x3EF(1ms) und 0x7CF(2ms) bewegen lassen. Dafür 
brauchst du überhaupt keinen Interrupt. Die Servosignale liegen dann 
OC3A und OC3B.

Du kannst auch mal versuchen deinen Code auf freie Pins von einem 
anderen Port zu ändern.

MfG Spess

von Fabian H. (fabian_hoh)


Angehängte Dateien:

Lesenswert?

zu widerstand: damit mein ich, als ich den ein megaohm rausgeschmissen 
hab und nen kleineren ausprobiert habe

das mit den pins war eig nur um zu sehen ob der atmel überhaubt in den 
interrupt springt. also nur eine überprüfung.

anbei das layout (ja der kondensator ist zu weit weg dann)

das mit dem timer drei probiere ich aus...dachte das geht nur mit nem 
interrupt weil ich kein hardwareseitige anbindung habe.

vielen dank schonmal
lg
fabian

von spess53 (Gast)


Lesenswert?

Hi

Ich hatte geschrieben

>Ich glaube da liegt einiges im Argen.

Da wusste ich noch nicht, wie schlimm es wirklich ist. Ehrlich gesagt 
bezweifle ich das du diese Platine jemals gescheit zum laufen bekommst.

MfG Spess

von fabian (Gast)


Lesenswert?

haha ok das hilft mir in dem fall aber auch nicht weiter... n paar 
verbesserungsvorschläge wären gut

von spess53 (Gast)


Lesenswert?

Hi

>haha ok das hilft mir in dem fall aber auch nicht weiter... n paar
>verbesserungsvorschläge wären gut

Da gibt es nichts zu verbessern, da ist ein komplettes neues Layout 
angesagt. Dazu muss aber vorher noch der Schaltplan überarbeitet werden.

MfG Spess

von Ingo (Gast)


Lesenswert?

Also dein Layout ist der Hammer. Alles falsch was so geht...


Also neues! Abblock Cs so dicht an den uC wie nur möglich, Signale mal 
ordnen bzw Bauteile besser platzieren, etc

Mich wundert das du das noch auf ne 2 lagige bekommen hast.


Ingo

von Thomas E. (thomase)


Lesenswert?

fabian schrieb:
> haha ok das hilft mir in dem fall aber auch nicht weiter... n paar
> verbesserungsvorschläge wären gut

Dein Programm ist halt nicht sonderlich optimal. Man könnte sogar sagen, 
es ist totaler Müll. Das würde ich aber nie tun.

Also diese Konstruktion:
1
        // Deklaration für servomotoren
2
        TCCR3A |=  (1<<WGM31);  // fast pwm mit höchstgrenze von icr3
3
        TIMSK3 |= (1<<OCIE3A) | (1<<OCIE3B) ;
4
        TCCR3B |=(1<<CS30)|(1<<WGM33) | (1<<WGM32) ; // clk mit prescaler 1
5
        ICR3H = 0x4E; //Counter für Servo auf 20000 µs obere Grenze
6
        ICR3L = 0x20; //Counter für servo auf 20 000  µs obere grenze
7
        OCR3AH = 0x23; // counter 1
8
        OCR3AL = 0x28;
9
        OCR3BH = 0x29; // counter 2 unterschied bis maximal 2000
10
        OCR3BL = 0x04;
11
12
      }
13
      ISR(TIMER3_COMPA_vect)
14
      {
15
        PORTA |= (1<<PA1) | (1<<PA2);
16
      }
17
18
      ISR(TIMER3_COMPB_vect)
19
      {
20
        PORTA &= ~((1<<PA1) | (1<<PA2));
21
      }
Könnte aus einem AVR-Tutorial stammen. Aus dem "So nicht"-Kapitel.

Erstmal das hier:
        ICR3H = 0x4E; //Counter für Servo auf 20000 µs obere Grenze
        ICR3L = 0x20; //Counter für servo auf 20 000  µs obere grenze
1
ICR3 = 20000;

Und dann entsprechend:
1
OCR3A = 9000;
2
OCR3B = 10500;

Da steigt irgendwann keiner mehr durch. Am wenigsten du selbst.

Daß das Mist ist:
      ISR(TIMER3_COMPA_vect)
      {
        PORTA |= (1<<PA1) | (1<<PA2);
      }
genauso wie die folgende ISR, hat Spess ja schon geschrieben.

Totaler Quatsch:
1
  ADCSRA |= (1<<ADSC);  //single conversion mode ein
2
  _delay_ms(10);  //warten bis konvertierung abgeschlosen
1
ADCSRA |= (1<<ADSC);          // Starte ADC
2
while(ADCSRA & (1 << ADSC));  // Warte bis fertig

Das mal zu deinem Programm, das aber trotzdem laufen müsste.

Tut es aber nicht. Und da deine Hardware:

spess53 schrieb:
> Da wusste ich noch nicht, wie schlimm es wirklich ist. Ehrlich gesagt
> bezweifle ich das du diese Platine jemals gescheit zum laufen bekommst.

mußt du jetzt ganz tapfer sein. Auch wenn es dir nicht gefällt:

fabian schrieb:
> haha ok das hilft mir in dem fall aber auch nicht weiter... n paar
> verbesserungsvorschläge wären gut

mfg.

: Bearbeitet durch User
von fabian (Gast)


Lesenswert?

ok, liegt das,problem jetzt aber nur am design? sonst würde ich halt mit 
det,platine erst mal weiter machen, um weitere fehler zu finden.
sry is meine 2. platine

lg fabian

von spess53 (Gast)


Lesenswert?

Hi

>ok, liegt das,problem jetzt aber nur am design?

Das kann niemand beurteilen, da deine Schaltung bis auf den kleinen 
Schnipsel unbekannt ist. Da dort aber schon mehrere Fehler enthalten 
sind, habe ich für den Rest auch kein gutes Gefühl.

>sonst würde ich halt mit
>det,platine erst mal weiter machen, um weitere fehler zu finden.

Und woher weißt du dann woher der Fehler kommt? Hier hast du doch auch 
auf ein Softwareproblem getippt.

Allein deine fast kriminelle Masseführung wird dir noch etliche lustige 
Effekte bescheren.

>sry is meine 2. platine

Insgesamt oder mit dieser Schaltung?

MfG Spess

von fabian (Gast)


Lesenswert?

insgesamt meine 2.
mh ok sollte ich mir dann doch gedanken über n redesign machen. besten 
dank für eure hilfe

von Dietrich L. (dietrichl)


Lesenswert?

fabian schrieb:
> mh ok sollte ich mir dann doch gedanken über n redesign machen.

Wenn Du mit dieser Leiterplatte noch testen wolltest, wäre es einen 
Versuch wert:
"Baue" einen ordentlichen GND-Layer dazu, z.B. mit versilbertem 
Kupferdraht (mindestens 1mm Durchmesser). Daraus kann man ein Netz 
bauen, das mit Abstand über der CU-Seite "schwebt" und an das alle 
wichtigen GND-Punkte angeschlossen werden.

Gruß Dietrich

von fabian (Gast)


Lesenswert?

super :) danke

von Fabian H. (fabian_hoh)


Angehängte Dateien:

Lesenswert?

Wie sieht es mit diesem layout aus?

mit besten grüßen
Fabian

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.