Hallo
ich will grade mit einem STM32 Timer 2 Impulse zählen.
Und zwar habe ich ein Impulspaket, wo während ca. 2 Sekunden ein Takt
von 4.5MHz anliegt, danach kommt eine Pause von einigen Sekunden, danach
kommen wieder für 2 Sekunden die 4.5MHz und so weiter. Ich will die
Anzahl der Zyklen während des 2 Sekunden-Fensters zählen.
Glucklicherweise habe ich ein externes Signal, welches ankündigt, wann
das Zeitfenster beginnt, und wann es endet.
Daher dachte ich ich kann folgendes machen:
- den Timer 2 (hat 32 Bit) konfigurieren als Counter, welcher vom
externen Taktsignal getaktet wird.
- das Hilfssignal wird mit einem GPIO abgefragt.
- Der Counter zählt die Impulse. Wenn das Hilfssignal logisch 0 wird,
ist das Zeitfenster vorüber und es kommen keine Impulse mehr und ich
kann den Zählerstand auswerten.
- Danach wird der Zähler zurückgesetzt und man wartet, bis das
Hilfssignal wieder 0 wird.
Grundsätzlich funktioniert es, wie es soll, ABER mein Timer 2 zählt
immer doppelt so viele Impulse wie er soll! :-)
Ich habe es mit einem HP 5315B Universalzähler verifiziert. Der HP zählt
gut 9000000 Takte. Das wäre O.K. Der STM32 zählt aber 18000000 Takte!
und ich kann mir nicht erklären wieso. Edge Detector habe ich geprüft,
der ist auf 'rising' konfiguriert, müsste also passen.
Anmerken muss man, dass mein externes Signal ca. 5 V Amplitude hat,
weshalb ich einen 1kOhm Seriewiderstand verbaut habe, um den STM32 nicht
zu grillieren.
Momentan benutze ich das Discovery Board. Als Takt für den STM wird der
8MHz Quarz verwendet, die PLL ist auf 160 MHz konfiguriert.
Hier mein Code:
1 | RCC->AHB1ENR |= (1u << 0); // enable gpio a
|
2 | GPIOA->MODER |= (2u << 0); // pa0 = alternate function
|
3 | GPIOA->AFR[0] |= (1u << 0); // pa0 = tim2_ch1 input
|
4 |
|
5 | RCC->APB1ENR |= (1u << 0); // enable timer2
|
6 |
|
7 | // reset timer
|
8 | TIM2->CR1 = 0;
|
9 | TIM2->CR2 = 0;
|
10 |
|
11 | TIM2->SMCR = (4u << 4) | (7u << 0); // select edge detector as trigger, count on TI1F_ED
|
12 | TIM2->CCER = 0; // disable all channels (otherwise ccmr is not writable)
|
13 | TIM2->CCMR1 = (2u << 0); // select TI1 input for channel 1
|
14 | TIM2->CR1 = 1; // counter enable
|
15 |
|
16 | while(1)
|
17 | {
|
18 | uint32_t a;
|
19 |
|
20 | // led off, wait until trigger signal goes low
|
21 | GPIOD->BSRRH = 1<<12;
|
22 | do
|
23 | {
|
24 | a = GPIOD->IDR;
|
25 | } while(a & (1u << 11));
|
26 |
|
27 | // led on
|
28 | GPIOD->BSRRL = 1<<12;
|
29 |
|
30 | // read & reset counter
|
31 | static uint32_t cnt = 0;
|
32 | cnt = TIM2->CNT;
|
33 | TIM2->CR1 &= ~1;
|
34 | TIM2->CNT = 0;
|
35 | TIM2->CR1 |= 1;
|
36 |
|
37 | // wait until trigger signal goes high
|
38 | do
|
39 | {
|
40 | a = GPIOD->IDR;
|
41 | } while(!(a & (1u << 11)));
|
42 | }
|
Das Triggersignal liegt am PD11 und das Signal, dessen Zyklen zu zählen
sind liegt an PA0. Ich sehe grade den Fehler nicht. Ist Jahre her seit
ich zum letzten mal mit einem STM was gemacht habe :-(
Wer sieht das Problem?