Forum: Mikrocontroller und Digitale Elektronik Fehler im code?


von Mark (Gast)


Lesenswert?

Hallo,
ich habe ein Programm geschrieben, welches einen Servo und eine LED 
ansteuern soll
1
#define F_CPU 1000000UL
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include <stdint.h>
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
void init_timer(){
9
  // Set Fast PWM mode.
10
  TCCR0A |= (1<<WGM00) | (1<<WGM01);
11
  // Clear 0C0A on compare.
12
  TCCR0A |= (1<<COM0A1);
13
  // Start timer, no prescaling.
14
  TCCR0B |= (1<<CS00) | (1<<CS01);
15
  // Duty cycle 0% 
16
  OCR0A = 0;
17
}
18
19
void init_servo(){
20
  PORTB |= (1<<PB0);  //PB0 als Ausgang definieren 
21
  PORTB &= ~(1<<PB0);  // PB0 auf low setzen   
22
  PORTB |= (1<<PB1);  //PB1 als Ausgang definieren 
23
  PORTB &= ~(1<<PB1);  // PB1 auf low setzen  
24
  DDRB &= ~(1<<PB4);  // PB4 als Eingang definieren
25
  PORTB |= (1<<PB4);  // Interner Pull-Up einschalten
26
}
27
28
29
30
31
int main(){
32
  int i=5;
33
  int val=0;
34
  init_servo();
35
  init_timer();
36
  while(1){
37
    val = PINB&(1<<PINB4);  // Abfrage ob Pin4 high ist
38
  if(val){
39
    PORTB = 0b00010;  // mache LED an Pin1 an
40
    while(val){
41
      i++;      // PWM um eins erhöhen
42
    OCR0A = i;    // setze PWM
43
    _delay_ms(15);
44
    val = PINB&(1<<PINB4);
45
    }
46
  }
47
  else{
48
    PORTB = 0b00000;  // mache LED an Pin1 ausa
49
    while(i>=5){
50
      i--;      // PWM um eins veringern
51
    OCR0A = i;    // setze PWM
52
    _delay_ms(15);
53
    }          
54
  }
55
  }
56
  return 0;
57
}

das ganze soll mit einem Attiny45 gemacht werden. beim kompilieren sagt 
er mir, dass es keinen Fehler gibt, also habe ich das ganze aus der 
Eingabeaufforderung auf meinem kontroller hochgeladen

avrdude -c STK500v2 -p t45 -P COM5 -B 9 -U flash:w:servo.hex

es ist so, dass die LED sofort schwach leuchtet.
Wenn ich den Eingangspin auf High setze, wird die LED zwar ein bischen 
heller (aber auch nciht so hell wie sie sein sollte), aber sonst 
passiert nichts.
Der Servo rührt sich gar nciht.
ich habe den Eingangspin noch mit einem 10k Widerstand mit ground 
verbunden. also dürfte der Pin eigenglich auf Low stehen.

Habe ich da Fehler in meinem Programm (Davon gehe ich eigentlich schon 
aus)?
und kann ich irgendwie direkt über AVR-Studio das Programm auf meinem 
Kontroller Programmieren?

Mark

von Edi R. (edi_r)


Lesenswert?

Mark schrieb:
> PORTB |= (1<<PB0);  //PB0 als Ausgang definieren
>   PORTB &= ~(1<<PB0);  // PB0 auf low setzen
>   PORTB |= (1<<PB1);  //PB1 als Ausgang definieren
>   PORTB &= ~(1<<PB1);  // PB1 auf low setzen

Da ist wohl was schief gelaufen. Zum Konfigurieren als Eingang oder 
Ausgang braucht man DDRB, nicht PORTB.

von jibi (Gast)


Lesenswert?

