Gpio_inittypedef gpio_initstructure;
Rcc_ahb1periphclockcmd (Rcc_ahb1periph_gpiof, ENABLE);
Gpio_initstructure.gpio_pin = Gpio_pin_6;
Gpio_initstructure.gpio_mode = gpio_mode_in;
GPIO_INITSTRUCTURE.GPIO_PUPD = Gpio_pupd_nopull;
Gpio_initstructure.gpio_speed = Gpio_speed_100mhz;//100mhz
Gpio_init (Gpiof, &gpio_initstructure);
Gpio_initstructure.gpio_pin = gpio_pin_7;
Gpio_initstructure.gpio_mode = Gpio_mode_out;
Gpio_initstructure.gpio_otype = gpio_otype_pp;
Gpio_init (Gpiof, &gpio_initstructure);
Nvic_inittypedef nvic_initstructure;
Exti_inittypedef exti_initstructure;
Rcc_apb2periphclockcmd (Rcc_apb2periph_syscfg, ENABLE);
Syscfg_extilineconfig (Exti_portsourcegpiof, Exti_pinsource6);
Syscfg_extilineconfig (Exti_portsourcegpiof, Exti_pinsource7);
Exti_initstructure.exti_line = Exti_line6;//line6
Exti_initstructure.exti_mode = exti_mode_interrupt;//
Exti_initstructure.exti_trigger = exti_trigger_rising_falling; //
Exti_initstructure.exti_linecmd = ENABLE;
Exti_init (&exti_initstructure);
Nvic_prioritygroupconfig (nvic_prioritygroup_2);
Nvic_initstructure.nvic_irqchannel = EXTI9_5_IRQN;
nvic_initstructure.nvic_irqchannelpreemptionpriority = 0x03;
nvic_initstructure.nvic_irqchannelsubpriority = 0x02;
Nvic_initstructure.nvic_irqchannelcmd = ENABLE;
Nvic_init (&nvic_initstructure);
void Exti9_5_irqhandler (void)
{
if (1) CNT
if (0) CNT end
Gengxin Quanju Distance
Exti_clearitpendingbit (Exti_line6);
}
while (1) {gpio_setbits (gpioa,gpio_pin_8);d Elay_nus (20);//pull higher than 10US, launch ultrasonic gpio_resetbits (gpioa,gpio_pin_8); tim2->cnt=0;//counter Clear 0while (Gpio_readinputdatabit (gpioa,gpio_pin_9) ==0);//wait for the echo foot high level Tim_cmd (TIM2, ENABLE);// TIM2 Enable counter [Allow TIM2 count]
while ((Gpio_readinputdatabit (gpioa,gpio_pin_9) ==1) && (tim2->cnt<tim2->arr-10));
Tim_cmd (TIM2, DISABLE);
Count=tim2->cnt;//echo the value of the counter after the low level of the foot to calculate the round trip time Length=count/58.0;display_list_char (1,9, "");D Isplay_list_float ( 1,9,length);d ELAY_NMS (200);}
Timer 4 on, set interrupt rising edge start, falling edge calculation distance
Timer 11 on, capture with input
STM32 input capture, that is, by detecting the edge signal on the channel, in the edge of the signal to jump (for example, a sudden rise or fall edge), the counter will be at the moment of the count value to the corresponding channel capture comparison register, in this way, to capture the "beautiful", words are said, Can be manipulated not only a few words, because the initialization and processing of the capture is not the same, so, in order to prepare for the capture, we will introduce the next few unfamiliar bits:
Some registers for timers are involved in previous blogs, such as
TIMX_CR1,
Capture/Compare Mode Register 1 (TIMX_CCMR1),
Capture/Compare enable register (timx_ccer),
Counter (TIMX_CNT)
Prescaler (TIMX_PSC)
Automatic reload Register (Timx_arr)
Capture/Compare Register 1 (TIMX_CCR1)
Let's take a look at capture/Compare mode Register 1 (TIMX_CCMR1), because we are using TIM5_CH1, so the register
CC1S[1:0]: Capture/Compare 1 selection (Capture/compare 1 selection) We select 01:CC1 Channel is configured as input, IC1 map on TI1; Does this know why it's TI1? Take a look at my beautiful graffiti:
Here we detect the width of the high level, so we detect when we encounter the rising edge to trigger the capture once, but how do we set it, see these several:
IC1PSC[1:0]: Enter/capture 1 prescaler (Input capture 1 prescaler) 00: No Prescaler, captures each edge detected on the input port to trigger a capture;
Magical, all right, ic1f[3:0]: Input capture 1 Filter (input capturing 1 filter) (This is the in-filter, here we do not filter processing, why, see the following explanation)
This is explained here: The digital filter consists of an event counter, which logs to n events will produce an output of the jump: This n can be value specific reference to the Chinese manual, meaning: I sampled the high level, only continuous sampling to n levels is high, I think is a valid high level, Less than n I think it is invalid, in this blog, as long as we are sampling to high level on the line, so there is no use of digital filtering.
Let's take a look at this register capture/Compare enable register (Timx_ccer), to enable capture enable, we need to set the Enable bit
CC1E: Input/capture 1 output enable (Capture/compare 1 output enable) is 0;
For our input to be processed after the interrupt we give to us, so here we have to turn on the interrupt enable bit
dma/Interrupt enable register (timx_dier) Cc1ie: Allows capturing/comparing 1 interrupts (Capture/compare 1 interrupt enable) to 1;
Introduce the above several great gods, next, we want to how a train of thought?? = = When we capture the rising edge, we read the value of CNT at this time and wait for the descent to come, which is divided into two situations:
First: The falling edge comes, we record the value of CNT at the moment, (capture value) and repeat the above action
Second: The falling edge does not come, but this time the timer count value has arrived, that is, to overflow, this time to special treatment, that is, directly to the value of the return
(Note: Here, to note the difference between the capture value and the count value, they are not the same,) as for why not the same, we can think about,
So we subtract the value of two captures, (the value of the falling edge minus the rising edge) to get a high-level pulse width, and these things we're dealing with in the Interrupt service function (interrupt Oh, remember?) What to do know, note that there are two interrupt triggers at this time: Update interrupt and capture interrupt, update interrupt to handle timer count overflow, capture interrupt to handle capture event)
Next, let's take a look at our specific implementation steps
1: Open the TIM5 clock mounted on the ABP1, turn on the Gpioa clock mounted on ABP2, and initialize the TIM5 and Gpioa, since these two initialize before several blogs are involved, so directly post the code:
1 2 3 4 //9 Tim_timebasestructure.tim_countermode = tim_countermode_up; Ten Tim_timebaseinit (TIM5, & tim_timebasestructure);
2, set the Tim_ch1 input capture function, open "stm3210x.tim.h" we can see
1 typedef struct2 {34 uint16_t Tim_channel;/*!< Specifies the TIM channel. Set channels 5 This parameter can be a value of@ref Tim_channel * *67 uint16_t tim_icpolarity;/*!< Specifies the active edge of the input signal. Sets the effective capture polarity of the input signal 8 This parameter can be a value of@ref tim_input_capture_polarity */ 9 uint16_t tim_icselection; / *!< Specifies the input. Set mapping relationship One this parameter can a value of @ref tim_input_capture_selection * / uint16_t Tim_icprescaler; / *!< Specifies the Input capture Prescaler. Set the allocation factor for the capture this parameter can be a value of @ref Tim_input_ca Pture_prescaler */ uint16_t tim_icfilter; / *!< Specifies the input capture filter. Set the length of the digital filter This parameter can be a number between 0x0 and 0xF */
18} tim_icinittypedef;
According to our understanding, we set, please look at the following code:
1 tim_icinitstructure.tim_channel = tim_channel_1; //Channel 12 tim_icinitstructure.tim_icpolarity = tim_icpolarity_rising; // rising edge capture //map to TI1//non-crossover // No filtering 6 tim_icinit (TIM5, &tim_icinitstructure);
3, set the interrupt priority, here is relatively simple, look directly at the code:
1 nvic_initstructure.nvic_irqchannel = tim5_irqn; 2 nvic_initstructure.nvic_irqchannelpreemptionpriority = 2;3 nvic_initstructure.nvic_ irqchannelsubpriority = 2;4 nvic_initstructure.nvic_irqchannelcmd = ENABLE; 5 Nvic_init (&nvic_initstructure);
4. Enable to interrupt and turn on the timer
1 2 tim_itconfig (TIM5, tim_it_Update | TIM_IT_CC1, ENABLE); 3 4 tim_cmd (TIM5, ENABLE);
5. Write Interrupt Service function
1 U8 Tm5_ch1_capture_sta =0;8-bit 0x00~0x802 U16 Tm5_ch1_capture_val;//Number of timer overflows after capturing high level34void Tim5_irqhandler (void5 {6if (Tm5_ch1_capture_sta &0x80) = =0)//Not successfully captured, 0x80 capture complete7 {8if (Tim_getitstatus (TIM5, tim_it_update) = = SET)//Data Update interrupt Generation9 {10if (Tm5_ch1_capture_sta &0x40The high level has been captured11 {12if (Tm5_ch1_capture_sta &0x3f) = =0x3f//Overflow13 {Tm5_ch1_capture_sta |=0x80Forced capture succeededTm5_ch1_capture_val =0xFFFF;The count value at this time16}17Else18 {tm5_ch1_capture_sta++;20}21st22}23}24if (Tim_getitstatus (TIM5, tim_it_cc1) = = SET)//Occurrence capture25 {26if (Tm5_ch1_capture_sta &0x40Successfully captures a falling edge, but not the first capture27 {Tm5_ch1_capture_sta |=0x80Capture successTm5_ch1_capture_val = Tim_getcapture1 (TIM5);Get capture valueTim_oc1polarityconfig (TIM5, tim_icpolarity_rising);To set the rising edge, wait for the falling edge to come31} 32 else //first capture 33 {34 Tm5_ch1_capture_sta = 0; Tm5_ch1_capture_val = 0; Tim_setcounter (TIM5, 0); //had not waited until the falling edge to bring all the clear 0 37 tm5_ch1_capture_sta |= 0x40; 38 tim_oc1polarityconfig (TIM5, tim_icpolarity_falling); //to be set to a falling edge, until the rising edge of the coming 39}40 41 }42}43 tim_clearitpendingbit (TIM5, TIM_IT_CC1 | Tim_it_update); 44 45}
6, pay attention to the red label part, well understand the beginning of the count and capture the difference between the value, there are
Set Counter Register value
Tim_oc1polarityconfig (TIM5, tim_icpolarity_falling); //Set Channel 1 input capture polarity the two functions are library functions for us to improve the operation of the channel can be separate uncle, very convenient
7. Here we need to write a little bit in the main function:
1 if (Tm5_ch1_capture_sta & 0x80) 2 {3 temp = (Tm5_ch1_capture_val & 0x3f); 4 temp *= 65536; //counter is 0~65535, that is 655,361 times Span class= "number" >5 temp + = Tm5_ch1_capture_val; 6 printf ( "high is %d\r\n ", temp); 7 Tm5_ch1_capture_sta = 0; Here because we were in the previous capture, if the capture succeeds then 1, and is not clear, so for the next capture, here you need to clear 0 8}
8, good, as for my title said the small application, that is, we last PWM output to this input capture, we can see the high-level pulse width through the serial port. Of course, in this blog program also need to keep the last PWM output of the program can,,
Timer Configuration Interrupt Configuration GPIO