Das Thema ist nicht neu, hierzu gibt es auch bereits einen Beitrag, den ich durgelesen habe, der mir aber nicht weiterhilft.
Zum Thema:
für einen Standalone ATmega328P mit internem Takt versuche ich gerade die Software zu schreiben. Dabei werden u. a. bistabile Relais über Ausgangspin per kurzem Pulse angesteuert. Da ich auch die Pins PB6 und PB7 verwende, die bei UNO für den Quarz vorgesehen und denen zumindest in der IDE-Umgebung keinen Pin-Nummern zugeordnet sind, will ich die Ausgänge direkt über die Ports B, C und D steuern. Soweit erst einmal kein Problem.
Mein Problem taucht bei der Übergabe des Ports und der zugehörigen Pin-Nr. an eine Funktion auf in der ich den entsprechen Pin für eine gewisse Zeit setze (z. B. 500 ms), um die Spule eines bistabilen Relais anzusteuern. Hierzu habe ich eine einfache Funktion pulse_Relais, in die ich den Port, die Pin-Nr. und die Pulse-Dauer übergebe.
Den Port gebe ich als Zeiger auf das entsprechende Register an. In der Funktion habe ich testhalber eine Maske gesetzt die ich auf den Port anwende. Später soll das entsprechende Bit über eine Portmanipulation gesetzt und nach der Pulsdauer auch wieder gelöscht werden. Aus mir nicht verständlichen Gründen funktioniert das nicht so wie ich mir das vorstelle.
Mein kleines Testprogramm:
#include <inttypes.h>
#include <avr/io.h>
#define t_pulse 1000 // Zeit in ms für Anregung Relaisspule
// -------------------------------- setup --------------------------------------
// Setup routine with pre definitions
// -----------------------------------------------------------------------------
void setup()
{
// Definition der Data-Direction-Register, 0 = Input, 1 = output
DDRB = DDRB | B11000100; // PB0 - nicht benutzt
// PB1 - nicht benutzt
// PB2 - nicht benutzt
// PB3 - nicht benutzt
// PB4 - nicht benutzt
// PB5 - nicht benutzt
// PB6 - Relais K3, Spule 1, ABC Gleis 1 und Gleis 2 zusammen, ABC1 a. B.
// PB7 - Ausgang BLM Gleis 1, Bremsbschnitt, 0 = belegt, 1 = frei
DDRC = DDRC | B00000000; // PC0 - nicht benutzt
// PC1 - nicht benutzt
// PC2 - Eingang BLM Gleis 1, Fahrabschnitt, 0 = belegt, 1 = frei
// PC3 - Eingang BLM Gleis 1, Bremsbschnitt, 0 = belegt, 1 = frei
// PC4 - Eingang BLM Gleis 2, Fahrabschnitt, 0 = belegt, 1 = frei
// PC5 - Eingang BLM Gleis 21, Bremsbschnitt, 0 = belegt, 1 = frei
PORTC = B10000001;
// DDRD = DDRD | B00111111; // PD0 - Relais K1, Spule 2, ABC Gleis 1 = on
DDRD = DDRD | B11111110; // PD0 - Relais K1, Spule 2, ABC Gleis 1 = on
// PD1 - Relais K1, Spule 1, ABC Gleis 1 = off
// PD2 - Relais K2, Spule 2, ABC Gleis 2 = on
// PD3 - Relais K2, Spule 1, ABC Gleis 2 = off
// PD4 - Relais K3, Spule 2, ABC Gleis 1 und Gleis 2 getrennt
// PD5 - Ausgang BLM Gleis 2, Bremsbschnitt, 0 = belegt, 1 = frei
// PD6 - Eingabe Zuglänge, 0 = kurze Züge, 1 = langer Zug
// PD7 - Freigabe Ausfahrtsignal 0 = HP0, 1 = HP1
Serial.begin(57600);
}
// ---------------------------- loop -----------------------------------------
// -----------------------------------------------------------------------------
void loop()
{
// Beispiel Funktionsaufruf pulse, Übergabe PORTx, PINy, Pulsedauer
PORTD |= B00000000;
pulse_Relais(PORTB, PB4, t_pulse);
delay (1000);
}
// ------------- pulse (uint8_t pin, long duration) -------------------
// Puls mit Dauer duration in ms an Ausgang pin L->H->L
// dient zur Pulsansteuerung des bistabilen Relais
// --------------------------------------------------------------------
void pulse_Relais (volatile uint8_t *port, uint8_t pin, long duration)
{
uint8_t mask;
mask |= B00100000;
Serial.print("Maske: ");Serial.print(mask, DEC); Serial.print(" ");Serial.println(mask, BIN);
*port |= mask;
Serial.print("Port: ");Serial.print(*port, DEC); Serial.print(" ");Serial.println(*port, BIN);
}
Gebe ich die Werte in der Funktion aus, so hat das absolut nichts mit dem zu tun was ich eigentlich beabsichtige:
Maske: 32 100000
Port: 255 11111111
Was mache ich falsch?
Grüße Thomas