Added Timer 'Input Capture' support and example

This commit is contained in:
Roger Clark 2018-02-10 14:47:33 +11:00
parent 42a5e9f907
commit 36bd1be387
4 changed files with 82 additions and 3 deletions

View File

@ -39,6 +39,7 @@ static void disable_channel(timer_dev *dev, uint8 channel);
static void pwm_mode(timer_dev *dev, uint8 channel);
static void output_compare_mode(timer_dev *dev, uint8 channel);
static void encoder_mode(timer_dev *dev, uint8 channel) ;//CARLOS
static void input_capture_mode(timer_dev *dev, uint8 channel);//@Cesco
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid);
@ -236,6 +237,9 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
case TIMER_ENCODER:
encoder_mode(dev, channel); //find a way to pass all the needed stuff on the 8bit var
break;
case TIMER_INPUT_CAPTURE:// code from @Cesco
input_capture_mode(dev, channel);
break;
}
}
@ -349,7 +353,11 @@ static void encoder_mode(timer_dev *dev, uint8 channel __attribute__((unused)))
timer_resume(dev);
}
// Code supplied by @Cesco (on the forum)
static void input_capture_mode(timer_dev *dev, uint8 channel) {
timer_oc_set_mode(dev, channel, 0, TIMER_CCMR_CCS_INPUT_TI1);
timer_cc_enable(dev, channel);
}
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
static void enable_bas_gen_irq(timer_dev *dev);

View File

@ -0,0 +1,68 @@
/* Example of the Timer Input Capture mode
*
* Thanks to @cesco on the stm32duino.com
*
* This example uses Timer2. Other timers also support this mode, bnt on the F103C
* only Timer 2 has usable external trigger pins. PA0 and PA15
* Because the only other usable pin on the F103C is one of the USB pins.
*
* Upload to your favourite F103Cx
* Open the Serial plotter
* Put your finger on either PA0 or PA15 (depenidng whether you USE the pin remapping)
*
* Observe your local mains frequency in terms of pulse width time.
*
*/
/* Timer2 external trigger can be ether PA0 or PA15.
To use use afio_remap(FIO_REMAP_TIM2_PARTIAL_1) or afio_remap(AFIO_REMAP_TIM2_FULL)
Note. using afio_remap also changes the pins used by Timer2 CH1,CH2,CH3 amd CH4
* See page 184 of the STM32F10x Refernce manual (PDF downloadable from ST.com
*/
//#define USE_REMAP_PIN
#ifdef USE_REMAP_PIN
const int timer2ExternalTriggerPin = PA15;
#else
const int timer2ExternalTriggerPin = PA0;
#endif
volatile boolean hasCapture;
volatile uint16_t captureValue;
volatile uint16_t lastCaptureValue=0;
volatile uint16_t captureDifference=0;
void captureCallback(void) {
hasCapture=true;
captureValue = Timer2.getCompare(1);
captureDifference = captureValue-lastCaptureValue;
lastCaptureValue=captureValue;
}
void setup() {
pinMode(timer2ExternalTriggerPin,INPUT);
#ifdef USE_REMAP_PIN
afio_remap(AFIO_REMAP_TIM2_PARTIAL_1);
#endif
hasCapture = false;
Timer2.setPrescaleFactor(72); // prescaler to count 72,000,000 / 72 counts per second. i.e count microseconds
Timer2.setMode(TIMER_CH1, TIMER_INPUT_CAPTURE);
Timer2.attachCompare1Interrupt(captureCallback);
}
void loop() {
// Printing inside the callback is not a good idea.
// Hence the capture callback sets a flag , which is detected here
if (hasCapture)
{
Serial.println(captureDifference);
hasCapture=false;
}
}

View File

@ -564,13 +564,15 @@ typedef enum timer_mode {
* values, the corresponding interrupt is fired. */
TIMER_OUTPUT_COMPARE,
/* TIMER_INPUT_CAPTURE, TODO: In this mode, the timer can measure the
/* TIMER_INPUT_CAPTURE, UNDER DEVELOPMENT: In this mode, the timer can measure the
* pulse lengths of input signals */
/* TIMER_ONE_PULSE, TODO: In this mode, the timer can generate a single
* pulse on a GPIO pin for a specified amount of
* time. */
TIMER_ENCODER, //CARLOS Change
TIMER_INPUT_CAPTURE,// code from @cesco
} timer_mode;
/** Timer channel numbers */

View File

@ -351,7 +351,8 @@ typedef enum afio_remap_peripheral {
* Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1,
* CH3 on PB10, CH4 on PB11) */
AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11,
/** Timer 2 full remapping */
/** Timer 2 full remapping
(CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */
AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL,
/** USART 3 part remapping */
AFIO_REMAP_USART3_PARTIAL = AFIO_MAPR_USART3_REMAP_PARTIAL,