Forum: Mikrocontroller und Digitale Elektronik ATmega 1284p Port C


von Martin W. (schnuffituffi)


Lesenswert?

Moin,
ich habe ein Problem mit meinem 1284p an Port C.
JTAGEN und OCDEN Fuse sind beide laut AtmelStudio 6 aus.
Pin 0,1,2 und 3 tuen was sie sollen. Pin 4 und 5 leider nicht :-(

Die Idee ist, dass Pin 3,4 und 5 über jeweils 1kOhm mit einem 
PWM-Ausgang verbunden sind. Wird nun ein Pin als Ausgang gesetzt, sollte 
man mit ihm das Signal auf der Leitung auf Hi oder Low setzten können. 
Setzt man hingegen das DDR auf Input so sollte das PWM Signal anliegen. 
Bei Pin 3 funktioniert genau das. Pin 4 hingegen erreicht einen 
undfinierten Zustand mit PWM-Spitzen wenn man ihn als Eingang festlegt. 
Pin 5 hingegen ignoriert einfach alles und liefert in allen 3 Zuständen 
das PWM-Signal.

Wer genaueres wissen will: 
https://www.mikrocontroller.net/articles/Brushless-Controller_f%C3%BCr_Modellbaumotoren

Nun meine Frage: Haben die Pins in Port C andere 
Pullup-/Pulldownwiderstände. Oder hab ich JTAG nicht richtig 
ausgeschaltet. Muss man da noch mehr tun als die Fuse auszuschalten? 
Oder wo liegt hier mein Problem?

Codebeispiel:
1
 
2
int main(void){
3
  pwm_init();
4
  
5
  while(1){
6
    DDRC  = 0b00000000;
7
    PORTC = 0b00000000;
8
    _delay_ms(1);
9
    DDRC  = 0b00111111;
10
    PORTC = 0b00000000;
11
    _delay_ms(1);
12
    DDRC  = 0b00111111;
13
    PORTC = 0b00111111;
14
    _delay_ms(1);
15
  }
16
}

vielen Dank schonmal
Martin

von Magic S. (magic_smoke)


Lesenswert?

Schaltplan her.

von Martin W. (schnuffituffi)


Angehängte Dateien:

Lesenswert?

Der "Plan".

von c-hater (Gast)


Lesenswert?

Martin W. schrieb:

> Der "Plan".

Das ist ziemlicher Mist. Die 1k-Widerstände begrenzen den Strom zu den 
Brückentreibern viel zu sehr und sie sind bei sauberer Programmierung 
auch überhaupt nicht nötig. Ersetze sie durch 0Ohm-Widerstände.

Ansonsten sollte das Prinzip aber so funktionieren, wie du dir das 
vorstellst. Deine Fehlerbeschreibung weist tatsächlich darauf hin, dass 
JTAG aktiv ist. Welche Fusewerte benutzt du denn? Poste einfach die drei 
Hexwerte, das spart eine Menge Laber/Sülz.

Zu der sauberen Programmierung:

Du mußt dir einfach nur klar machen, dass das DDRC-Register nur wenige 
gültige Bitkombinationen haben kann. Entweder legst du dir eine Tabelle 
dieser Bitkombinationen an und schreibst nur Werte aus dieser Tabelle 
nach DDRC oder du schreibst dir eine Funktion, die "on the fly" die 
Kombination ausrechnet und benutzt immer nur diese Funktion zum Setzen 
von DDRC. Dann kann nix schief gehen, weil immer einer der beiden 
Ausgänge eines Paares hochohmig ist. In Assembler würde das (vor einer 
Optimierung ;o) ungefähr so aussehen:
1
;->R16: in den unteren drei Bits sind die Kanal-Selektoren
2
;       der drei Phasen, gesetztes Bit bedeutet Direktsteuerung
3
;       über die Pins 0..2, gelöschtes Bit bedeutet PWM-Steuerung
4
;       über die Pins 3..5.
5
SelectDirectPWM:
6
  push R17
7
  mov R17,R16
8
  swap R17
9
  lsr R17
10
  com R17
11
  andi R16,0b00000111
12
  andi R17,0b00111000
13
  or R16,R17
14
  cli                 ;ab hier nur nötig, wenn PORTC6/7
15
  in R17,DDRC         ;anderweitig genutzt werden sollen
16
  andi R17,0b11000000 ;ansonsten entfällt das alles bis
17
  or R16,R17          ;einschließlich
18
  sei                 ;dieser Zeile
19
  out DDRC,R16
20
  pop R17
21
  ret

von Magic S. (magic_smoke)


Lesenswert?

Die 1k-Widerstände einfach durch 0 Ohm ersetzen geht nicht. Dann 
funktioniert sein Steuer-Patent, die PWM zu den einzelnen Stufen 
abschalten zu können nicht mehr.

von Martin W. (schnuffituffi)


Angehängte Dateien:

Lesenswert?

Danke schonmal für die Antwort. Hier die Fuses, ich schätz mal dich 
interessierten nur die letzten drei Zeilen.

BODLEVEL = DISABLED
OCDEN = [ ]
JTAGEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [ ]
BOOTSZ = 4096W_F000
BOOTRST = [ ]
CKDIV8 = [ ]
CKOUT = [ ]
SUT_CKSEL = EXTXOSC_8MHZ_XX_258CK_65MS

EXTENDED = 0xFF (valid)
HIGH = 0xD9 (valid)
LOW = 0xDE (valid)

------------------------------------------

Deine Idee mit der Tabelle hatte ich vorher bereits einprogrammiert 
(siehe Anhang). Da das so allerdings nicht Funktioniert hatte, hab ich 
immer weiter gemessen und festgestellt, dass an den Eingängen der 
Motortreiber schon nicht das gewünschte Signal anliegt. Anschließend hab 
ich die Motortreiber ausgelötet um zu Prüfen ob sie das Messergebnis 
beeinflussen. Die Messungen sind also mit ausgelöteten Treibern.

Ich werde jetzt als Nächstes nochmal andere Pins eventuell auch in 
anderen Ports so verbinden wie es mit Pin 4 und 5 geplant war und Messen 
ob das Signal dann eher meinen Erwartungen entspricht.

von Martin W. (schnuffituffi)



Lesenswert?

Ich hab nun die letzten beiden Pins (6 und 7) des Ports C gemessen. 
Einmal mit 1k Verbindung zu PWM und einmal ohne. Pin 7 tut was er soll. 
Meine These ist nun:

1. Pin 4 hat einen Internen Pullup-Widerstand
2. Pin 5 lässt sich nicht als Ausgang verwenden
3. Pin 6 hat einen Internen Pulldown-Widerstand

4. Pin 3 und 7 verhalten sich wie erwartet.


Hat jemand eine Idee ?

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.