【蓝桥杯嵌入式拓展板】—PWM输入捕获 详解(官网程序优化)(附程序源码)

首先,有一点要说,这个程序经过测试,比官网例程更稳定。而且数据误差很小。官网程序在高占空比的时候会存在数据严重抖动的现象。

STM32-ADC配置详解及应用。实例:《中断单通道读取ADC》、《DMA多通道读取ADC》
关于ADC的讲解,这篇文章所讲内容,不仅可以满足蓝桥杯的需求,而且还进行了拓展

链接: https://blog.csdn.net/qq_45689790/article/details/113862143

优化代码

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;
		}
	}
}

其实相比较官网例程,主要增加了初始化时基结构体,周期很重要,既然是输入捕获,所以直接设成最大 0xFFFF

还有就是计算周期和占空比的时候,应进行 加一操作。

实测 稳的一批!

欢迎交流探讨

猜你喜欢

转载自blog.csdn.net/qq_45689790/article/details/114149928