Counts signal transitions on p30(CAP2.0) or p29(CAP2.1) for LPC1768 target. Can detecte rising, falling or both signal edge. Return the signal edge count during a period in seconds. In theory (Shannon's theorem) input signal frequency can up to 48 MHz with 96 MHz CCLK. But only tested with frequencys up to 20 MHz and it work.
lib_ClockCounter.cpp@5:b5e68cd91f09, 2020-12-02 (annotated)
- Committer:
- YSI
- Date:
- Wed Dec 02 15:48:45 2020 +0000
- Revision:
- 5:b5e68cd91f09
- Parent:
- 4:b873a2fda102
add split start and stop count
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| YSI | 0:d3c997729db1 | 1 | /** Mbed Library Clock Counter |
| YSI | 0:d3c997729db1 | 2 | * Hardware pulse counter with TIMER2 (CAP2.0 or CAP2.1) on Mbed LPC1768 |
| YSI | 0:d3c997729db1 | 3 | * |
| YSI | 1:bdbac277828a | 4 | * Counts signal transitions on p30(CAP2.0) or p29(CAP2.1) for LPC1768 target. |
| YSI | 0:d3c997729db1 | 5 | * Can detecte rising, falling or both signal edge. |
| YSI | 1:bdbac277828a | 6 | * Return the signal edge count during a period in seconds. |
| YSI | 1:bdbac277828a | 7 | * In theory (Shannon's theorem) input signal frequency can up to 48 MHz with 96 MHz CCLK. |
| YSI | 1:bdbac277828a | 8 | * But only tested with frequencys up to 20 MHz and it work. |
| YSI | 0:d3c997729db1 | 9 | * |
| YSI | 0:d3c997729db1 | 10 | * Example : |
| YSI | 0:d3c997729db1 | 11 | * @code |
| YSI | 0:d3c997729db1 | 12 | * #include "mbed.h" |
| YSI | 0:d3c997729db1 | 13 | * #include "lib_ClockCounter.h" |
| YSI | 0:d3c997729db1 | 14 | * |
| YSI | 0:d3c997729db1 | 15 | * Serial pc(USBTX, USBRX); |
| YSI | 0:d3c997729db1 | 16 | * ClockCounter Frequency; |
| YSI | 0:d3c997729db1 | 17 | * |
| YSI | 0:d3c997729db1 | 18 | * int main() |
| YSI | 0:d3c997729db1 | 19 | * { |
| YSI | 0:d3c997729db1 | 20 | * while(1) pc.printf("Frequency = %d Hz\r\n", Frequency.getCount()); |
| YSI | 0:d3c997729db1 | 21 | * } |
| YSI | 0:d3c997729db1 | 22 | * @endcode |
| YSI | 0:d3c997729db1 | 23 | */ |
| YSI | 0:d3c997729db1 | 24 | |
| YSI | 0:d3c997729db1 | 25 | #include "lib_ClockCounter.h" |
| YSI | 5:b5e68cd91f09 | 26 | #include <cstdint> |
| YSI | 0:d3c997729db1 | 27 | |
| YSI | 0:d3c997729db1 | 28 | ClockCounter::ClockCounter(PinName PIN_CAP2, edgeDetection EDGE) |
| YSI | 0:d3c997729db1 | 29 | { |
| YSI | 5:b5e68cd91f09 | 30 | _count = 0; |
| YSI | 5:b5e68cd91f09 | 31 | _selectPin = NC; |
| YSI | 0:d3c997729db1 | 32 | switch(PIN_CAP2) |
| YSI | 0:d3c997729db1 | 33 | { |
| YSI | 0:d3c997729db1 | 34 | case p30: case p29: |
| YSI | 0:d3c997729db1 | 35 | // PCONP => Power Mode Control register |
| YSI | 0:d3c997729db1 | 36 | LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on |
| YSI | 0:d3c997729db1 | 37 | // PCLKSEL1 => Peripheral Clock Selection register 1 |
| YSI | 0:d3c997729db1 | 38 | LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz) |
| YSI | 0:d3c997729db1 | 39 | // TCR => Timer Control Register |
| YSI | 0:d3c997729db1 | 40 | LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled |
| YSI | 0:d3c997729db1 | 41 | // PINSEL0 => Pin Function Select register 0 |
| YSI | 0:d3c997729db1 | 42 | LPC_PINCON->PINSEL0 |= (0x3<<((PIN_CAP2==p30)?8:10)); // Bits(9,8) 11 => pin function CAP2.0 (p30), Bits(11,10) 11 => pin function CAP2.1 (p29) |
| YSI | 0:d3c997729db1 | 43 | // CTCR => Count Control Register |
| YSI | 0:d3c997729db1 | 44 | LPC_TIM2->CTCR = ((PIN_CAP2==p30)?0:4)+EDGE; // Bits(3,2) 00 => CAP2.0 (p30 signal is counter clock) or 11 => CAP2.1 (p29 signal is counter clock), Bits(1,0) XX => timer is incremented on edge |
| YSI | 0:d3c997729db1 | 45 | // CCR => Capture Control Register |
| YSI | 0:d3c997729db1 | 46 | LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled |
| YSI | 0:d3c997729db1 | 47 | break; |
| YSI | 4:b873a2fda102 | 48 | default: |
| YSI | 4:b873a2fda102 | 49 | break; |
| YSI | 0:d3c997729db1 | 50 | } |
| YSI | 0:d3c997729db1 | 51 | } |
| YSI | 0:d3c997729db1 | 52 | |
| YSI | 5:b5e68cd91f09 | 53 | void ClockCounter::setPin(PinName PIN_CAP2, edgeDetection EDGE) |
| YSI | 5:b5e68cd91f09 | 54 | { |
| YSI | 5:b5e68cd91f09 | 55 | _selectPin = PIN_CAP2; |
| YSI | 5:b5e68cd91f09 | 56 | switch(PIN_CAP2) |
| YSI | 5:b5e68cd91f09 | 57 | { |
| YSI | 5:b5e68cd91f09 | 58 | case p30: case p29: |
| YSI | 5:b5e68cd91f09 | 59 | // PCONP => Power Mode Control register |
| YSI | 5:b5e68cd91f09 | 60 | LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on |
| YSI | 5:b5e68cd91f09 | 61 | // PCLKSEL1 => Peripheral Clock Selection register 1 |
| YSI | 5:b5e68cd91f09 | 62 | LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz) |
| YSI | 5:b5e68cd91f09 | 63 | // TCR => Timer Control Register |
| YSI | 5:b5e68cd91f09 | 64 | LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled |
| YSI | 5:b5e68cd91f09 | 65 | // PINSEL0 => Pin Function Select register 0 |
| YSI | 5:b5e68cd91f09 | 66 | LPC_PINCON->PINSEL0 |= (0x3<<((PIN_CAP2==p30)?8:10)); // Bits(9,8) 11 => pin function CAP2.0 (p30), Bits(11,10) 11 => pin function CAP2.1 (p29) |
| YSI | 5:b5e68cd91f09 | 67 | // CTCR => Count Control Register |
| YSI | 5:b5e68cd91f09 | 68 | LPC_TIM2->CTCR = ((PIN_CAP2==p30)?0:4)+EDGE; // Bits(3,2) 00 => CAP2.0 (p30 signal is counter clock) or 11 => CAP2.1 (p29 signal is counter clock), Bits(1,0) XX => timer is incremented on edge |
| YSI | 5:b5e68cd91f09 | 69 | // CCR => Capture Control Register |
| YSI | 5:b5e68cd91f09 | 70 | LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled |
| YSI | 5:b5e68cd91f09 | 71 | break; |
| YSI | 5:b5e68cd91f09 | 72 | default: |
| YSI | 5:b5e68cd91f09 | 73 | break; |
| YSI | 5:b5e68cd91f09 | 74 | } |
| YSI | 5:b5e68cd91f09 | 75 | } |
| YSI | 5:b5e68cd91f09 | 76 | |
| YSI | 5:b5e68cd91f09 | 77 | void ClockCounter::startCount(void) |
| YSI | 5:b5e68cd91f09 | 78 | { |
| YSI | 5:b5e68cd91f09 | 79 | // TCR => Timer Control Register |
| YSI | 5:b5e68cd91f09 | 80 | LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset |
| YSI | 5:b5e68cd91f09 | 81 | LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled |
| YSI | 5:b5e68cd91f09 | 82 | } |
| YSI | 5:b5e68cd91f09 | 83 | |
| YSI | 5:b5e68cd91f09 | 84 | int ClockCounter::stopCount(void) |
| YSI | 5:b5e68cd91f09 | 85 | { |
| YSI | 5:b5e68cd91f09 | 86 | LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled |
| YSI | 5:b5e68cd91f09 | 87 | uint32_t TC = LPC_TIM2->TC; // TC => Timer Counter |
| YSI | 5:b5e68cd91f09 | 88 | _selectPin = NC; |
| YSI | 5:b5e68cd91f09 | 89 | return TC; |
| YSI | 5:b5e68cd91f09 | 90 | } |
| YSI | 5:b5e68cd91f09 | 91 | |
| YSI | 3:20dd01b1a1fd | 92 | int ClockCounter::getCount(int period) |
| YSI | 0:d3c997729db1 | 93 | { |
| YSI | 0:d3c997729db1 | 94 | // TCR => Timer Control Register |
| YSI | 0:d3c997729db1 | 95 | LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset |
| YSI | 0:d3c997729db1 | 96 | LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled |
| YSI | 3:20dd01b1a1fd | 97 | wait_us(period); |
| YSI | 0:d3c997729db1 | 98 | LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled |
| YSI | 0:d3c997729db1 | 99 | return LPC_TIM2->TC; // TC => Timer Counter |
| YSI | 5:b5e68cd91f09 | 100 | } |
| YSI | 5:b5e68cd91f09 | 101 | |
| YSI | 5:b5e68cd91f09 | 102 | PinName ClockCounter::getPin(void) |
| YSI | 5:b5e68cd91f09 | 103 | { |
| YSI | 5:b5e68cd91f09 | 104 | return _selectPin; |
| YSI | 0:d3c997729db1 | 105 | } |
Y SI