PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Radencoder- und Timer-Probleme



Speedking
26.07.2006, 23:18
Hallo Forum,

nach zwei Wochen Lektüre auf der Insel Samos habe ich nun einiges dazu gelernt, in Sachen Mega32-Programmierung.

Zuhause angekommen läuft aber nur wenig mir meinem neuen Bot.

Ich habe Probleme mit der PWM-Programmierung mit dem Timer 1 und mit der Interrupt-Programmierung zwecks Verarbeitung der Radencoder.

Ich habe alles in das Listing gepackt. Auch nähere Erklärungen und so.

Eventuell fällt ja einem Bot-Profi sofort was auf.

Übrigens programmiere ich in C und habe einen q-fix-crash-bobby mit den rn-control aufgerüstet. Die RS232-Verbindung erfolgt über rn-funk (noch nicht getestet).

Ich hoffe den Bot lauffertig (fährt und kann Strecken messen) bis zum Ende der Sommerferien (in 2 Wochen) zu bekommen. Der Bot soll in einer Realschule als Motivationsschub und Technolieträger verwendet werden.

Vielen Dank schon mal im Vorraus.... Klaus O:)


// Ich verwende das rn-control-board mit drei Entfernungssensoren (Sharp) an Port A
// Zwei Radencodern mit je 120 Einteilungen
//
// Herausforderung Nr.1:
// Die Motoren laufen (langsam) an, wenn ich die Laufrichtung einstelle (PB0 und PB1)
// und den PWM-Ausgang (PD5) dauerhaft auf 1 setze.
// Die von mir gew�lten Einstellungen fr den fast-PWM-Betrieb von Timer 1 scheinen aber nicht zu funktionieren.
// Jedenfalls passiert an den Motoren nix.
// Was also stimmt bei den Einstellungen nicht ?
// Mu�man den Timer irgenwie erst einschalten oder "anschieben"?
//
//
// Herausforderung Nr.2:
// Ich habe die Einstellungen so gew�lt, damit ich die Signale der Radencoder,
// die an INT0 und INT1 des Controllers angeschlossen sind jeweils einen Interrupt ausl�en und
// eine globale Z�lvariable hochsetzen, die ich dann im Programm abfragen und auch l�chen kann.
// Jedenfalls kann ich in meinen Einstellungen keinen Fehler finden.
// Die Variablen werden jedoch aus irgend einem Grunde nicht hochgez�lt.
//
// Herausforderung Nr.3:
// Ich m�hte noch zwei digitale IR-Sensoren an meinen Bot anschlie�n. An Port A habe ich noch einige Pins frei.
// Allerdings nutze ich den Port ja schon als A/D-Wandler fr die drei IR-Entfernungssensoren.
// Kann ich die brigen Pins an Port-A als "normale" digitale Eing�ge und gleichzeitig
// Pin 0 bis Pin 2 als A/D-Eing�ge verwenden ?
// Was mu�ich dazu in den Einstellungen ver�dern ?

// Vielen Dank schon mal im Vorraus !!

// Bis dahin.... Klaus


#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

//-----------------------------------------------

#define SYSCLK 16000000
#define F_CPU 16000000;
#define BAUDRATE 19200;

#define ball_l 6
#define ball_r 7

#define IR_l 5
#define IR_m 4
#define IR_r 3

//-----------------------------------------------

static uint32_t rad_l = 0;
static uint32_t rad_r = 0;
static uint32_t clicks_l = 0;
static uint32_t clicks_r = 0;

//-----------------------------------------------

// Port-Konfiguration
//-----------------------------------------------
// PORT A:
// analog in + ein Taster an PA7
DDRA = 0; // Alles auf input 0 0 0 0 0 0 0 0
PORTA = 128; // Pullup setzen fr den Taster an PA7 1 0 0 0 0 0 0 0


//-----------------------------------------------
// PORT B:
// Motortreiber: PB0 und PB1
DDRB = 2+1; // Bit 0 und 1 als output setzen 0 0 0 0 0 0 1 1
PORTB = 0;


//-----------------------------------------------
// PORT C:
// Motortreiber: PC7 und PC6
DDRC = 0xff; // Alle Bits als output setzen 1 1 1 1 1 1 1 1
PORTC = 32+16+8+4+2; // Bit 0 bis Bit 5 setzen fr 5 LEDs 0 0 1 1 1 1 1 1


//-----------------------------------------------
// PORT D:
// Motortreiber: PD4 und PD5
// Lautsprecher: PD7
DDRD = 128+32+16; // Bit 4 und 5 als output setzen 1 0 1 1 0 0 0 0
PORTD |= 128; // 1 0 0 0 0 0 0 0


//-----------------------------------------------
// A/D-Wandler-Einstellungen ( Prescaler = 128, interne +5V Referenz, "8-Bit" Ergebnis )
ADMUX = (1<<REFS0)|(1<<ADLAR);
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
// SFIOR &= ~(1<<ACME);


//-----------------------------------------------
// Interrupt-Register setzen
GICR = (1<<INT0)||(1<<INT1); // Externe Ints aktivieren (Int0 und Int1)
MCUCR = (1<<ISC00)||(1<<ISC10); // logische �derungen an Int0 und Int1 fhren zum Interrupt


//-----------------------------------------------
// Timer1-Einstellung fr PWM-Betrieb
void initTimer1()
{
OCR1A = 255; // Match-Level fr Kanal A
OCR1B = 255; // Match-Level fr Kanal B
TCCR1A= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TCCR1B= (1<<WGM12)|(1<<CS12)|(1<<CS10);
TIMSK = (1<<OCIE1A)|(1<<OCIE1B);
sei(); // Alle Interrupts global einschalten
}


// Interrupt-Routine fr Radencoder links
SIGNAL(SIG_INTERRUPT0)
{ clicks_l++;
if(clicks_l >= 120)
{rad_l++;
clicks_l=0;
}
}

//-----------------------------------------------
// Interrupt-Routine fr Radencoder rechts
SIGNAL(SIG_INTERRUPT1)
{ clicks_r++;
if(clicks_r >= 120)
{rad_r++;
clicks_r=0;
}
}