[Lanqiao Cup Embedded Expansion Board]—Detailed explanation of PWM input capture (official website program optimization) (program source code attached)

First of all, one thing to say is that this program has been tested and is more stable than the official website routine. And the data error is very small. The official website program will have serious data jitter when the duty cycle is high.

STM32-ADC configuration detailed explanation and application. Examples: "Interrupt Single Channel Reading ADC", "DMA Multi-channel Reading ADC"
about ADC, the content of this article can not only meet the needs of the Blue Bridge Cup, but also expand

Link: https://blog.csdn.net/qq_45689790/article/details/113862143

Optimized code

1、static void General_Timer_GPIO_Config(void)

static void General_Timer_GPIO_Config(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(TIM_CH_GPIO_CLK,ENABLE);

	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin = TIM_CH_GPIO_PIN;
	GPIO_Init(TIM_CH_GPIO_PORT,&GPIO_InitStruct);
}

2、static void General_Timer_NVIC_Config(void)

static void General_Timer_NVIC_Config(void)
{
    
    
	NVIC_InitTypeDef 	NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStructure.NVIC_IRQChannel = General_TIMx_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

3、static void General_Timer_Config(void)

static void General_Timer_Config(void)
{
    
    
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_ICInitTypeDef TIM_ICInitStruct;
	
	RCC_APB1PeriphClockCmd(General_TIM_CLK,ENABLE);
	/*------------------初始化时基结构体--------------*/
	TIM_TimeBaseInitStruct.TIM_Prescaler = General_TIM_Prescaler;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = General_TIM_Period;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(General_TIM_x,&TIM_TimeBaseInitStruct);
	
	/*------------------输入捕获结构体--------------*/
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICFilter = 0x0;
	
	TIM_PWMIConfig(General_TIM_x,&TIM_ICInitStruct);
	
	TIM_SelectInputTrigger(General_TIM_x,TIM_TS_TI2FP2);
	
	TIM_SelectSlaveMode(General_TIM_x,TIM_SlaveMode_Reset );
	TIM_SelectMasterSlaveMode(General_TIM_x,TIM_MasterSlaveMode_Enable);
	
	TIM_Cmd(General_TIM_x,ENABLE);
	
	TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}

4、void General_Timer_Init(void)

void General_Timer_Init(void)
{
    
    
	General_Timer_GPIO_Config();
	General_Timer_NVIC_Config();
	General_Timer_Config();
}

5、"bsp_GeneralTimer.h"

#ifndef _BSP_GENERALTIMER_H_
#define	_BSP_GENERALTIMER_H_

#include "stm32f10x.h"
		
#define TIM_CH_GPIO_PORT						GPIOA
#define TIM_CH_GPIO_PIN							GPIO_Pin_7
#define TIM_CH_GPIO_CLK							RCC_APB2Periph_GPIOA
	
//TIM3_CH2		
#define General_TIM_x							TIM3
#define General_TIM_CLK							RCC_APB1Periph_TIM3


#define General_TIM_Prescaler					(72-1)
#define General_TIM_Period						(0xffff)

#define General_TIMx_IRQn						TIM3_IRQn

void General_Timer_Init(void);

#endif /*_BSP_GENERALTIMER_H_*/

6、main

int main(void)
{
    
    
	LED_GPIO_Config();
	STM3210B_LCD_Init();
	General_Timer_Init();
	LCD_SetTextColor(White);
	LCD_SetBackColor(Blue);
	LCD_Clear(Blue);
	LCD_DisplayStringLine(Line1,"     PUSLE DEMO         ");

	LCD_SetTextColor(Blue);
	LCD_SetBackColor(White);
	
	LCD_ClearLine(Line4);
	LCD_ClearLine(Line5);
	LCD_ClearLine(Line6);
	LCD_ClearLine(Line7);
	LCD_ClearLine(Line8);
	LCD_ClearLine(Line9);
		
	while(1)
	{
    
    
		sprintf(TXT_test, " PA7-DTY:%d%%     ", DutyCycle);
		LCD_DisplayStringLine(Line6, TXT_test);
		
		sprintf(TXT_test," PA7-FRQ:%.1fKHz   ",Frequency/1000.);
		LCD_DisplayStringLine(Line7, TXT_test);
	}          
}

7、void TIM3_IRQHandler(void)

void TIM3_IRQHandler(void)
{
    
    
	
	if(TIM_GetITStatus(General_TIM_x, TIM_IT_CC2) == SET)
	{
    
    
			TIM_ClearITPendingBit(General_TIM_x, TIM_IT_CC2);

			IC1Value = TIM_GetCapture1(General_TIM_x);	//占空比
			IC2Value = TIM_GetCapture2(General_TIM_x);  //周期

		if (IC2Value != 0)
		{
    
    
				DutyCycle = ((IC1Value+0) * 100) / (IC2Value+1);
				Frequency = (SystemCoreClock/(General_TIM_Prescaler+1) )/ (IC2Value+1);
		}
		else
		{
    
    
				DutyCycle = 0;
				Frequency = 0;
		}
	}
}

In fact, compared to the official website routines, the initialization time base structure is mainly added. The period is very important. Since it is an input capture, it is directly set to the maximum value of 0xFFFF.

In addition, when calculating the period and duty cycle, one should be added.

A batch of measured and stable!

Welcome to exchange and discuss

Guess you like

Origin blog.csdn.net/qq_45689790/article/details/114149928