Code:
/* >>
Stand ...\C4\C4\SVbby2\SVbby1p.c
=============================================================================== =
Target MCU : ATmega 328p QFM
Target Hardware : babyorangutan und Micromotor als Servo mit Standardfunktion
Target cpu-frequ. : 20 MHz Resonator
=============================================================================== =
. . . . Code gestrichen
============================================================================== */
. . . . Code gestrichen
// ============================================================================= =
// === HAUPTProgramm ========================================================== =
. . . . Code gestrichen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// === Grundlegende Initialisierungen der Hardware, Portdefinition (PDIP !!)
// PCINT14,/RESET,PC6 1 28 PC5,ADC5,SCL,PCINT13
// PCINT16,RxD,PD0 2 27 PC4,ADC4,SDA,PCINT12
// PCINT17,TxD,PD1 3 26 PC3,ADC3,PCINT11
// PCINT18,INT0,PD2 4 25 PC2,ADC2,PCINT10
// PCINT19,OC2B,INT1,PD3 5 24 PC1,ADC1,PCINT9
// PCINT20,XCK,T0,PD4 6 23 PC0,ADC0,PCINT8
// VCC 7 22 GND
// GND 8 21 AREF
// PCINT6,XTAL1,TOSC1,PB6 9 20 VCC
// PCINT7,XTAL2,TOSC2,PB7 10 19 PB5,SCK,PCINT5
// PCINT21,OC0B,T1,PD5 11 18 PB4,MISO,PCINT4
// PCINT22,OC0A,AIN0,PD6 12 17 PB3,MOSI,OC2,OC2A,PCINT3
// PCINT23,AIN1,PD7 13 16 PB2,/SS,OC1B,PCINT2
// PCINT0,CLKO,ICP1,PB0 14 15 PB1,OC1A,PCINT1
// - - - - - - - - - - - - - - -
// Initialisierung der BOARD!! Anschlüsse am babyorangutan mit mega328-TQFP:
// /RESET, PC6 1 EU A 28 PC5 ============
// UART-RxD, PD0 2 EU A 27 PC4 ====
// rtUserLED, UART-TxD, PD1___3 EU A 26___PC3
// Encoder-1-A, INT0, PD2 4 EU A 25 PC2, TASTEJ-GND
// Motor2B, OC2B, PD3 5 EU EU 24 PC1, TASTEJ-In = PCINT9
// Encoder-1-B, PCINT20, PD4___6 EU A 23___PC0
// +++ VCC 7 + - 22 GND ---
// --- GND 8 - + 21 AREF ref
// XTAL1 PB6___9 A 20___AVCC
// XTAL2 PB7 10 A A 19 PB5, SCK, PCINT5
// Motor1B, OC0B, PD5 11 EU A 18 PB4, MISO, (GND)-blaue-LED
// Motor1A, OC0A, PD6__12 A A 17___PB3, MOSI, OC2A, Motor2A
// Taste rechts, PD7 13 A A 16 PB2, (+)-blaue LED
// (+)-heartbeat, PB0 14 A A 15 PB1, (GND)-Heartbeat-LED
// Anmerkungen zu den Motoren: die Controllerpins sind NUR über
// sind NUR über den Motortreiber (Wahrheitstabelle!!) zu erreichen
// - - - - - - - - - - - - - - -
// Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pins/Pull Ups (1) aktiv.
// A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp, Belegung siehe oben
DDRB = 0b11101111; // Heartbeat auf B0(+)/(GND -)
PORTB = 0b00010000; // PB5: PCI für Servopuls
//
DDRC = 0b00111101; // PC0, PC2-5, PC6+7-Pin H I E R bei babyorangutan (MLF)
PORTC = 0b11000010; // PC0, PC2-5 sind aktuell Ausgänge ##>> KEIN Pullup !!
//
DDRD = 0b01101011; // RX/TX-PD0/1, PD5/PD6 = M1B/M1A, PD7 = Taste: PullUP !
PORTD = 0b10010100; // Pull Ups aktivieren, mit pololuMot AUCH bei INT0/~1
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
. . . . Code gestrichen
Build succeeded with 0 Warnings...
============================================================ */
Initialisierungen und Auswertung der Encodereingänge
Code:
/* >>
Stand ...\C4\SVbby1p\Sbby1p_motij.c
=============================================================================== =
. . . . Code gestrichen
=============================================================================== =
*** Versionsgeschichte:
====================
x24 23Nov16 1450 Motor EINschalten erst nach Einstellung der "Hand auf für Geld"
. . . . Code gestrichen
============================================================================== */
// ============================================================================= =
// === Initialisierung externer Interrupts bei m328, doc 8271I
// EXT_INT0 auf PORTD2 -- Encoder IencB0 auf PIND2
// ============================================================================= =
void XTI0_int( void ) // Initialisiere Interrupt 0, PD2, auf ANY edge
{ // => EICRA ISC00 + ~10 auf 1 S71
// - - - - - - - - - - - - - - - -
// Initialisiere PD2 als externen Interrupt, ANY edge
EICRA |= (1<<ISC00); // INT0 triggert auf jede Flanke (any edge)
EIMSK |= (1<<INT0); // erlaube INT0
// Initialisierung der Zeiten:
Iencdr0 = Iz_diff0 = Iz_yseci0 = Iz_ysecv0 = 0;
tmrE0 = 0; // Timer für Drehzahlerfassung
//
Iencdr0 = Iencdef0; // Initialisiere Startwert Encoder (vgl. main)
IencB0 = IenBdef0; // Initialisiere Startwert Encoder
//
} // Ende von void XTI_0_1_init( void )
// ============================================================================= =
// ============================================================================= =
// === Nicht unterbrechbare ISR für EXT_INT0(any edge auf mega328 ======== =
// Der Timer tmrE0 wird ausgelesen für Laufzeit des EXT_INT0 auf PD2.
// Enc-zähler Iencdr0 wird mit jedem Tick hochgezählt, ohne Richtung=any edge
// Encoder IencB0 wird richtungskonform hochgetickert => gesamte Fahrstrecke
// seit Rücksetzen (irgendwo); Aussage über Drehrichtung ist gegeben
// EXT_INT0 (Enc-spurA) triggert auf PORTD 2
// PCINT20 (ENC-spurB) triggert auf PORTD 4
// ============================================================================= =
ISR(INT0_vect) // INT0-PD2 triggert ANY edge => lesen Iencdr0/A
{ // => Bei Aufruf PORTD2 prüfen auf high/low
// - - - - - - - - - - - - - - - -
//251116 if ( Isecstrt ) return; // Keine Messung in der Startphase
// ToggleBit ( PBLED, LBb ); // blLED toggeln, PORTB, blLED auf PB2
Iz_diff0 = tmrE0; // Hier die Zeit (in x 50µs-tupsi) seit letztem ISR-Aufruf
tmrE0 = 0; // Timer für Encoderinterupts auf Null
Iencdr0 ++; // Incrementiere Encodercounter, NUR aufwärts
if ((IsBitSet (PIND, 2)) == (IsBitClr (PIND, 4))) IencB0++;
// Rad treibt vorwärts, math. negativ
else IencB0--; // Rad treibt rückwärts, math. positiv
} // Ende ISR(INT0_vect)
// ============================================================================= =
// ============================================================================= =
// === Initialisierung Pin Change Interrupt bei m328, doc 8271I
// PCINT[23:16], PORT D4, any Edge <=> Für Zählung Encoderflanken Spur "B"
// Die zugehörige ISR tickert Iencdr0 und IencB0 rauf bzw. runter
// ==>> Die Zeit-/Drehzahlerfassung bleibt NUR bei EXT_INT0/PB2
// ============================================================================= =
void PCI2_int( void ) // Initialisiere PCI 20, PB4, any edge doc 74
{ //
// - - - - - - - - - - - - - - - -
//251116 if ( Isecstrt ) return; // Keine Messung in der Startphase
PCICR |= ( 1<<PCIE2 ); // Auswahl PCINT[23:16] ; hier PD4; siehe PCMSK2
// PCI triggert auf jede Flanke (any edge)
PCMSK2 |= ( 1<<PCINT20 ); // Interrupt kommt von PB5
} // Ende von void XTI_0_1_init( void )
// ============================================================================= =
// ============================================================================= =
// === Nicht unterbrechbare ISR für PCINT0 auf PB5; mega328
// PCINT[7:0], PORTB5, any Edge <=> Für Pulszeitmessung Servopuls
// Die zugehörige ISR misst die Pulszeit tPULS für einen Servo in [tupsi]
// also die Zeit, in der der Servopuls auf high steht
// Siehe dazu ISR(TIMER1_COMPA..
// ============================================================================= =
ISR(PCINT2_vect) // PCINT2 triggert ANY edge => lesen Iencdr0/B
{ // prüfe ob PB5 = high, nur dann Wert übernehmen
// - - - - - - - - - - - - - - - -
//251116 if ( Isecstrt ) return; // Keine Messung in der Startphase
// ToggleBit ( PBLED, LBb ); // blLED aus, PORTB, blLED auf PB2
Iz_diff0 = tmrE0; // Hier die Zeit (in x 50µs-tupsi) seit letztem ISR-Aufruf
tmrE0 = 0; // Timer für Encoderinterupts auf Null
Iencdr0 ++; // Incrementiere Encodercounter, NUR aufwärts
if ((IsBitSet (PIND, 2)) == (IsBitClr (PIND, 4))) IencB0--;
// vgl. ISR(INT0_vect)
else IencB0++; // vgl. ISR(INT0_vect)
//
} // Ende ISR(PCINT2_vect)
// ============================================================================= =
. . . . Code gestrichen
// ============================================================================= =
// ===== ENDE Subroutinen ================================================= =
// ============================================================================= =
Der Wert tmrE0 enthält die Anzahl der Zeiteinheiten für die Drehzahlmessung - wird von einem Timer geliefert.
Lesezeichen