Hallo liebe Forumsmitglieder,
ich bin Neuling in Sachen Mikrocontroller, muss mich aber innerhalb
kurzer Zeit in das Thema einarbeiten, da ich für ein zeitkritisches
Projekt an der Uni eine einfache Motorsteuerung entwickeln muss. Ich bin
kein Elektrotechniker... trotzdem muss das irgendwie gehen. Ich nutze
dabei ein Programm namens Wormhole, mit dem ich Simulink-Code direkt aus
Matlab heraus auf den AT90CAN128 übertragen kann. Zusätzlich kann
separat geschriebener C-Code eingebunden werden. A/D-Wandler, PWM Signal
ausgeben, Digitale I/Os hab ich soweit unter Kontrolle. Für die
Drehzahlbestimmung (Hall-Sensor) muss ich allerdings die Frequenz
messen, was ich noch nicht kann. Der Hall-Sensor (bzw. der
Frequenzgenerator) liegt am ICP1 an. Mit einer sehr einfachen
Interruptroutine kann ich bei fallender Flanke einen Pin setzen, den ich
später wieder zurücksetze:
1 | #ifndef ____testinterrupt
|
2 | #define ____testinterrupt
|
3 |
|
4 |
|
5 | #include <avr/io.h>
|
6 | #include <avr/interrupt.h>
|
7 | #include <string.h>
|
8 | #include <util/delay.h>
|
9 | #include <math.h>
|
10 | #include <inttypes.h>
|
11 | #include <stdbool.h>
|
12 |
|
13 |
|
14 | #define setbit(ADR,BIT) (ADR |= (1<<BIT))
|
15 | #define clearbit(ADR,BIT) (ADR &=~(1<<BIT))
|
16 | #define getbit(ADR, BIT) (ADR & (1<<BIT))
|
17 |
|
18 |
|
19 |
|
20 | ISR( TIMER1_CAPT_vect )
|
21 | {
|
22 |
|
23 | setbit(PORTF,0); //PORTF.0 auf 1 setzen
|
24 |
|
25 | }
|
26 |
|
27 |
|
28 |
|
29 | uint8_T get_freq() //Diese Funktion wird aus dem Simulink Modell heraus aufgerufen
|
30 | {
|
31 |
|
32 |
|
33 | clearbit(PORTF,0); //PORTF.0 auf 0 setzen
|
34 |
|
35 | return 1;
|
36 |
|
37 |
|
38 | }
|
39 |
|
40 |
|
41 | #endif
|
Von daher gehe ich davon aus, dass ich die Register richtig gesetzt habe
(geschieht in Simulink) und auf dem richtigen Weg bin. Die
Frequenzmessung mit einem auf den AT90CAN128 angepassten Code von dieser
Seite wollte ich die Frequenz messen, es klappt allerdings nicht:
1 | volatile unsigned int StartTime = 0; // ICR-Wert bei 1.High-Flanke speichern
|
2 | volatile unsigned int EndTime = 0; // ICR-Wert bei 2.High-Flanke speichern
|
3 | volatile unsigned char vollstMess = 0; // Messung vollständig?
|
4 |
|
5 |
|
6 | ISR( TIMER1_CAPT_vect )
|
7 | {
|
8 | static unsigned char ErsteFlanke = 1;
|
9 |
|
10 | if(vollstMess)
|
11 | return;
|
12 |
|
13 |
|
14 | setbit(PORTF,0);
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | if( ErsteFlanke )
|
20 | {
|
21 | StartTime = ICR1;
|
22 | NrOverflows = 0;
|
23 | ErsteFlanke = 0; // Die naechste Flanke ist das Ende der Messung
|
24 | }
|
25 |
|
26 | else
|
27 | {
|
28 | EndTime = ICR1;
|
29 | ErsteFlanke = 1;
|
30 | vollstMess = 1;
|
31 | // Bei der naechsten Flanke beginnt der naechste Messzyklus
|
32 | }
|
33 |
|
34 | }
|
35 |
|
36 | ISR( TIMER1_OVF_vect )
|
37 | {
|
38 | NrOverflows++;
|
39 | }
|
40 |
|
41 |
|
42 | int get_freq() //wird von SImulink aus aufgerufen
|
43 | {
|
44 | int Erg=0;
|
45 |
|
46 | clearbit(PORTF,0);
|
47 |
|
48 |
|
49 | if( vollstMess )
|
50 | {
|
51 |
|
52 | Erg = (NrOverflows * 65536) + EndTime - StartTime;
|
53 |
|
54 |
|
55 | Erg = F_CPU / Erg; // f = 1 / t
|
56 |
|
57 | vollstMess=0;
|
58 |
|
59 | }
|
60 | return Erg;
|
61 |
|
62 |
|
63 | }
|
64 |
|
65 |
|
66 | #endif
|
Könnt ihr mir weiterhelfen? Leider konnten mir die anderen Threads nicht
helfen und wie gesagt bin ich Neuling und habe wenig Zeit (schlechte
Kombination).
Vielen Dank,
Jakob