Also mein Programm ist noch nicht ganz fertig. Ich hatte meine Drehzahl die ganze Zeit mit Digitalen Widerstaende gestellt, doch das ist zu bloede. Ich versucht heute mal PWM und passte mein Programm dann darauf an.
Das Grundgeruest kann ich aber schonmal freigeben _
Code:
/*
* Motordrehzahlreglung, geschrieben fuer einen ATMega8 mit 8MHz.
* Das Programm ist fuer 2 Motoren geschrieben. Die Lichtschranken
* werden ueber eine Gatter Logig an Pin 6 (T0) angeschlossen. Es wechselt
* alle 62ms die Lichtschranke und vergleicht den Wert der in das Timer/Counter
* Register0 geschrieben wuerde mit einem Sollwert. Danch werden die Motoren langsamer
* oder schneller gestellt.
*
*/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdint.h>
#define nop() asm volatile( "nop" );
#define MS PB0
#define NORMALSPEED 20
volatile uint16_t wayLeft = 0,
wayRight = 0,
wayLeftOld = 0,
wayLeftDiff = 0,
wayRightOld = 0,
wayRightDiff = 0;
volatile uint8_t impulseLeft = 0,
impulseRight = 0,
testLeftWheel = 1,
speedLeft = 0,
speedRight = 0,
geradeausFahren = 1;
// Timer1
SIGNAL(SIG_OVERFLOW1)
{
// Welches Rad ueberpruefen wir?
if (testLeftWheel == 1)
{
wayLeftOld = wayLeft;
// Die Lichtschranke sendet auch manchmal im Stillstand einen Wert von 1
if (TCNT0 <= 1) impulseLeft = 0;
else impulseLeft = TCNT0;
wayLeft += impulseLeft;
wayLeftDiff = wayLeft - wayLeftOld;
if (impulseLeft != speedLeft)
{
if (impulseLeft < speedLeft)
{
// Irgend etwas tun damit der linke Motor schneller dreht
nop();
}
else
{
// Irgend etwas tun damit der linke Motor langsamer dreht
nop();
}
}
testLeftWheel = 0;
// Rechter Motor auswaehlen
PORTB |= (1 << MS);
}
else
{
wayRightOld = wayRight;
if (TCNT0 <= 1) impulseRight = 0;
else impulseRight = TCNT0;
wayRight += impulseRight;
wayRightDiff = wayRight - wayRightOld;
if (impulseRight != speedRight)
{
if (impulseRight < speedRight)
{
// Irgendetwas tun damit der rechte Motor schneller dreht
nop();
}
else
{
// Irgendetwas tun damit der rechte Motor langsamer dreht
nop();
}
}
testLeftWheel = 1;
// Linker Motor auswaehlen
PORTB &=~ (1 << MS);
}
if (geradeausFahren == 1)
{
if (wayLeftDiff < wayRightDiff)
{
// Der rechte Motor hat eine groessere Strecke zurueckgelegt als der linke.
// Den rechten Motor langsamer fahren lassen
}
else if (wayLeftDiff > wayRightDiff)
{
// Der linke Motor hat eine groessere Strecke zurueckgelegt als der recht.
// Den linken Motor langsamer fahren lassen.
}
}
// Timer auf 0 setzten
TCNT0 = 0;
}
int main(void)
{
DDRB = 0xFF; // PORTB as Output
DDRD = 0x00; // PORTD as Input
PORTD = 0xff; // interne Pull-Ups an allen PortD-Pins aktivieren
TCCR0 |= (6<<CS00); // Ext. Clock, falling edge
TCCR1B |= (2<<CS10); // Clk/8
TIMSK |= (1 <<TOIE1); // Timer-1 Interrupt einschalten
speedLeft = 30;
speedRight = 30;
// Interrupts aktivieren
sei();
// Hauptschleife
while (1)
{
// Irgenwelche Befehler ueber z.B USART empfangen
}
}
Lesezeichen