Hallo Leute,
ich habe ein kleines Problem:
Ich habe ein Gehäuse mit Motoren des CC-RP5, AT89C5131 & einen PCF8591 welchen ich über I²C an den µC angebunden habe(zum auslesen von Analogsensoren). Das wird ein kleiner autonomer Roboter / ist es schon.
Mein derzeitiges Programm :
Nun meine Frage : wie bekomme ich eine PWM zur Steuerung der Motoren möglichst einfach hin ? Die Motoren werden über einen L298 geschalten.Code:/*------------------------------------------------------------------+ | File: Roboterfahrzeug | | Autor: | | Klasse: E3GS1 | | Controller: at89c5131 | | Datum: 27.03.13 | | Version: 2 | +--------------------------------------------------------------------+ | Beschreibung: | | | +-----------------------------------------------------------------------------*/ #include <at89c5131.h> // fuer Atmel AT89C5131 /* adda_kniel.c ********************************************************************************* * Hilfsprogramme für den AD- und DA- Umsetzer mit I2C-Bus ******************************** * An DA-Umsetzer wert ausgeben: void aout (unsigned char wert) * AD-Umsetzer einlesen, Kanal = 0,1,2,3: unsigned char ain (unsigned char kanal) ******************************************************************************************/ // geänderte Version 11/2007: Start und Stop-Bedingungen, funktioniert mit US-Sensoren // geänderte Version 12/2006: funktioniert endlich aus als Library: adda.obj mit // Tool -> Library-Manager in die Bibliothek RC51atms.lib einfügen #include <reg51.h> // Registerdefinitionen //#include <intrins.h> // für Rotationsfunktion // !-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-! //****** verwendete I2C-Leitungen ********************************************************* sbit SDA = P4^1; // SDA-Leitung: ED2-Boards P3_5, (USB-Boards P4_1) sbit SCL = P4^0; // SCL-Leitung: ED2-Boards P3_4, (USB-Boards P4_0) //**************************************************************************************** // !-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-! //***** verwendete Adressen und Kontrollbyte für den AD- und DA-Umsetzter **************** #define Motor1 P1 #define Motor2 P2 #define vor 0x50 #define zurueck 0x44 #define stopp 0x40 #define adr_lies 0x91 // 10010001 -> 1001 fest, 000 durch Platine, 1 Wert lesen #define adr_schreib 0x90 // 10010000 -> 1001 fest, 000 durch Platine, 0 Wert lesen #define contr_ain 0x40 // 01000000 -> Kontrollbyte 4 einzelne ADU, Kanal= Offset dazu sbit acc7 = 0xE7; // für Aus- und Eingabe eines Bits des Akkus //void warte(int z); // ***************************************************************************************** // I2C- Routinen zur Ansteuerung eins I2C-Slaves // I2C-Bus-Funktionen i2c_init, i2c_start, i2c_stop, i2c_schreiben, i2c_lesen auch für andere // I2C-Bus-ICs verwendbar // ***************************************************************************************** // **** Zeitverzögerung zur Verlangsamung der Datenübertragungsrate *********************** // **** i=2 bis i=100 wählen je nach I2C-IC und Pull-Up-Widerstand void zeit (void) {unsigned char i; for (i=5;i!=0;i--) ;} void vorwaerts (void); void rueckwaerts (void); void drehen (void); void speaker(void); void warte(int z); void stop(void); // **************************************************************************************** // ****** Initialiserung I2C-Bus ********************************************************** void i2c_init (void) { SDA = 1; // Leitungen in den Grundzustand High zeit (); SCL = 1; zeit (); } // ****** Startbedingung I2C-Bus ********************************************************** void i2c_start (void) { SDA = 1; // Grundzustand SCL = 1; // neu eingefügt 11/07 zeit(); SDA = 0; // Wechsel SDA von 1 -> 0 während SCL = 1 zeit (); SCL = 0; zeit (); } //****** Stoppbedingung I2C-Bus *********************************************************** void i2c_stop (void) { SDA = 0; // neu eingefügt 11/07 SCL = 1; zeit (); SDA = 1; // Wechsel von SDA 0 -> 1 während SCL =1 zeit (); } //***************************************************************************************** // * Byte ausgeben an I2C-Bus , Rückgabewert = Acknoledgebit = 0 wenn erfolgreich // **************************************************************************************** bit i2c_schreiben (unsigned char byte) { unsigned char z; // Zähler bit ack; // Acknoledge-Bit ACC = byte; // Rotationsregister Akku for (z = 8; z != 0; z --) // Zähler: serielle Ausgabe von 8 Bit { SDA = acc7; // Bit7 des Akku ausgeben zeit (); SCL = 1; // Daten sind gültig asm {0x23}; // Akku links schieben //ACC = _crol_ (ACC,1); // links rotieren, Funktion von intrins.h zeit (); SCL = 0; // Datenausabe beendet zeit (); } SDA = 1; // Leitung freigeben für Acknoledge-Bit zeit (); SCL = 1; // Slave kann bestätigen zeit (); // warten ack = SDA; // Acknoledge-Bit lesen zeit (); SCL = 0; // Slave soll Ackn-Ausgabe beenden zeit(); return (ack); // Acknoledge-Bit ist Rückgabewert der Funktion // ack = 0 bedeutet "verstanden" !!!!!! } //***************************************************************************************** // * Byte einlesen vom I2C-Bus. Bei Ack=1 wird Acknoledgebit gesendet, sonst nicht // ***************************************************************************************** unsigned char i2c_lesen (bit ack) { unsigned char z,byte; SDA = 1; // Leitung freigeben (high) für Daten for (z = 8; z != 0; z --) // Zähler: serielles Einlesen von 8 Bit { SCL = 1; // Daten sind gültig zeit (); acc7 = SDA; // Datenbit in den Akku asm {0x23}; // Akku links schieben // ACC = _crol_ (ACC,1); // links rotieren, Funktion von intrins.h //P2_7 = SDA; zeit(); SCL = 0; // Daten lesen beendet zeit(); } byte = ACC; // Eingelesenes Byte if (ack == 1) {SDA = 0;} // Acknowledge-Bit senden else {SDA = 1;} // kein Acknowledge-Bit zeit (); SCL = 1; // Ackn. gültig zeit (); SCL = 0; // Ackn. beendet zeit (); SDA = 0; // Leitung SDA vorbereiten für Stoppbed. zeit (); return (byte); // eingelesenes Byte = Rückgabewert } //************************** ADU und DAU- Funktionen ************************************* //***************************************************************************************** // * AD-Umsetzter einlesen, Kanal = Nr des ADU: 0,1,2,3 // ***************************************************************************************** unsigned char ain (unsigned char kanal) { unsigned char wert; i2c_init (); // I2C-Bus initialisieren (Grundzustand) i2c_start (); // Startbedingung I2C-Bus ausgeben i2c_schreiben (adr_schreib); // Adresse des IC und Schreibwunsch (zur Kanalwahl) i2c_schreiben ( (kanal&0x03) | contr_ain); // Controll-Byte mit Kanalnummer i2c_stop (); // Stoppbedingung I2C-Bus ausgeben i2c_start (); // Startbedingung I2C-Bus ausgeben i2c_schreiben (adr_lies); // Adresse des IC und Lesewunsch i2c_lesen (1); // neue AD-Wandlung Acknoledge = 1 wert = i2c_lesen (0); // Wert abholen Acknoledge =0 i2c_stop (); // Stoppbedingung I2C-Bus ausgeben return (wert); } //***************************************************************************************** // * An DA-Umsetzer wert ausgeben // ***************************************************************************************** void aout (unsigned char wert) { i2c_init (); // I2C-Bus initialisieren (Grundzustand) i2c_start (); // Startbedingung I2C-Bus ausgeben i2c_schreiben (adr_schreib); // Adresse ADU i2c_schreiben (contr_ain); // Control-Byte acu für Analogwert einlesen i2c_schreiben (wert); // Wert ausgeben i2c_stop (); // Stoppbedingung I2C-Bus ausgeben } void main (void) // Hauptprogramm { unsigned char wert; //Definition Variable wert unsigned char swert; //Definition Variable swert zum abfragen P0=0x00; // Port0 - Port3 als Ausgang deklarieren P1=0x00; P2=0x00; P3=0x00; while(1) //While Schleife { P3_1=1; //linke weiße LED ausschalten P3_3=1; //linke rote LED ausschalten P3_5=1; //rechte rote LED ausschalten P3_7=1; //rechte linke LED ausschalten wert = ain(0); //Kanal 0 einlesen und auf wert schreiben P0 = ~wert; //wert auf P0 schreiben swert=wert&0x80; //swert = wert mit 80 Hex "und"-Verknüpft switch(swert) // abfrage von swert { case 0x80: rueckwaerts(); //Wenn swert = 80 Hex dann führe das Programm rückwärtsfahren aus break; // Break um die Abfragen von einander zu trennen default: vorwaerts(); break; // Wenn swert ungleich 80 Hex dann führe das Programm vorwärtsfahren aus } wert = ain(1); P0 = ~wert; swert=wert&0x80; switch(swert) { case 0x80: rueckwaerts(); break; default: vorwaerts(); break; } wert = ain(2); P0 = ~wert; swert=wert&0x80; switch(swert) { case 0x80: rueckwaerts(); break; default: vorwaerts(); break; } } } void vorwaerts (void) //Unterprogramm Vorwärtsfahren { Motor1 = vor; // die höherwertige 1 ist der Enable Pin Motor2 = vor; // die niederwertige 1 ist die Richtung des Motors } void rueckwaerts (void) //Unterprogramm Rückwärtsfahren { unsigned char hinten_abfrage; hinten_abfrage = ain(3); if(hinten_abfrage>=0x40) { drehen(); } else { stop(); // Sprung ins Unterprogramm stop P3_1=0; // LED links weiß an P3_3=1; // LED links rot aus P3_5=1; // LED rechts rot aus P3_7=0; // LED rechts weiß an Motor1 = zurueck; // Motoren nach hinten fahren lassen Motor2 = zurueck; speaker(); // Unterprogramm für den Piepser drehen(); // Verzweigungs ins Unterprogramm drehen } } void drehen (void) // Unterprogramm drehen { double long x; // Variable x mit einem großen Datenbereich adressieren Motor1 = zurueck; // Motor 1 rückwärts fahren lassen Motor2 = vor; // Motor 2 vorwärts fahren lassen for(x=0;x<2100;x++); // Warteschleife in der x hochgezählt wird } void stop(void) // Unterprogramm stop & rote LEDS an { Motor1=stopp; // Enable pin & Drehrichtungsangabe aus Motor2=stopp; P3_3=0; // LED links rot an P3_5=0; // LED rechts rot an warte(50); // Sprung ins unterprogramm warte mit Übergabe einer Variablen } void speaker (void) // Unterprogamm für die Lautsprecher { P3_0=1; // Lautsprecher an warte(25); // Sprung ins unterprogramm warte mit Übergabe einer Variablen P3_0=0; // Lautsprecher aus warte(10); // Sprung ins unterprogramm warte mit Übergabe einer Variablen P3_0=1; warte(25); P3_0=0; } void warte(int z) // Unterprogramm fürs Warten { int s, x; // definieren von Variablen for(s=z;s>0;s--) // s nimmt den Wert von z an welche vorher übergeben wurde. s wird runtergezählt { for(x=2000;x>0;x--); // for schleife in welcher x runtergezählt wird } }







Zitieren


Lesezeichen