这次用了两天的时间来验证这个功能,虽然实验没有成功,但是也要记录一下,后面能解决了,回来再写上解决的办法:
这个程序最后的实验结果是读取到的CCR1和CCR2的值都是0,所以没有办法算出来频率和占空比。
还是说一下这个工程中开启输入捕获的方法吧:
第一步:RCC开启时钟,把GPIO和TIM的时钟打开
第二步:GPIO初始化,把GPIO配置成输入模式(上拉输入)
第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
第四步:配置输入捕获单元(滤波器、极性、直连通道还是交叉通道、分频器这些参数)
第五步:选择从模式的触发源(TI1FP1)(一个函数)
第六步:选择触发之后执行的操作执行Reset操作(一个函数)
第七步:开启定时器
整个过程的思维框图:
第五步和第六步的思维框图:
整个工程的机构:
下面是IC.c的文件:
#include "stm32f10x.h" // Device header
void 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; //选择通道1
TIM_ICInitStruct.TIM_ICFilter = 0XF; //滤波器值最大0XF
TIM_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); // 触发源选择
//第六步:设置从模式为Reset
TIM_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_H
void 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
也许我是仿真的缘故吧!所以没有成功,回头我买来了硬件,再来学习一下,看看是不是能解决这个问题。如果能后面会更新的。.....