Forum: Mikrocontroller und Digitale Elektronik Funktion in C


von Paul (Gast)


Lesenswert?

Hallo Forum-User,

ich habe ein kleines Verständnisproblem und denke, dass es eigentlich 
nur eine Kleinigkeit ist.

Ich habe vor kurzen angefangen einen Attiny45 mit Atmel Studio zu 
programmieren in C.

Nun habe ich mit kleinen Schritten angefangen und erfolgreich ein PWM 
Ausgang angesteuert.
Nun wollte ich der übersichtshalber eine Funktion schreiben die das 
Register des jeweiligen PWM-Pin beschreibt, aber leider scheiterte ich 
an der Aufgabe.

Kann mir jemand anhand meines Codes helfen die Wissenslücke zu füllen?
Ich habe nicht ganz verstanden, wie ich der Funktion etwas übergebe, 
damit sie auf das richtige Register des Output Compare Register 
schreibt.

Vielen dank im voraus.


Mein Code:
1
# define F_CPU 1000000UL
2
# define pwm1 OCR0A
3
# define pwm2 OCR0B
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
9
10
int main(void)
11
{  
12
  DDRB |= (1<<PB1) | (1<<PB0);
13
  
14
    TCCR0A |= (1<<COM0A1) | (1<<COM0B1) | (1<<WGM00) | (1<<WGM02);
15
  TCCR0B |= (1<<CS01);
16
  
17
  void SetPWM(pinout, int value)
18
  {
19
    pinout= value;
20
  }
21
  
22
  
23
  
24
  
25
    while (1) 
26
    {
27
    for(int i=0; i<255; i++)
28
    {
29
      SetPWM(pwm1, i);
30
      _delay_ms(4);
31
    }
32
    
33
  _delay_ms(500);
34
  
35
    for(int i=255; i>0;i--)
36
    {
37
      SetPWM(pwm1, i);
38
      _delay_ms(4);
39
    }
40
    
41
    }
42
  
43
  
44
}

von Falk B. (falk)


Lesenswert?

Paul schrieb:

> Kann mir jemand anhand meines Codes helfen die Wissenslücke zu füllen?
> Ich habe nicht ganz verstanden, wie ich der Funktion etwas übergebe,
> damit sie auf das richtige Register des Output Compare Register
> schreibt.

Dein Funktion muss AUßERHALB eiener anderen Funktion definiert werden! 
Das ist immer so! Man kann sie nur innerhalb von anderen Funktionen 
aufrufen.
C-Buch besorgen und KOMPLETT durcharbeiten!
Man kann zwar auch das Ziel für die PWM (das Register) als Parameter 
übergeben, aber das wird für deinen aktuellen Wissenstand zuviel. 
Stichwort Pointer.
1
# define F_CPU 1000000UL
2
# define pwm1 OCR0A
3
# define pwm2 OCR0B
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
void SetPWM(int value) {
9
    OCR0A = value;
10
}
11
12
int main(void) {  
13
    DDRB |= (1<<PB1) | (1<<PB0);
14
    TCCR0A |= (1<<COM0A1) | (1<<COM0B1) | (1<<WGM00) | (1<<WGM02);
15
    TCCR0B |= (1<<CS01);
16
17
    while (1) {
18
      for(int i=0; i<255; i++) {
19
          SetPWM(i);
20
          _delay_ms(4);
21
      }
22
    
23
      _delay_ms(500);
24
  
25
      for(int i=255; i>0; i--) {
26
          SetPWM(i);
27
          _delay_ms(4);
28
      }
29
    } 
30
}

von Paul (Gast)


Lesenswert?

Vielen Dank für die Info.
An einen Pointer habe ich auch schon gedacht.

Könntest du mir an meinen Beispiel die Funktionen mit einen Pointer 
abändern, damit ich weiß wohin die Reise mal geht?

Das Buch für C steht schon bei mir auf der Agenda.

von Teo D. (teoderix)


Lesenswert?

Paul schrieb:
> Könntest du mir an meinen Beispiel die Funktionen mit einen Pointer
> abändern, damit ich weiß wohin die Reise mal geht?

Das Thema ist dafür viel zu umfangreich!
Da hilft nur lesen lesen.....

Pointer:
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/012_c_zeiger_001.htm
Wertübergabe an Funktionen (call-by-value):
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/009_c_funktionen_014.htm
Call by reference:
https://www.tutorialspoint.com/cprogramming/c_function_call_by_reference.htm

