ASURO Library  2.80
Makrodefinitionen | Funktionen | Variablen
asuro.c-Dateireferenz

Init- und Interrupt-Funktionen der Asuro Library.
Timer2 wird mit 36 kHz betrieben, im Gegensatz zur ausgelieferten
Version mit 72 kHz. Mehr ...

#include "asuro.h"
#include "myasuro.h"
Include-Abhängigkeitsdiagramm für asuro.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define BAUD_RATE   2400
 

Funktionen

void IsrStandard (void)
 
void Init (void)
 Initialisiert die Hardware: Ports, A/D Wandler, Serielle Schnittstelle, PWM
Die Init Funktion muss von jeden Programm beim Start aufgerufen werden.
 
 SIGNAL (TIMER2_OVF_vect)
 
 if (!count36kHz) timebase++
 
 SIGNAL (ADC_vect)
 

Variablen

volatile unsigned int adcValue [6]
 

Ausführliche Beschreibung

Init- und Interrupt-Funktionen der Asuro Library.
Timer2 wird mit 36 kHz betrieben, im Gegensatz zur ausgelieferten
Version mit 72 kHz.

Interrupt-Doku nur ueber die Datei zu sehen:
Bitte ueber den oben ausgegebenen Link 'gehe zum Quellcode
dieser Datei' direkt in der Datei nachsehen.
DoxyGen ist nicht zur Erkennung von Interrupt-Funktionen 'bereit'.
Behandelt werden folgende Interrupts:
  • TIMER2_OVF_vect : Timer 2 (fest mit 36 kHz belegt)
  • ADC_vect : Analog-Digital-Wandler
Wichtiger Hinweis:
Die Init()-Funktion muss von jedem Programm beim Start
aufgerufen werden.
Siehe auch
Defines zum setzen von Port's und Konfigurationen in asuro.h
IRTX, LEFT_DIR, PWM, GREEN_LED, RIGHT_DIR, FRONT_LED,
ODOMETRIE_LED, RED_LED, ON, OFF, GREEN, FWD, TRUE, FALSE
Version
V— - 10.11.2003 - Jan Grewe - DLR
Original Version von der ASURO CD
V— - 20.11.2006 - m.a.r.v.i.n
+++ SIGNAL (ADC_vect)
static Variable toggle mit FALSE initialisiert.
(Bug report von Rolf_Ebert)
V— - bis zum 07.01.2007 -
Bitte in Datei CHANGELOG nachsehen.
V001 - 13.01.2007 - m.a.r.v.i.n
+++ Alle Funktionen
Zerlegte Sourcen in einzelne Dateien fuer eine echte Library.
V002 - 27.01.2007 - Sternthaler
+++ Alle Funktionen
Kommentierte Version (KEINE Funktionsaenderung)
V003 - 20.02.2007 - m.a.r.v.i.n
Defines fuer Dometrie High/Low Werte aus myasuro.h verwenden StopSwitch ersetzt. Deshalb wurde immer die komplette switches.o mitgelinkt
V004 - 15.11.2007 - m.a.r.v.i.n
RIGHT_DIR und LEFT_DIR waren in der Init Funktion vertauscht
V005 - 29.01.2008 - m.a.r.v.i.n
Initialisierung fuer ATmega168
UART Baudrate einstellbar durch Define
Interrupt User Funktionen für Timer und A/D Wandler
V006 - 29.03.2009 - rossir
A/D Wandler Abfrage ueber Interrupt
V007 - 2013-11-25 - matze Some SIGNALS became deprecated, so I replaced them: SIG_OVERFLOW2 -> TIMER2_OVF_vect SIG_OUTPUT_COMPARE2A -> TIMER2_COMPA_vect SIG_OUTPUT_COMPARE2 -> TIMER2_COMP_vect SIG_ADC -> ADC_vect

Definiert in Datei asuro.c.

Makro-Dokumentation

#define BAUD_RATE   2400

Definiert in Zeile 70 der Datei asuro.c.

Dokumentation der Funktionen

if ( count36kHz)

being used insted TIMER2_OVF_vect during ultrasonic polling