Probier mal den:
1
#define F_CPU 1000000UL
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include <stdint.h>
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
void init_timer(){
9
  // Set Fast PWM mode.
10
  TCCR0A |= (1<<WGM00) | (1<<WGM01);
11
  // Clear 0C0A on compare.
12
  TCCR0A |= (1<<COM0A1);
13
  // Start timer, no prescaling.
14
  TCCR0B |= (1<<CS00) | (1<<CS01);
15
  // Duty cycle 0% 
16
  OCR0A = 0;
17
}
18
19
void init_servo(){
20
  DDRB |= (1<<PB0);  //PB0 als Ausgang definieren 
21
  PORTB &= ~(1<<PB0);  // PB0 auf low setzen   
22
  DDRB |= (1<<PB1);  //PB1 als Ausgang definieren 
23
  PORTB &= ~(1<<PB1);  // PB1 auf low setzen  
24
  DDRB &= ~(1<<PB4);  // PB4 als Eingang definieren
25
  PORTB |= (1<<PB4);  // Interner Pull-Up einschalten
26
}
27
28
29
30
31
int main(){
32
  int i=5;
33
  int val=0;
34
  init_servo();
35
  init_timer();
36
  while(1){
37
    val = PINB&(1<<PINB4);  // Abfrage ob Pin4 high ist
38
  if(val){
39
    PORTB = 0b00010;  // mache LED an Pin1 an
40
    while(val){
41
      i++;      // PWM um eins erhöhen
42
    OCR0A = i;    // setze PWM
43
    _delay_ms(15);
44
    val = PINB&(1<<PINB4);
45
    }
46
  }
47
  else{
48
    PORTB = 0b00000;  // mache LED an Pin1 ausa
49
    while(i>=5){
50
      i--;      // PWM um eins veringern
51
    OCR0A = i;    // setze PWM
52
    _delay_ms(15);
53
    }          
54
  }
55
  }
56
  return 0;
57
}

von Edi R. (edi_r)


Lesenswert?

jibi schrieb:
> PORTB = 0b00010;  // mache LED an Pin1 an

und

jibi schrieb:
>     PORTB = 0b00000;  // mache LED an Pin1 ausa

würde ich auch anders schreiben:
1
PORTB |= (1<<PB1);  // mache LED an Pin1 an
und
1
PORTB &= ~(1<<PB1);  // mache LED an Pin1 aus

sonst setzt Du alle anderen Portpins auf 0 bzw schaltest bei den 
Eingängen die Pull-Ups ab.

: Bearbeitet durch User
von Mark (Gast)


Lesenswert?

Ah, so sieht das schon viel besser aus.
Leider habe ich das alles bisher nur auf einem Steckbrett aufgebaut und 
anstelle eines Schalters habe ich immer kabel umgesteckt.
Ich denke, dadurch kam es beim Servo zu einigen Problemen(mal hat er 
sich bewegt mal nicht) als nichts eingesteckt war.
Dies denke ich, ist aber verschwunden, wenn der Schalter drinn ist.

Eine andere Frage habe ich noch allgemein zum Servo.
ich lasse die PWM ja immer um eins erhöhen. Was ist, wenn diese zu hoch 
wird? Wie verhält sich der servo dann? Durch ausprobieren ist er dann 
immer wieder ein stück hin und her gefahren, ist das richtig?

Aber sonst schon einmal ein dankeschön an die aufgefallenen Fehler

Mark

von jibi (Gast)


Lesenswert?

>ine andere Frage habe ich noch allgemein zum Servo.
>ich lasse die PWM ja immer um eins erhöhen. Was ist, wenn diese zu hoch
>wird? Wie verhält sich der servo dann? Durch ausprobieren ist er dann
>immer wieder ein stück hin und her gefahren, ist das richtig?

Wie meinen?

Gruß Jonas

von Mak (Gast)


Lesenswert?

Nun ja, sobald der Eingang eingeschaltet ist, zählt die PWM ja immer 
höher. Dadurch fährt der Servo immer weiter, so lange biss der Eingang 
wieder auf Low ist. Was passiert aber, wenn der Eingang auf High bleibt?

von knotter (Gast)


Lesenswert?

er fährt bis zum ende und bleibt da stehen?!

von Mark (Gast)


Lesenswert?

mhh, dann ist da wohl ncoh ein Fehler drinn. Bei mir bleibt er wohl 
zunächst stehen, aber nach einer kurzen Zeit fährt der imme ein stück 
zurück und hin und her. Dann muss ich nochmal ein bisschen gucken.

Wie bekomme ich den den Wert heraus auf welchen Winkel sich der Servo 
einstellt?
ist 1=1°, 90=90° usw?
dann könnte ich ja einfach hinschreiben
1
 if(i>=180) i=180;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.