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

Code:
// 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;
		}
}