void Init ( void  )

Initialisiert die Hardware: Ports, A/D Wandler, Serielle Schnittstelle, PWM
Die Init Funktion muss von jeden Programm beim Start aufgerufen werden.

Siehe auch
Die Funktionen Sleep() und Msleep() in time.c werden mit dem hier
eingestellten 36 kHz-Takt betrieben.
Funktionsweise der Zeitfunktionen:
Msleep() ruft Sleep() auf. In Sleep() wird die globale Variable count36kHz
zur Zeitverzoegerung benutzt. Diese Variable wird jedesmal im Interrupt
TIMER2_OVF_vect um 1 hochgezaehlt.
Der Interrupt selber wird durch den hier eingestellten Timer ausgeloesst.
Somit ist dieser Timer fuer die Zeitverzoegerung zustaendig.
Siehe auch
Die globale Variable autoencode fuer die automatische Bearbeitung der
Odometrie-ADC-Wandler wird hier auf FALSE gesetzt.
Hinweis zur 36 kHz-Frequenz vom Timer 2
Genau diese Frequenz wird von dem Empfaengerbaustein benoetigt und kann
deshalb nicht geaendert werden.
In der urspruenglichen, vom Hersteller ausgelieferten LIB, war diese
Frequenz allerdings auf 72 kHz eingestellt. Durch eine geschickte
Umkonfigurierung durch waste konnte diese aber halbiert werden.
Sinnvoll ist dies, da der durch diesen Timer2 auch ausgeloesste Timer-
Interrupt dann nur noch die Haelfte an Rechenzeit in Anspruch nimmt.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
// Die Init()-Funktion MUSS IMMER zu Anfang aufgerufen werden.
int main (void)
{
int wert;
Init ();
while (1)
(
// Dein Programm
}
return 0;
}

Definiert in Zeile 228 der Datei asuro.c.

{
/*
Timer2, zum Betrieb mit der seriellen Schnittstelle, fuer die
IR-Kommunikation auf 36 kHz eingestellt.
*/
#if defined(__AVR_ATmega168__)
// fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
TCCR2A = _BV(WGM20) | _BV(WGM21) | _BV(COM2A0) | _BV(COM2A1);
TCCR2B = _BV(CS20);
// interrupt on timer overflow
TIMSK2 |= _BV(TOIE2);
#else
// fast PWM, set OC2A on compare match, clear OC2A at bottom, clk/1
TCCR2 = _BV(WGM20) | _BV(WGM21) | _BV(COM20) | _BV(COM21) | _BV(CS20);
// interrupt on timer overflow
TIMSK |= _BV(TOIE2);
#endif
// 36kHz carrier/timer
OCR2 = 0x91;
/*
Die serielle Schnittstelle wurde waerend der Boot-Phase schon
programmiert und gestartet. Hier werden die Parameter auf 2400 1N8 gesetzt.
*/
#if defined(__AVR_ATmega168__)
UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR0B = (1<<RXEN0) | (1<<TXEN0);
UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
#else
UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate
UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1
#endif
/*
Datenrichtung der I/O-Ports festlegen. Dies ist durch die Beschaltung der
Asuro-Hardware nicht aenderbar.
Port B: Seriell Senden; Richtungsvorgabe Motor links; Takt fuer die
Geschwindigkeit beider Motoren; Grueneanteil-Status-LED
Port D: Richtungsvorgabe Motor rechts; Vordere LED;
Odometrie-LED (Radsensor); Rotanteil-Status-LED
*/
DDRB = IRTX | RIGHT_DIR | PWM | GREEN_LED;
DDRD = LEFT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED | SWITCHES; // Port-Bits als Output
/*
PWM-Kanaele OC1A und OC1B auf 8-Bit einstellen.
Sie werden fuer die Geschwindigkeitsvorgaben der Motoren benutzt.
*/
TCCR1A = _BV(WGM10) | _BV(COM1A1) | _BV(COM1B1);
TCCR1B = _BV(CS11); // tmr1-Timer mit MCU-Takt/8 betreiben.
/*
Sonstige Vorbereitungen.
- Alle LED's ausschalten
- Motoren stoppen und schon mal auf Vorwaerts einstellen.
- Globale Variable autoencoder ausschalten.
*/
MotorSpeed (0, 0);
/*
* Vorbereitung für WHEEL-Interrupts (Encoder)
Port C als Input => dadurch gehen die Back-LED aus ...
*/
DDRC &= ~ (_BV(PC0) | _BV(PC1));
/*
... aber nun koennen die LED's am Rad eingeschaltet werden, und die
Sensoren koennen gemessen werden.
*/
/*
Linken Odometrie-Sensor auswaehlen. (AVCC ref. with external capacitor)
*/
ADMUX = _BV(ADLAR) | _BV(REFS0) | WHEEL_LEFT;
/*
AD-Wandler einschalten, Parameter einstellen und Starten. (clk/128)
Startet den ADC im 'free running'-Mode (ADFR). Das heisst, der Wandler
nach einer Messung automatisch wieder neu startet.
*/
ADCSRA = _BV(ADEN) | _BV(ADFR) | _BV(ADIE) | _BV(ADSC) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
/*
Funktion zum ALLGEMEINEN ZULASSEN von Interrupts.
*/
sei ();
}
void IsrStandard ( void  )