von Falk B. (falk)


Lesenswert?

1
void SetPWM(volatile uint8_t *reg, int value) {
2
    *reg = value;
3
}

SetPWM(&OCR0A, 42);

Das Beispiel ist zwar praktisch Unsinn, denn es ersetzt ein einfaches

OCR0A = 42;

aber es zeigt das Prinzip.

von Buchfinder (Gast)


Lesenswert?

Überschrift gelesen. Thread geöffnet. Nach "C-Buch" gesucht. Fündig 
geworden. :)

von Einer K. (Gast)


Lesenswert?

Teo D. schrieb:
> Pointer:
> http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/012_c_zeiger_001.htm

Gerade in Sachen Pointer ist der Rheinwerk Buch mehr als bedenklich!
Ich rate davon ab.

von Paul (Gast)


Lesenswert?

Super, vielen Dank für die Interesse.

Und wenn ich das so sehe ist es recht unnötig es in dieser Form zu 
gestalten.

Der Gedanke ging dahin, wenn ich größere Projekte programmieren will, 
möchte ich natürlich den Code "sauber" gestalten.

#define led1_pwm OCR0A   <--- wäre wohl leichter&besser?

Ich habe vorher mit Arduino programmiert und da wurde einen viel 
abgenommen und man konnte mit einfachen Befehlen viel bewirken, aber nun 
interessiert mich immer mehr das Background und entschied mich auf Atmel 
Studio in C.

Habe jahrelang erfahren in Programmieren, aber mit SPS.


Danke an alle nochmals.

von Dirk B. (dirkb2)


Lesenswert?

Paul schrieb:
> Habe jahrelang erfahren in Programmieren, aber mit SPS.

Schließe aber nicht von dem Verhalten der SPS auf das Verhalten von C.

von Walter T. (nicolas)


Lesenswert?

Falk B. schrieb:
> Das ist immer so!

Gilt nur für C. Bei anderen Sprachen sind nested functions/embedded 
functions gang und gäbe.

Tipp an den TO: Versuch erst einmal, eine einfache 
C-Entwicklungsumgebung mit Konsolenausgabe am PC ans Laufen zu bekommen. 
Dann kannst Du solche Sachen aus (egal welchem) Lehrbuch direkt in der 
Konsole ausprobieren und musst nicht warten, bis es auf den µC geflasht 
ist. Außerdem kannst Du Dir Zwischenergebnisse anzeigen lassen.

von Bernd K. (prof7bit)


Lesenswert?

Falk B. schrieb:
> Dein Funktion muss AUßERHALB eiener anderen Funktion definiert werden!

Kleine Vervollständigung am Rande:

Wenn man auf ANSI-C verzichtet und sich auf GNU-C festlegt dann sind 
lokale Funktionen erlaubt. Ganz nützlich für kleine Hilfsfunktionen die 
nur auf lokalen Variablen arbeiten und die man an sonst keiner anderen 
Stelle braucht. In Pascal wird das gerne gemacht, wer also aus dieser 
Ecke kommt wird öfter mal in Versuchung kommen das nutzen zu wollen. Es 
stellt eigentlich auch die Symmetrie wieder ein bisschen her: ich kann 
globale, modullokale und funktionslokale Variablen haben, warum also 
nicht die gleiche Abstufung auch für Funktionen?

von Nils P. (torus)


Lesenswert?

Bernd K. schrieb:
> Wenn man auf ANSI-C verzichtet und sich auf GNU-C festlegt dann sind
> lokale Funktionen erlaubt. Ganz nützlich für kleine Hilfsfunktionen die
> nur auf lokalen Variablen arbeiten und die man an sonst keiner anderen
> Stelle braucht. In Pascal wird das gerne gemacht, wer also aus dieser
> Ecke kommt wird öfter mal in Versuchung kommen das nutzen zu wollen. Es
> stellt eigentlich auch die Symmetrie wieder ein bisschen her: ich kann
> globale, modullokale und funktionslokale Variablen haben, warum also
> nicht die gleiche Abstufung auch für Funktionen?

Guter Hinweis, mache ich auch ganz gerne. Aber eine kleine Warnung aus 
der Praxis: Wenn man die GNU Extension für lokale Funktionen benutzt hat 
man keine Chance mehr seinen C Code auch mal eben in C++ zu kompilieren.

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.