基于学习江科大stm32输入捕获的总结

要实现课上讲的第一个项目,大体可以分为两大部分,第一部分是配置输出,第二部分是配置输入捕获。

首先是配置输出,输出分为5步:

1.开启总线时钟,包括定时器(APB2)和GPIO(APB1)。

2.配置GPIO,选择为推挽输出,并将定时器配置为内部时钟。

3.配置时基单元,设置不分频,上拉输出,同时配置PSC(分频器)和ARR(时钟周期)。

4.配置输出比较模块,设置初始CCR,以及输出比较模式。

5. 最后是使能时钟。

然后是输入捕获模式,总体可以分为7步

前两步和输出比较一样,其中注意GPIO接口的选择,配置上拉输入模式,以及定时器的选择(TIM3)。

3.时基单元大体一致,但注意Period要设置的大一些,应为这里使用的计算频率的方法是根据输入频率跳动一次的情况下,输入定时器CCR跳到的个数,应当防止数据的溢出(一般为65535),然后是PSC分频的设置,这个的设置尽量的小一点,(因为其中会有+-1的误差在里面,要尽量使这里+-1的误差对整体的影响小,所以要让输入定时器频率快一点,也就是分频小一点),同时为了方便计算频率,所以一般使用PSC设置为72,(这样子72M的频率就可以转化为1M来计算了)。

4.然后是配置输入捕获模块,按照正常配置即可(如上拉,不分频,通道1,滤波0xF)

5.然后是配置从模式,选择输入触发源

6.设置复位模式,让计数归零       //此处作者电路图没太看懂,无法给出更详细的解释,回去好好                                                                                                                             //学数电哈哈哈

7.定时器使能

最后按照需要,可以将设置输出比较值和设置PSC1以及获取输入捕获获取频率封装成函数。再在主函数中实现即可,最后奉上代码

//PWM
#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  //开启时钟APB1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_IniStruct;
	GPIO_IniStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_IniStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_IniStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_IniStruct);
	
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 100 - 1;   //确定周期(ARR)
	TIM_TimeBaseInitStruct.TIM_Prescaler = 720 - 1;   //确定PSC分频(PSC)
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;   //通用计时器没有重复计数器功能
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0;      //CCR
	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
	
	
	TIM_Cmd(TIM2, ENABLE);  //定时器使能
}


void PWM_SetCompare1(uint16_t compel)
{
	TIM_SetCompare1(TIM2, compel);
}

void PWM_SetPrescaler(uint32_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);
}
//IC
#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  //开启时钟APB1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_IniStruct;
	GPIO_IniStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_IniStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_IniStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_IniStruct);
	
	TIM_InternalClockConfig(TIM3);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_Period = 65535 - 1;
	TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICFilter = 0xF;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM3, &TIM_ICInitStruct); 
	
	// 5. 选择从模式的触发源
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	// 6. 选择从模式触发后执行的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	TIM_Cmd(TIM3, ENABLE);
	
}

uint32_t IC_GetFreq(void)
{
	return 1000000 / TIM_GetCapture1(TIM3);
}
//main
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

uint8_t i;

int main()
{
	OLED_Init();
	PWM_Init();
	IC_Init();
	OLED_ShowString(1, 1, "Freq:00000Hz");
	PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值