Definiert in Zeile 138 der Datei asuro.c.

{
static int sign[2]={1,1}, avg[2], adc_cnt = 0;
static unsigned char mux[]={
_BV(ADLAR) | _BV(REFS0) | IR_RIGHT, // AVCC reference with external capacitor
_BV(ADLAR) | _BV(REFS0) | IR_LEFT, // AVCC reference with external capacitor
_BV(ADLAR) | _BV(REFS0) | SWITCH,
_BV(ADLAR) | _BV(REFS0) | BATTERIE | _BV(REFS1), // internal 2.56V reference with external capacitor
_BV(ADLAR) | _BV(REFS0) | WHEEL_RIGHT, // AVCC reference with external capacitor
_BV(ADLAR) | _BV(REFS0) | WHEEL_LEFT, // AVCC reference with external capacitor
};
// Vielleicht hat Rakke ja Recht:
// ADCL muss zuerst gelesen werden! Sonst können sich zwei Wandlungen überschneiden.
unsigned int sensor = ADCL | (ADCH << 8);
adcValue[adc_cnt]=sensor;
if(autoencode) // Aus Kompatibilitätsgründen wird autoencode weiter benutzt
{
if(adc_cnt<2) { // WHEEL_RIGHT || WHEEL_LEFT
int s=(sensor >> 8);
// In avg wird ein gleitender Mittelwert mitgeführt: a(n+1) = 0.75*a(n)+0.25*s
avg[adc_cnt] += (s-avg[adc_cnt])>>2;
// Schneidet die aktuelle Sensorkurve den gleitenden Mittelwert? Konkret:
// Weicht der aktuelle Sensorwert um mehr als +/- 2 vom gleitenden Mittelwert ab?
if (sign[adc_cnt]*(s-avg[adc_cnt]) > 2)
{
// Dann zähle einen Tick weiter.
// Und nächster Tick erst wieder bei -/+ 2 Abweichung vom gleitenden Mittelwert.
encoder[adc_cnt^RIGHT]++;
sign[adc_cnt] = -sign [adc_cnt];
}
}
}
if(adc_cnt==SWITCH) {
switched=switched || sensor<(MY_SWITCH_THRESHHOLD<<6); // Es wurde (ganz sicher) eine Taste gedrückt
}
ADMUX = mux[adc_cnt];
adc_cnt=(adc_cnt+1) % sizeof(mux);
}
SIGNAL ( TIMER2_OVF_vect  )

Definiert in Zeile 356 der Datei asuro.c.

{
TCNT2 += 0x25;
if (!count36kHz)
}
SIGNAL ( ADC_vect  )

Definiert in Zeile 403 der Datei asuro.c.

{
}

Variablen-Dokumentation

volatile unsigned int adcValue[6]

Definiert in Zeile 78 der Datei asuro.c.