当前位置:   article > 正文

STM32输入捕获频率和占空比proteus仿真失败

STM32输入捕获频率和占空比proteus仿真失败

这次用了两天的时间来验证这个功能,虽然实验没有成功,但是也要记录一下,后面能解决了,回来再写上解决的办法:

这个程序最后的实验结果是读取到的CCR1和CCR2的值都是0,所以没有办法算出来频率和占空比

还是说一下这个工程中开启输入捕获的方法吧:

第一步:RCC开启时钟,把GPIO和TIM的时钟打开

第二步:GPIO初始化,把GPIO配置成输入模式(上拉输入)

第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行

第四步:配置输入捕获单元(滤波器、极性、直连通道还是交叉通道、分频器这些参数)

第五步:选择从模式的触发源(TI1FP1)(一个函数)

第六步:选择触发之后执行的操作执行Reset操作(一个函数)

第七步:开启定时器

整个过程的思维框图:

第五步和第六步的思维框图:

整个工程的机构:

下面是IC.c的文件:

  1. #include "stm32f10x.h" // Device header
  2. void IC_Init(void)
  3. {
  4. //第一步:RCC开启时钟,把GPIO和TIM的时钟打开
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  7. //第二步:GPIO初始化,把GPIO配置成输入模式(上拉输入)
  8. GPIO_InitTypeDef GPIO_InitStruct;
  9. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  10. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
  11. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA, &GPIO_InitStruct);
  13. //第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
  14. TIM_InternalClockConfig(TIM3); // 选择内部时钟
  15. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  16. TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  17. TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  18. TIM_TimeBaseInitStruct.TIM_Period = 65536-1; // ARR的值,设置成最大,防止溢出
  19. TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1; // PSC的值
  20. TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
  21. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
  22. //第四步:配置输入捕获单元(滤波器、极性、直连通道还是交叉通道、分频器这些参数)
  23. TIM_ICInitTypeDef TIM_ICInitStruct;
  24. TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; //选择通道1
  25. TIM_ICInitStruct.TIM_ICFilter = 0XF; //滤波器值最大0XF
  26. TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发
  27. TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //预分频器为1分频
  28. TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //直连通道
  29. TIM_ICInit(TIM3, &TIM_ICInitStruct);
  30. //
  31. // TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; //选择通道1
  32. // TIM_ICInitStruct.TIM_ICFilter = 0XF; //滤波器值最大0XF
  33. // TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; //上升沿触发
  34. // TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //预分频器为1分频
  35. // TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI; //交叉通道
  36. // TIM_ICInit(TIM3, &TIM_ICInitStruct);
  37. TIM_PWMIConfig(TIM3, &TIM_ICInitStruct); // 这个函数和上面注释的7行效果一样。
  38. //第五步:选择从模式的触发源(TI1FP1)(一个函数)
  39. TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 触发源选择
  40. //第六步:设置从模式为Reset
  41. TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 从模式设置
  42. //第七步:开启定时器
  43. TIM_Cmd(TIM3, ENABLE);
  44. }
  45. uint32_t IC_GetFreq(void)
  46. {
  47. return 1000000 / (TIM_GetCapture1(TIM3)+1); // 1000000/CCR的值
  48. }
  49. uint32_t IC_GetDuty(void)
  50. {
  51. return (TIM_GetCapture2(TIM3)+1)*100 / (TIM_GetCapture1(TIM3)+1);
  52. }

IC.h的文件:

  1. #ifndef __IC_H
  2. #define __IC_H
  3. void IC_Init(void);
  4. uint32_t IC_GetFreq(void);
  5. uint32_t IC_GetDuty(void);
  6. #endif

主函数main.c的文件:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "IC.h"
  4. int main(void)
  5. {
  6. OLED_Init(); //oled 屏幕初始化
  7. IC_Init();
  8. //OLED_ShowString(1,1, "Freq: Hz");
  9. while(1)
  10. {
  11. OLED_ShowNum(1,2, IC_GetFreq(),8);
  12. OLED_ShowNum(2,2, IC_GetDuty(),8);
  13. OLED_ShowNum(3,1, TIM_GetCapture1(TIM3),16);
  14. OLED_ShowNum(4,1, TIM_GetCapture2(TIM3),16);
  15. }
  16. }

由于总是显示不了正确的频率和占空比,特意把两个数都显示在OLED上,结果都是0

也许我是仿真的缘故吧!所以没有成功,回头我买来了硬件,再来学习一下,看看是不是能解决这个问题。如果能后面会更新的。.....

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/233377
推荐阅读
相关标签
  

闽ICP备14008679号