Hallo, ich durchforste schon seit einigen Tagen das Forum, ich lese jedoch nur wie man mit verschiedene Arten und Weisen PWM-Signale erzeugt. Nun meine Frage ist: Wie lese ich ein PWM-Signal am besten ein? -AD-Wandler ? oder -Frequenzmessung ? Ich nehme gerne jeden TIP an und/oder eventl. ASM-Codes würden mir auch sehr weiterhelfen. MfG Rufus
Frequenz- bzw. Periodendauermessung. Die Input Capture Funktion bzw. ein extern taktbarer Zähler im uC sind dabei sehr hilfreich. MFG Falk
Hallo Falk, danke vielmals für die rasche Antwort. ich werde mal im Datenblatt(ATtiny13) nachstöbern, ob es die Funktion gibt. MfG Rufus
Hallo an alle, nun sitze ich schon den ganzen Tag hiervor und komme nicht weiter. @Falk Es scheint so, als ob der ATtiny keine Input Capture Funktion hat. Eine "simple" Frequenzmessung d.H. Bei der positiven Flanke -> Timer Interrupt = Timer läuft bei der negativen Flanke -> Timer stop Der Wert von Timer ist die Periodendauer... Mit dem Programm von Franzis komme ich nicht weit, da verlaufe ich mich irgendwie. µC=ATtiny13 Takt 1,2MHz Hänge den Code mit an, dass Programm erzeugt ein Testsignal, den will ich aber nicht. Ich konnte es auch nicht entfernen. Ich verzweifele langsam, brauche hilfe, bitte.
@ Rufus (Gast) >Es scheint so, als ob der ATtiny keine Input Capture Funktion hat. Aber sicher, schau dir mal Timer 1 an, Input Capture Unit. >d.H. Bei der positiven Flanke -> Timer Interrupt = Timer läuft >bei der negativen Flanke -> Timer stop >Der Wert von Timer ist die Periodendauer... Ja, so macht man das. >Ich verzweifele langsam, brauche hilfe, bitte. Tja, was soll ich machen? Das Programm schreiben? MFG Falk
hallo ich habe hetzt einwenig experementiert, aber leider noch nicht zum Ziel gekommen. Ich möchte nicht die Peride messen sondern die Frequenz d.H. bei der positiven Flanke soll die Zeit 1sek laufen und nach einer 1sek den Zählerinhalt (wieviele positive Flanken) rausgeben. Klappt aber nicht. Hier ist der Code, kann mir einer weiterhelfen?
1 | .include "tn13def.inc" |
2 | |
3 | .def A = r16 |
4 | .def timer = r17 |
5 | .def timer2 = r18 |
6 | .def sek = r19 |
7 | .def sicher = r20 |
8 | .def Delay = r23 |
9 | .def Count = r24 |
10 | |
11 | ;Port B |
12 | .equ TXD = 1 ;TXD Senden PB1 |
13 | .equ RXD = 2 ;RXD Empfang PB2 |
14 | .equ Eingang = 3 ;Messeingang PB3 |
15 | |
16 | |
17 | rjmp Anfang ;Springe nach Anfang |
18 | .org 0x0003 |
19 | rjmp TIM0_OVF |
20 | |
21 | Anfang: |
22 | sbi ddrb,TXD ;SBI=Setze Bit In DDRB 1 |
23 | ldi A,7 ;LDI=Lade Register mit Wert 7 |
24 | out TCCR0B,A ;Start mit positiven Flanke |
25 | ldi A,2 ;LDI=Lade Register mit Wert 2 |
26 | out TIMSK0,A ;Timer Interrupt freigeben |
27 | clr timer ;r17 löschen |
28 | clr timer2 ;r18 löschen |
29 | clr sek ;r19 löschen |
30 | sei |
31 | |
32 | Schleife: |
33 | cpi sek,1 |
34 | rcall Lesen |
35 | in A,TCNT0 |
36 | rcall WrCOM |
37 | rjmp Schleife |
38 | |
39 | TIM0_OVF: ;Timer Interrupt |
40 | in sicher, SREG ;Statusregister in r20 kopieren |
41 | ldi timer, 6 ;LDI=Lade Register mit Wert 6 |
42 | out TCNT0,timer ;TCNT0 auf 6 setzen 256-6=250 bis Overflow |
43 | inc timer2 ;Registerinhaltinhalt um 1 erhöhen |
44 | cpi timer2,75 ;Vergleich Register mit Wert 75 |
45 | brlo TIM0_ende ;Sprung, wenn kleiner (Vorzeichenlos) |
46 | clr timer2 ;r18 löschen |
47 | nop |
48 | inc sek ;Registerinhaltinhalt um 1 erhöhen |
49 | TIM0_ende: |
50 | out SREG,sicher ;r20 in Statusregister kopieren |
51 | reti ;Zurück an die Stelle wo das Interrupt begann |
Bitte habt verständnis, bin noch ein Anfänger, deshalb kommentiere ich es auch so wie oben. MfG Rufus
Hi Initialisierung vom Stackpointer vergessen. MfG Spess
Hi Anfang: ldi r16,Low(RAMEND) out SPL,r16 MfG Spess
Hi, danke werde ich gleich mal testen. MfG Rufus
Schade hat immernoch nicht geklappt. Ergebnis ist immernoch 0 0 0 0 0 ... Am Eingang ist aber definitiv ein Signal (PWM), messe mit Multimeter 2,6V. MfG Rufus
Hallo, meine Frage, wie ich ein PWM-Signal messen muss, hat sich ja bereits geklärt. Frequenmessung!!! Ich habe hier ein ASM-Code der Firma Franzis was im Lernpaket dabei war.
1 | ;Frequenz.asm, Frequenzmessung an PB4 |
2 | |
3 | .include "tn13def.inc" |
4 | |
5 | .def A = r16 |
6 | .def timer = r17 |
7 | .def timer2 = r18 |
8 | .def sek = r19 |
9 | .def sicher = r20 |
10 | .def freqlow = r21 |
11 | .def freqhigh = r22 |
12 | .def Delay = r23 |
13 | .def Count = r24 |
14 | |
15 | ;Port B |
16 | .equ TXD = 1 |
17 | .equ RXD = 2 |
18 | |
19 | |
20 | rjmp Anfang |
21 | .org 0x0003 |
22 | rjmp TIM0_OVF ;Timer0 Overflow |
23 | Anfang: |
24 | sbi ddrb,TXD |
25 | sbi ddrb,3 |
26 | ldi A,3 ;Start mit Vorteiler / 64 |
27 | out TCCR0B,A |
28 | ldi A,2 |
29 | out TIMSK0,A ;Timer Interrupt freigeben |
30 | Schleife: |
31 | clr timer2 |
32 | clr sek |
33 | clr freqlow |
34 | clr freqhigh |
35 | sei ;Interrupt freigeben |
36 | Z1: sbic pinb,4 |
37 | rjmp Z2 |
38 | sbi portb,3 ;Testsignal |
39 | cpi sek,1 |
40 | brsh Z4 |
41 | rjmp Z1 |
42 | Z2: sbis pinb,4 |
43 | rjmp Z3 |
44 | cbi portb,3 ;Testsignal |
45 | cpi sek,1 |
46 | brsh Z4 |
47 | rjmp Z2 |
48 | Z3: inc freqlow |
49 | brne Z4 |
50 | inc freqhigh |
51 | Z4: cpi sek,1 |
52 | brlo Z1 |
53 | Z5: cli ;Interrupt sperren |
54 | mov A,freqhigh |
55 | rcall WrCOM |
56 | mov A,freqlow |
57 | rcall WrCOM |
58 | rjmp Schleife |
59 | |
60 | |
61 | TIM0_OVF: ;Timer Interrupt |
62 | in sicher, SREG |
63 | ldi timer, 6 |
64 | out TCNT0,timer ;250 bis Overflow |
65 | inc timer2 |
66 | cpi timer2,75 |
67 | brlo TIM0_ende |
68 | clr timer2 |
69 | inc sek |
70 | TIM0_ende: |
71 | out SREG,sicher |
72 | reti |
73 | |
74 | RdCOM: sbis pinb,RXD ;Empfangen |
75 | rjmp RdCOM |
76 | ldi Delay,58 |
77 | D1: dec Delay |
78 | brne D1 |
79 | ldi A,0 |
80 | ldi Count,8 |
81 | L1: lsr A |
82 | sbic pinb,RXD |
83 | ori A,128 |
84 | ldi Delay, 38 |
85 | D2: dec Delay |
86 | brne D2 |
87 | dec Count |
88 | brne L1 |
89 | ldi Delay, 38 |
90 | D3: dec Delay |
91 | brne D3 |
92 | com A |
93 | ret |
94 | |
95 | WrCOM: sbi portb,TXD ;Senden |
96 | ldi Delay,38 |
97 | D4: dec Delay |
98 | brne D4 |
99 | ldi Count,8 |
100 | L2: sbrc A,0 |
101 | rjmp OFF |
102 | rjmp ON |
103 | ON: sbi portb,TXD |
104 | rjmp BitD |
105 | OFF: cbi portb,TXD |
106 | rjmp BitD |
107 | BitD: ldi Delay,38 |
108 | D5: dec Delay |
109 | brne D5 |
110 | lsr A |
111 | dec Count |
112 | brne L2 |
113 | cbi PORTB,TXD |
114 | ldi Delay,38 |
115 | D6: dec Delay |
116 | brne D6 |
117 | ret |
Ich hänge nun mein PWM-Signal an PB4 und bekomme: 0 123 0 123 0 122 0 123 0 124 0 123 0 123.... in sekunden Takt werden nun jeweils zwei Bytes empfangen: 0 und 122 oder 123 oder 124. Die gemessene Anzahl der Impulse ist damit 0*256+123=123, d.h. die Frequenz beträgt 123Hz. Wenn ich das PWM-Signal mit einem Multimeter messe habe ich 2.6V Das Signal kommt übrigens aus einem ADXL202 (Beschleunigungssensor), wenn ich es kippe (links/rechts) messe ich +/-0.2V als 2.4-2.8V. Nur am Terminal bleibt der wert immer gleich: 0 123 0 123 0 122 0 123... Warum? Noch eine Frage: Der Timer wird vom Vorteiler mit 1,2MHz/64 getaktet. Er zählt 250 Takte bis zum Überlauf. Dazu wird das Timer-Register jedes Mal mit einem neuen Startwert von 6 geladen. Daraus ergibt sich eine Interruptfrequenz von 75Hz (1200000/64/250=75). Nach jeweils 75 Interrupts wird der Sekundenzähler erhöht. Warum entspricht 75Hz eine 1sekunde?
Hi Bevor du weitermachst solltest du erst mal deine serielle Verbindung testen. Interner RC-Oszillator + Software-UART scheint mir etwas gewagt. Hast du schon mal getestet, ob du wirklich die Zeichen empfängst, die an WRcom übergeben werden. Bevor das nicht sicher ist, brauchst di garnicht weitermachen. MfG Spess P.S. Der Tip mit dem Stackpointer war Quatsch. Ich war irgendwie auf ATTiny2313.
hallo Spess, zu deiner Frage, ja, es scheint zu funzen. Habe diverse Programme getestet mit schreiben und lesen. Es ist auf 9600Baud eingestellt. Erst bei 115200 Baud kommt es zu einzelnen Übertragungsfehlern. Bei einer Bitlänge von knapp 9 µs reicht also die zeitliche Auflösung des ASM-Programms nicht mehr aus. Hast du dennoch Antworten auf meine Fragen? MfG Rufus
@ Falk Brunner (falk)
>Aber sicher, schau dir mal Timer 1 an, Input Capture Unit.
Der ATtiny besitzt nur den Timer/Counter0 und kein Timer 1 und somit
auch kein Input Capture Unit.
Die Antwort kommt nur so spät, weil ich seit 1,5 Wochen mich
ausschließlich nur damit beschäftige und so allmählich werden einige
Sachen auch klar.
Aber trotzdem danke für deine Hilfe.
@all
Ich komme trotz des vieeeeeelen vielen lesens noch nicht mit der Messung
des PWM-Signals nicht ganz klar. Ich habe eine Erklärung, aber ob es
richtig ist weiß ich nicht. Und Zwar: Der Code s.oben macht eine
Frequenzmessung und gibt mir die Frequenz via SW-UART auf den Terminal
wieder. Wie ich bereits geschrieben hatte, messe ich mit einem
Multimeter Spannungen zwischen 2.4-2,8V je nach Schräglage des ADXL
(PWM-OUT). Selbstverständlich bleibt die Periodendauer die Selbe, weil
es ja keine Impulsmessung ist, sondern eine Frequenz bzw. Periodendauer
Messung ist.
Sprich , wenn T1(Impuls) + T2(Pause) = Periodendauer ist, muss ich
wissen wie sich T1 zu T2 verändert um Werte zu erfassen mit denen ich
weiter arbeiten kann. RICHTIG?
Wäre echt sehr Nett , wenn mir das jemand bestätigen oder verneinen
(falls nicht richtig) könnte.
MfG Rufus
>Der ATtiny besitzt nur den Timer/Counter0 und kein Timer 1 und somit >auch kein Input Capture Unit. sry, meine natürlich den ATtiny13
Die Frequenzmessung bringt wirklich nicht viel. Man muß die Zeiten für high und low level einzeln messen. Im pronzip sollte das aber sehr ähnlicher der Frequenzmessung gehen.
Hi, danke Ulrich, zu dieser Erkenntnis bin nun auch gekommen. Hab den ADXL202 jetzt mal mit einen Oszi ausgelesen, siehe Anhang. In einigen Treads über PWM und Beschleunigungssensoren hatte ich gelesen, dass sich T1 verändert und T2 würde gleich bleiben, demnach müsste sich bei jeder Abtastung die F ändern. Natürlich ist das aber nicht richtig, weil T2 verhält sich propotional zu T1, d.H. F bleibt immer gleich. Ich habe nun wirklich (ohne Hilfestellung) meinen allerersten 100% aus eignem Gedankengang entstandenen ASM-Prog geklimmpert :) Viele Spezis werden es wahrscheinlich mit Ironie nehmen, aber ich bin dennoch glücklich, weil ich allmählich die Syntax begriffen habe :) So nun zum ASM-Code: Es wird bestimmt auch eleganter und einfacher gehen, aber mit dem Simulator sieht es schon ganz gut aus. Bei einer +Pulsbreite von ~4ms muss ich natürlich noch ein TIMER_OVF mit Einfügen und später etwas umrechnen. Vielleicht kann mir jemand einpaar Tips geben wie ich den ASM-Code verfeinern kann. Danke
1 | ;Pulsbreitenmessung (vereinfacht) |
2 | |
3 | .include "tn13def.inc" |
4 | |
5 | .def A = r16 |
6 | .def timer = r17 |
7 | |
8 | Beginn: |
9 | ldi A,0 ;TCNT0 leeren |
10 | out TCNT0,A |
11 | loopa: |
12 | sbis pinb,4 ;PB4 abfragen |
13 | rjmp loopa ;wiederholen |
14 | rjmp Tgo ;weiter, wenn Signal da ist |
15 | Tgo: |
16 | ldi A,1 ;Timer aktiveren ohne Vorteiler |
17 | out TCCR0B,A |
18 | loopb: |
19 | sbis pinb,4 ;PB4 abfragen |
20 | rjmp Tstop ;Sprung, wenn kein Signal |
21 | rjmp loopb ;Abfrage wiederholen |
22 | Tstop: |
23 | ldi A,0 ;Timer stoppen |
24 | out TCCR0B,A |
25 | clr timer |
26 | in timer,TCNT0 ;Timerwert auslesen zur |
27 | ;Weiterverarbeitung |
28 | rjmp Beginn |
Für jeder Art Tips bin ich sehr dankbar. MfG Rufus
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.