Hallo!
Scheint ein klasse Forum zu sein in dem einem schnell geholfen wird,
daher hier mein erster Versuch!
Bin seit Tagen am grübeln wie ich es am besten programmieren soll. Hier
mal die Randdaten:
- Getriebemotor ist über eine Polwenderschaltung an den Ausgängen PB2
und PB3
- Mittels Taster soll automatisch bis zur Endposition aufgefahren werden
- Mittels Schalter solang der geschaltet ist
- Falls Endschalter nicht auslöst soll nach einer maximalen Zeit
ausgeschaltet werden
Realsiert wurde das ganze jetzt über Hardwareinterrupts an INT0 und INT1
(Fallende Flanke da Endschalter gegen Masse schalten) und mit dem 16Bit
Timer, der im CTC Modus läuft und nach ungefähr 21 Sekunden auslöst.
Ich kann das Programm erst wieder am WE testen da ich dann zu Hause bin,
wollte aber vorab wissen ob es so gehen könnte. Bin mir besonders bei
dem Timer und der Zeit-Variablen unsicher (Wie kann ich es am
geschicktesten lösen, dass der Timer nicht mehr weiter zählt wenn der
Schalter zurückgestellt wurde und dann beim nächsten mal auch wieder bei
0 anfängt.). Hatte mir gedacht das man ja eine 8-Bit Zahl braucht die
man dann verundet, sobald der Timer den Wert in OCR1A erreicht wird Zeit
genullt und er springt raus!?
Danke für die Hilfe!
# include <avr/io.h>
# include <util/delay.h>
# include <avr/interrupt.h>
//Eingänge
#define Endschalter_Innen PD2 //(INT0) blau grün
#define Endschalter_Außen PD3 //(INT1) weiß gelb
#define Schalter_Auf PD4
#define Schalter_Zu PD5
#define Taster_Auf PD6
#define Taster_Zu PD7
//Ausgänge
#define Motor_Auf PB2
#define Motor_Zu PB3
volatile uint8_t Zeit;
void delay_ms(uint16_t ms)
{
for(uint16_t t=0; t<=ms;t++)
_delay_ms(1);
}
ISR (INT0_vect)
{
PORTB &= ~(1 << PB3);
TIMSK &= ~(1 << OCIE1A); //CTC-IRQ deaktivieren
}
ISR (INT1_vect)
{
PORTB &= ~(1 << PB2);
TIMSK &= ~(1 << OCIE1A);
}
ISR (TIMER1_COMPA_vect)
{
PORTB &= ~(1 << PB3);
PORTB &= ~(1 << PB2);
TIMSK &= ~(1 << OCIE1A);
Zeit = 0;
}
int main ()
{
DDRD=0x00; //DDRD als Eingang
PORTD=0xFF; //interne Pull-Ups aktiv
DDRB |= (1 << PB2)|(1 << PB3);
GICR = (1 << INT0)|(1 << INT1); // Interrupts INT0 and INT1
aktiviert
MCUCR = (1 << ISC01)|(1 << ISC11); // Interrupts INT0 und INT1 bei
fallender Flanke
TCCR1B |= (1 << WGM12); //CTC-Modus aktiv; Überlauf bei
erreichen des Wertes in OCR1A
TCCR1B |= (1 << CS12)|(1 << CS10); // Prescaler: 1/1024
OCR1A = 21500; //Festlegen des CTC-Wertes
sei();
while(1)
{
Zeit= 11110000;
if (!(PIND & (1<<PIND6))) //Taster auf
{
if (PIND & (1<<PIND3)) //Endschalter außen noch nicht
erreicht
{
delay_ms (50); //Sehr simples entprellen
PORTB = PORTB | ( 1 << PB2 );
TIMSK |= (1 << OCIE1A); //Compare A IRQ Enable
}
}
if (!(PIND & (1<<PIND7))) //Taster zu
{
if (PIND & (1<<PIND2)) //Endschalter innen noch nicht
erreicht
{
delay_ms (50);
PORTB = PORTB | ( 1 << PB3 );
TIMSK |= (1 << OCIE1A);
}
}
while ((!(PIND & (1<<PIND4))) ^ Zeit) //Schalter auf
{
if (PIND & (1<<PIND3)) //Endschalter außen noch nicht
erreicht
{
delay_ms (50);
PORTB = PORTB | ( 1 << PB2 );
TIMSK |= (1 << OCIE1A);
}
}
while ((!(PIND & (1<<PIND5))) ^ Zeit) //Schalter zu
{
if (PIND & (1<<PIND2)) //Endschalter innen noch nicht
erreicht
{
delay_ms (50);
PORTB = PORTB | ( 1 << PB3 );
TIMSK |= (1 << OCIE1A);
}
}
}
}
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.