@robocat:
Das stimmt natürlich. Hab das eben erstmal geändert.
Das mit dem schalten, fürs rückwärtsdrehen klappt jetzt.
Aber, wer hätte das gedacht, ich hab natürlich gleich noch ein Problem.
Die Motoren brummen nur und quälen sich voll rum, seitdem ich das Array programmiert hab. Hab das setzen vom ADSC-Bit auch vorher nicht in der Main-Funktion gehabt. Selbst wenn ich OCR0 und OCR2 den wert 150 gebe ändert sich nichts.
Ohne das Array laufen die Motoren ganz normal.
Hier is mein ganzer Code:
Code:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#ifndef F_CPU
#define F_CPU 16000000
#endif
#define Scheinwerfer PD0
#define Rueckleuchten PD1
#define PWM_ServoPort PD5
#define IR_Servo OCR1A
#define Motor_Links PB3
#define Motor_Rechts PD7
#define Motor_Links_Rueck PC0
#define Motor_Rechts_Rueck PC1
/*************************************Prototypes****************************************/
void helligkeitsmessung(void);
int IR_Servoposition(void);
void Motorsteuerung(int);
int GP2D12(void);
/***************************************************************************************/
/**********************************Globale Variablen************************************/
uint8_t count=0, reward_time=0;
int8_t posi=25, a=1, changechannel=0;
uint16_t LDR;
uint16_t IR_Wert[51]; //Array für Messwerte 0-50
/***************************************************************************************/
/**********************************Interruptroutinen************************************/
//--------------------------------------Timer1COMB--------------------------------------
ISR(TIMER1_COMPB_vect)
{
count++;
}
//-----------------------------------------ADC------------------------------------------
ISR(ADC_vect)
{
if (changechannel<=0)
{
changechannel++;
ADMUX |= (1<<MUX0); //Eingang ADC1 vorbereiten für den IR-Sensor
LDR = ADC;
}
else
{
changechannel=0;
ADMUX &= ~(1<<MUX0); //Eingang ADC0 vorbereiten für LDR-Messung
IR_Wert[posi]=ADC;
}
}
/****************************************************************************************/
/***************************************Routinen*****************************************/
//---------------------------------Helligkeitsmessung---------------------------------
void helligkeitsmessung(void)
{
if (LDR<=150)
{
PORTD |= (1<<Scheinwerfer);
PORTD |= (1<<Rueckleuchten);
}
if (LDR>=190)
{
PORTD &= ~(1<<Scheinwerfer);
PORTD &= ~(1<<Rueckleuchten);
}
}
//-------------------------------------IR_Servosteuerung---------------------------------------
int IR_Servoposition(void)
{
if (a>=1)
{
posi++;
if (posi>=50)
{
a=0;
}
}
if (a<=0)
{
posi--;
if (posi<=0)
{
a=1;
}
}
return ((posi)+440); //440=min, 490=max
}
//--------------------------------------Motorsteuerung-----------------------------------------
void Motorsteuerung(int Hinderniss_info)
{
OCR0=100; //Maximal 255
OCR2=100; //Maximal 255
if(Hinderniss_info<=15)
{
PORTC |= (1<<Motor_Rechts_Rueck); //Roboter soll sich nach Rechts drehen
}
else
{
PORTC &= ~(1<<Motor_Rechts_Rueck); //Roboter soll aufhören nach Rechts zu drehen
}
if(Hinderniss_info>=35)
{
PORTC |= (1<<Motor_Links_Rueck); //Roboter soll sich nach Links drehen
}
else
{
PORTC &= ~(1<<Motor_Links_Rueck); //Roboter soll aufhören nach Lins zu drehen
}
}
//------------------------------------------GP2D12---------------------------------------------
int GP2D12(void)
{
uint8_t i, memoposi=0;
uint16_t memo=0xffff; //zum merken des kleinsten Wertes; 0xffff=maxwert bei 16-Bit
for (i=0; i<=50; i++)
{
if (IR_Wert[i]<memo)
{
memo = IR_Wert[i];
memoposi = i; //Zum merken der Servoposition, bei der der kleinste wert liegt
}
}
return (memoposi);
}
/**********************************************************************************************/
/**************************************initialisierungen***************************************/
void Initial_ADC(void)
{
ADMUX |= 0x00; //AREF, resultat rechtsbündig, ADC-Eingang ADC0
ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)); //ADC eingeschaltet, Teilungsfaktor..
ADCSRA |= (1<<ADIE);
DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten));
}
void Initial_IR_Servo(void)
{
TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A
TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B
TCCR1B |= (1<<CS12); //Prescaler 256
TIMSK |= (1<<OCIE1B);
DDRD |= (1<<PWM_ServoPort);
PORTD |= (1<<PWM_ServoPort);
OCR1B=500; //beliebige zeit (irgendwas unter ner ms)
}
void Initial_Motoren(void)
{
//Ausgang Initialisieren (OC0)
DDRB |= (1<<Motor_Links); //Setzen als Ausgang
PORTB |= (1<<Motor_Links); //Pull-Up
//Ausgang Initialisieren (OC2)
DDRD |= (1<<Motor_Rechts); //Setzen als Ausgang
PORTD |= (1<<Motor_Rechts); //Pull-Up
//Initialisierung der Ausgänge für Rückwärtsfahren
DDRC |= ((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck));
//Initialisierung PWM für OC0
TCCR0 |= ((1<<WGM01)|(1<<WGM00)); //Fast PWM
TCCR0 |= (1<<COM01); //Clear Output on Compare, Set on Top
TCCR0 |= ((1<<CS02)|(1<<CS00)); //CLK/1024 (15,625kHz, 64µs/periode)
//Compare Register ist OCR0
//Initialisierung PWM für OC2
TCCR2 |= ((1<<WGM21)|(1<<WGM20)); //Fast PWM
TCCR2 |= (1<<COM21); //Clear Output on Compare, Set on Top
TCCR2 |= ((1<<CS22)|(1<<CS21)|(1<<CS20)); //CLK/1024 (15,625kHz, 64µs/periode)
//Compare Register ist OCR2
}
/**************************************************************************************/
/**************************************Hauptprogramm***********************************/
int main(void)
{
Initial_ADC();
Initial_IR_Servo();
Initial_Motoren();
sei(); //Globales Interrupt gesetzt
while(1)
{
ADCSRA |= (1<<ADSC); //ADC-Messung immer wieder gestartet werden, wenn möglich
if (count)
{
count=0;
IR_Servo = IR_Servoposition();
Motorsteuerung(GP2D12());
helligkeitsmessung();
}
}
return 0; //wird nie erreicht
}
/****************************************************************************************/
Hoffe da findet jemand was. Ich finde die sache mit dem Array eigentlich echt gut und will das am liebsten beibehalten.
Kann auch sein das ich mit den Zeiten wieder irgendwas falsch gemacht habe. Ich finde aber leider nichts.
MfG Jan
Lesezeichen