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
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
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
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