这次用了两天的时间来验证这个功能,虽然实验没有成功,但是也要记录一下,后面能解决了,回来再写上解决的办法:
这个程序最后的实验结果是读取到的CCR1和CCR2的值都是0,所以没有办法算出来频率和占空比。
还是说一下这个工程中开启输入捕获的方法吧:
第一步:RCC开启时钟,把GPIO和TIM的时钟打开
第二步:GPIO初始化,把GPIO配置成输入模式(上拉输入)
第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
第四步:配置输入捕获单元(滤波器、极性、直连通道还是交叉通道、分频器这些参数)
第五步:选择从模式的触发源(TI1FP1)(一个函数)
第六步:选择触发之后执行的操作执行Reset操作(一个函数)
第七步:开启定时器
整个过程的思维框图:
第五步和第六步的思维框图:
整个工程的机构:
下面是IC.c的文件:
#include "stm32f10x.h" // Device headervoid IC_Init(void){//第一步:RCC开启时钟,把GPIO和TIM的时钟打开RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//第二步:GPIO初始化,把GPIO配置成输入模式(上拉输入)GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);//第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行TIM_InternalClockConfig(TIM3); // 选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period = 65536-1; // ARR的值,设置成最大,防止溢出TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1; // PSC的值TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);//第四步:配置输入捕获单元(滤波器、极性、直连通道还是交叉通道、分频器这些参数)TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; //选择通道1TIM_ICInitStruct.TIM_ICFilter = 0XF; //滤波器值最大0XFTIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //预分频器为1分频TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //直连通道TIM_ICInit(TIM3, &TIM_ICInitStruct);
//
// TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; //选择通道1
// TIM_ICInitStruct.TIM_ICFilter = 0XF; //滤波器值最大0XF
// TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; //上升沿触发
// TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //预分频器为1分频
// TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI; //交叉通道
// TIM_ICInit(TIM3, &TIM_ICInitStruct);TIM_PWMIConfig(TIM3, &TIM_ICInitStruct); // 这个函数和上面注释的7行效果一样。//第五步:选择从模式的触发源(TI1FP1)(一个函数)TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 触发源选择//第六步:设置从模式为ResetTIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 从模式设置//第七步:开启定时器TIM_Cmd(TIM3, ENABLE);
}uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3)+1); // 1000000/CCR的值
}uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3)+1)*100 / (TIM_GetCapture1(TIM3)+1);
}
IC.h的文件:
#ifndef __IC_H
#define __IC_Hvoid IC_Init(void);uint32_t IC_GetFreq(void);uint32_t IC_GetDuty(void);#endif
主函数main.c的文件:
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "IC.h"int main(void)
{OLED_Init(); //oled 屏幕初始化IC_Init();//OLED_ShowString(1,1, "Freq: Hz");while(1){OLED_ShowNum(1,2, IC_GetFreq(),8); OLED_ShowNum(2,2, IC_GetDuty(),8); OLED_ShowNum(3,1, TIM_GetCapture1(TIM3),16);OLED_ShowNum(4,1, TIM_GetCapture2(TIM3),16);}
}
由于总是显示不了正确的频率和占空比,特意把两个数都显示在OLED上,结果都是0
也许我是仿真的缘故吧!所以没有成功,回头我买来了硬件,再来学习一下,看看是不是能解决这个问题。如果能后面会更新的。.....