-
komischerweise hatten die defines mit channel 1 also pin0 wunderbar alleine funktioniert.
Naja mein neuer Code is jetzt:
Code:
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/signal.h>
#include <string.h>
#include <compat/deprecated.h>
#include <inttypes.h>
#include <myheader.h>
#define SYSCLK 16000000
void init(void);
// Initialisierung
void init(void)
{
DDRD= (1<<PD4) | (1<<PD5); // PWM Pins als ausgang
DDRC= (1<<PC6) | (1<<PC7); // 6=Motor 1 Kanal 1 7= Motor 1 Kanal 2
DDRB= (1<<PB0) | (1<<PB1); // 0=Motor 2 Kanal 1 1= Motor 2 Kanal 2
TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10);
// 10 Bit Pwm, invertierend
TCCR1B = (1<<CS11) | (1<<CS10); // Prescaler 64
OCR1A=1; // Mindestzeit für PWM1
OCR1B=1; // Mindestzeit für PWM2
}
void warte(unsigned int ms) // Wartet um x ms
{
unsigned int zaehler;
while (ms)
{
zaehler = SYSCLK / 20000;
while (zaehler)
{
asm volatile ("nop");
zaehler--;
}
ms--;
}
}
void R_Motor_r() // Rechter Motor rückwärts
{
sbi(PORTC,6);
cbi(PORTC,7);
}
void R_Motor_v() // Rechter Motor vorwärts
{
sbi(PORTC,7);
cbi(PORTC,6);
}
void R_Motor_s() // Rechter Motor stop
{
cbi(PORTC,7);
cbi(PORTC,6);
}
void L_Motor_r() // Linker Motor rückwärts
{
sbi(PORTB,0);
cbi(PORTB,1);
}
void L_Motor_v() // Linker Motor vorwärts
{
sbi(PORTB,1);
cbi(PORTB,0);
}
void L_Motor_s() // Linker Motor stop
{
cbi(PORTB,1);
cbi(PORTB,0);
}
uint16_t readADC(uint8_t channel) //Funktion um ADC-Wert auszulesen an Pin channel
{
uint8_t i;
uint16_t result = 0;
// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
// Kanal des Multiplexers waehlen
ADMUX = channel;
// Interne Referenzspannung verwenden (also 2,56 V)
ADMUX |= (1<<REFS1) | (1<<REFS0);
// Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
// Jetzt 3x die analoge Spannung and Kanal channel auslesen
// und dann Durchschnittswert ausrechnen.
for(i=0; i<3; i++) {
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));
result += ADCW;
}
// ADC wieder deaktivieren
ADCSRA &= ~(1<<ADEN);
result /= 3;
return result;
}
int main(void) // Main-Funktion, d.h. dass was der Roboter macht!
{
init();
warte(2000);
unsigned int r; // ADC-Wert für rechten Sensor
unsigned int l; // ADC-Wert für linken Sensor
for(;;)
{
r = readADC(0); //Auslesen der analogen Spannungen an Pin 0
l = readADC(1); //Auslesen der analogen Spannungen an Pin 1
if (r>0 && r<32) // wenn schwarzer Untergrund
R_Motor_v();
if (r>=32) // wenn weißer Untergrund
R_Motor_r();
if (l>0 && l<32) // wenn schwarzer Untergrund
L_Motor_v();
if (l>=32) // wenn weißer Untergrund
L_Motor_r();
warte(10);
}
return 0;
}
-
Bei 16MHz solltest Du den Prescaler auf 128 stellen, also am Ende der Zeile noch ein | (1 <<ADPS0) dazu, sonst läuft der ADC zu schnell, er sollte unter 200kHz kommen.
so schauts dann aus:
Code:
// Den ADC aktivieren und Teilungsfaktor auf 128 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1 <<ADPS0);
-
Er hat mit Channel 1 begonnen auf Channel 2 geschaltet und konnte dann nicht mehr zurück.
Dein Prog hat nur den Schönheitsfehler das du, wenn noch weiterer Code dazukommt, aufgrund der Warteschleifen timingprobleme bekommen wirst. Versuche mit Interrupts zu arbeiten und Timer, auch wenn es so jetzt klaglos funktioniert.