当前位置:   article > 正文

STM32个人学习笔记(标准库)-2023.09.20_void tim_bdtrconfig(tim_typedef* timx, tim_bdtrini

void tim_bdtrconfig(tim_typedef* timx, tim_bdtrinittypedef *tim_bdtrinitstru

第六节、TIM定时中断

6.1 TIM简介

TIM(Timer)定时器

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断(定时触发中断)。

16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。

不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。

根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。

定时器的类型如下:

STM32F103ZET6定时器资源:TIM1-8均有。

主模式触发DAC:在使用DAC时,可以将定时器的更新事件映射到触发输出TRGO上,TRGO直接接到DAC的触发转换引脚上,定时器的更新就不需要通过中断来触发DAC转换。实现了硬件的自动化。

6.2 定时器结构图分析

首先来看基本定时器:

它们的功能如下:

预分频器:对72MHZ的计数时钟进行预分频,例如如果预分频器写1,则为2分频,输出频率=输入频率/2=36MHZ。(即实际分配系数=预分频器的值+1

计数器:对预分频后的技术时钟进行计数。

自动重装寄存器:16位的寄存器,存入写入的计数目标。运行过程中,计数值不断自增,当计数值等于自动重装值,计时时间到,产生中断信号(更新中断,更新中断之后通往NVIC,配置好NVIC的定时器中断后,定时器的更新中断就能得到CPU的响应),并且清零计数器。

接下来来看通用定时器:

通用定时器与高级定时器支持三种计数模式,即向上计数、向下计数、中央对齐计数。

通用定时器的电路总共可以分为四个部分:

1、时基单元:与基本定时器的时基单元相同。

2、内外时钟源选择和主从触发模式:通用定时器不仅可以选择内部时钟作为时钟源,也可以选贼外部时钟作为时钟源。

3、输入捕获电路:可以用于测量方波频率等。

4、输出比较电路:总共有四个通道,分别对应CH1到CH4的引脚,适用于PWM产生波形。

下面再来看一下高级定时器:

相较于通用定时器,高级定时器多了个重复计数器,使计数时间大大增加。并且高级计数器还拥有输出比较模块,驱动三相无刷电机。以及刹车输入功能。

6.3 定时中断的基本结构

通过上图,定时器初始化可以分为以下几个步骤:

1、RCC开启时钟。

2、选择时基单元的时钟源。

3、配置时基单元。

4、配置输出中断控制。运行更新中断输出到NVIC

5、配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级。

6、运行控制。使能计数器。

通过时序图,我们能研究时基单元运行时的细节问题。

1、预分频器时序

计数器计数频率:CK_CNT=CK_PSC/(PSC+1)

预分频器的工作流程:首先,CK_PSC(预分频器输入时钟)不断运行;CNT_EN(计数器使能)为高电平时计数器正常运行,低电平时计数器停止;CK_CNT(计数器时钟)运行时,根据分频系数,前半段预分频器参数为1,计数器时钟等于预分频器前的时钟,后半段预分频器系数变为2,计数器时钟变为预分频器前时钟的一半。在计数器时钟的驱动下,计数器寄存器也跟随时钟的上升沿不断自增,在FC后,计数值变为0,下面产生更新事件。

2、计数器时序

计数器溢出频率:CK_CNT_OV=CK_CNT/(ARR+1)=CK_PSC/(PSC+1)/(ARR+1)

3、RCC时钟树

 

6.4 代码实现定时器功能

首先来看一下定时器的库函数:

  1. void TIM_DeInit(TIM_TypeDef* TIMx);//恢复缺省配置
  2. void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//时基单元初始化
  3. /*配置输出比较模块*/
  4. void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  5. void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  6. void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  7. void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  8. /*结构体配置输入捕获单元的函数*/
  9. void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
  10. /*初始化输入捕获单元*/
  11. void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
  12. void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
  13. void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//给结构体变量赋默认值
  14. void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);//给结构体变量赋参数值
  15. void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);//给输入捕获结构体赋一个初值
  16. void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
  17. void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//使能计数器
  18. void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
  19. void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//使能外设中断输出
  20. void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
  21. void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
  22. void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
  23. /*时基单元时钟选择*/
  24. void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//选择内部时钟
  25. void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
  26. void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
  27. uint16_t TIM_ICPolarity, uint16_t ICFilter);
  28. void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
  29. void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
  30. uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
  31. void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
  32. uint16_t ExtTRGFilter);
  33. void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//可用于单独写预分频值
  34. void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);//改变计数器的计数模式
  35. void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//选择输入触发源TRGI
  36. void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
  37. uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);//定时器编码器接口配置
  38. /*配置强制输出模式*/
  39. void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
  40. void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
  41. void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
  42. void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
  43. void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//自动重装器预装功能配置
  44. void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
  45. void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
  46. void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
  47. /*配置OC预装功能*/
  48. void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
  49. void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
  50. void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
  51. void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
  52. /*配置快速使能*/
  53. void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
  54. void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
  55. void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
  56. void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
  57. /*外部事件时清除REF信号*/
  58. void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
  59. void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
  60. void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
  61. void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
  62. /*单独设置输出比较极性*/
  63. void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
  64. void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
  65. void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
  66. void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
  67. void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
  68. void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
  69. void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
  70. /*单独修改输出使能参数*/
  71. void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
  72. void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
  73. /*选择输出比较模式*/
  74. void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
  75. void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
  76. void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
  77. void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
  78. void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
  79. void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);//选择输出触发源TRGO
  80. void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);//选择从模式
  81. void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
  82. void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//给计数器写入一个计数值
  83. void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);//给自动重装器写入一个值
  84. /*单独更改CCR寄存器的值*/
  85. void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
  86. void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
  87. void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
  88. void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
  89. /*分别单独配置通道1,2,3,4的分频器*/
  90. void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
  91. void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
  92. void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
  93. void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
  94. void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
  95. /*分别读取四个通道的CCR*/
  96. uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
  97. uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
  98. uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
  99. uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
  100. uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//获取当前计数器的值
  101. uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//获取当前的预分频器的值
  102. FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
  103. void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
  104. ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
  105. void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

内部时钟实现定时器定时:

Timer.c:

  1. #include "stm32f10x.h" // Device header
  2. void Timer_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. /*选择时基单元的时钟*/
  7. TIM_InternalClockConfig(TIM2);
  8. /*配置时基单元*/
  9. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  10. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  11. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  12. Tim_InitStructure.TIM_Period=10000-1;//选择周期-ARR值
  13. Tim_InitStructure.TIM_Prescaler=7200-1;//预分频器
  14. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  15. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  16. /*配置输出中断控制,使能更新中断*/
  17. TIM_ClearFlag(TIM2,TIM_FLAG_Update);
  18. TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
  19. /*配置NVIC*/
  20. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  21. NVIC_InitTypeDef NVIC_InitStructure;
  22. NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
  23. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  24. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
  25. NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
  26. NVIC_Init(&NVIC_InitStructure);
  27. /*启动定时器*/
  28. TIM_Cmd(TIM2,ENABLE);
  29. }
  30. /*
  31. 中断函数
  32. void TIM2_IRQHandler(void)
  33. {
  34. if(TIM_GetITStatus(TIM2,TIM_IT_Update) ==SET )
  35. {
  36. TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
  37. }
  38. }*/

 Timer.h:

  1. #ifndef __TIMER_H
  2. #define __TIMER_H
  3. void Timer_Init(void);
  4. #endif

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "Timer.h"
  5. uint16_t Num;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. Timer_Init();
  10. OLED_ShowString(1,1,"Num:");
  11. while(1)
  12. {
  13. OLED_ShowNum(1,5,Num,5);
  14. }
  15. }
  16. /*中断函数*/
  17. void TIM2_IRQHandler(void)
  18. {
  19. if(TIM_GetITStatus(TIM2,TIM_IT_Update) ==SET )
  20. {
  21. Num++;
  22. TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
  23. }
  24. }

 定时器外部时钟:

Timer.c:

  1. #include "stm32f10x.h" // Device header
  2. void Timer_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0111);//通过ETR引脚的外部时钟模式2配置
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=10-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=1-1;//预分频器
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  23. /*配置输出中断控制,使能更新中断*/
  24. TIM_ClearFlag(TIM2,TIM_FLAG_Update);
  25. TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
  26. /*配置NVIC*/
  27. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  28. NVIC_InitTypeDef NVIC_InitStructure;
  29. NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
  30. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  31. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
  32. NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
  33. NVIC_Init(&NVIC_InitStructure);
  34. /*启动定时器*/
  35. TIM_Cmd(TIM2,ENABLE);
  36. }
  37. /*计数器值封装*/
  38. uint16_t Timer_GetCount(void)
  39. {
  40. return TIM_GetCounter(TIM2);
  41. }
  42. /*
  43. 中断函数
  44. void TIM2_IRQHandler(void)
  45. {
  46. if(TIM_GetITStatus(TIM2,TIM_IT_Update) ==SET )
  47. {
  48. TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
  49. }
  50. }*/

 Timer.h:

  1. #ifndef __TIMER_H
  2. #define __TIMER_H
  3. void Timer_Init(void);
  4. uint16_t Timer_GetCount(void);
  5. #endif

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "Timer.h"
  5. uint16_t Num;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. Timer_Init();
  10. OLED_ShowString(1,1,"Num:");
  11. OLED_ShowString(2,1,"CNT:");
  12. while(1)
  13. {
  14. OLED_ShowNum(1,5,Num,5);
  15. OLED_ShowNum(2,5,Timer_GetCount(),5);
  16. }
  17. }
  18. /*中断函数*/
  19. void TIM2_IRQHandler(void)
  20. {
  21. if(TIM_GetITStatus(TIM2,TIM_IT_Update) ==SET )
  22. {
  23. Num++;
  24. TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
  25. }
  26. }

 6.5 TIM输出比较

6.5.1 输出比较简介

OC(Output Compare)输出比较

输出比较可以通过比较CNT(时基单元计数器)与CCR寄存器(捕获/比较寄存器)值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形

每个高级定时器和通用定时器都拥有4个输出比较通道

高级定时器的前3个通道额外拥有死区生成和互补输出的功能

6.5.2 PWM简介

PWM(Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域。使用PWM波形等效实现模拟信号的输出。

PWM参数:      频率 = 1 / TS            占空比 = TON / TS           分辨率 = 占空比变化步距

通用定时器的输出比较电路:

输出比较模式:

PWM的基本结构:

 通过上图,PWM进行初始化可分为以下几步:

1、RCC开启时钟。

2、配置时基单元。

3、配置输出比较单元。

4、配置GPIO。

5、运行控制,启动计数器。

PWM的参数计算:

 上图中,蓝色:CNT,黄色:ARR,红色:CCR

PWM的频率=计数器的更新频率

PWM的占空比=30/100=30%

6.5.3 舵机简介

舵机是一种根据输入PWM信号占空比来控制输出角度的装置

输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms

6.5.4 直流电机及驱动介绍

直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转

直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作

TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向

电机驱动电路的电路图如下:

通过控制IN1,IN2两个引脚的电平,能够控制电机是正转还是反转。 

6.6 代码实现TIM功能

PWM驱动LED呼吸灯:

PWM.c:

  1. #include "stm32f10x.h" // Device header
  2. void PWM_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM2);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=100-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=720-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  23. /*配置输出比较单元*/
  24. TIM_OCInitTypeDef TIM_OCInitStructure;
  25. TIM_OCStructInit(&TIM_OCInitStructure);//给结构体成员赋初始值
  26. TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较模式
  27. TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//输出比较极性
  28. TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态
  29. TIM_OCInitStructure.TIM_Pulse=0;//设置CCR寄存器的值
  30. TIM_OC2Init(TIM2,&TIM_OCInitStructure);
  31. /*启动定时器*/
  32. TIM_Cmd(TIM2,ENABLE);
  33. }
  34. /*封装设定CCR值函数*/
  35. void PWM_SetCompare2(uint16_t Compare)
  36. {
  37. TIM_SetCompare2(TIM2,Compare);
  38. }

PWM.h:

  1. #ifndef __PWM_H
  2. #define __PWM_H
  3. void PWM_Init(void);
  4. void PWM_SetCompare2(uint16_t Compare);
  5. #endif

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "PWM.h"
  5. uint8_t i;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. PWM_Init();
  10. while(1)
  11. {
  12. for(i=0;i<=100;i++)
  13. {
  14. PWM_SetCompare2(i);
  15. Delay_ms(10);
  16. }
  17. for(i=0;i<=100;i++)
  18. {
  19. PWM_SetCompare2(100-i);
  20. Delay_ms(10);
  21. }
  22. }
  23. }

按键控制舵机:

Servo.c:

  1. #include "stm32f10x.h" // Device header
  2. #include "PWM.h"
  3. void Servo_Init(void)
  4. {
  5. PWM_Init();
  6. }
  7. /*舵机的设定角度函数
  8. 0 500
  9. 180 2500
  10. */
  11. void Servo_SetAngle(float Angle)
  12. {
  13. PWM_SetCompare2(Angle/180*2000+500);
  14. }

Servo.h:

  1. #ifndef __SERVO_H
  2. #define __SERVO_H
  3. void Servo_Init(void);
  4. void Servo_SetAngle(float Angle);
  5. #endif

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "Servo.h"
  5. #include "Key.h"
  6. uint8_t KeyNum;
  7. float Angle;
  8. int main(void)
  9. {
  10. OLED_Init();
  11. Servo_Init();
  12. Key_Init();
  13. OLED_ShowString(1,1,"Angle:");
  14. while(1)
  15. {
  16. KeyNum=Key_GetNum();
  17. if(KeyNum == 1)
  18. {
  19. Angle+=30;
  20. if(Angle>180)
  21. {
  22. Angle=0;
  23. }
  24. }
  25. Servo_SetAngle(Angle);
  26. OLED_ShowNum(1,7,Angle,3);
  27. }
  28. }

按键控制直流电机:

Motor.c:

  1. #include "stm32f10x.h" // Device header
  2. #include "PWM.h"
  3. void Motor_Init(void)
  4. {
  5. /*初始化电机方向控制脚*/
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  9. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
  10. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOA,&GPIO_InitStructure);
  12. PWM_Init();
  13. }
  14. void Motor_SetSpeed(int8_t Speed)
  15. {
  16. if(Speed>=0)
  17. {
  18. GPIO_SetBits(GPIOA,GPIO_Pin_4);
  19. GPIO_ResetBits(GPIOA,GPIO_Pin_5);
  20. PWM_SetCompare2(Speed);
  21. }
  22. else
  23. {
  24. GPIO_SetBits(GPIOA,GPIO_Pin_5);
  25. GPIO_ResetBits(GPIOA,GPIO_Pin_4);
  26. PWM_SetCompare2(-Speed);
  27. }
  28. }

motor.h:

  1. #ifndef __MOTOR_H
  2. #define __MOTOR_H
  3. void Motor_Init(void);
  4. void Motor_SetSpeed(int8_t Speed);
  5. #endif

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "MOTOR.h"
  5. #include "Key.h"
  6. uint8_t KeyNum;
  7. int8_t Speed;
  8. int main(void)
  9. {
  10. OLED_Init();
  11. Motor_Init();
  12. Key_Init();
  13. OLED_ShowString(1,1,"Speed:");
  14. while(1)
  15. {
  16. KeyNum=Key_GetNum();
  17. if(KeyNum == 1)
  18. {
  19. Speed+=20;
  20. if(Speed>100)
  21. {
  22. Speed=-100;
  23. }
  24. }
  25. Motor_SetSpeed(Speed);
  26. OLED_ShowSignedNum(1,7,Speed,3);
  27. }
  28. }

6.7 TIM输入捕获

IC(Input Capture)输入捕获

输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中(将当前CNT的值读出并写入到CCR中),可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数

每个高级定时器和通用定时器都拥有4个输入捕获通道

可配置为PWMI模式,同时测量频率和占空比

可配合主从触发模式,实现硬件全自动测量

频率测量

测频法:在闸门时间T内,对上升沿计次,得到N,则频率

f_x=N / T

测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率

f_x=f_c / N

中界频率:测频法与测周法误差相等的频率点

f_m=√(f_c / T)

输入捕获的基本结构:

其中的CNT,就是测周法中用来计数计时的参数。

根据上图,配置输入捕获的步骤为:

1、RCC开启时钟,将GPIO和TIM的时钟都打开。

2、GPIO初始化,将GPIO配置为输入模式。

3、配置时基单元,让CNT计数器在内部时钟的驱动下自增运行。

4、配置输入捕获单元。

5、选择从模式的触发源。

6、选择触发后执行的操作。

7、调用TIM_Cmd函数,开启定时器。

输入捕获模式测频率代码:

PWM.c:

  1. #include "stm32f10x.h" // Device header
  2. void PWM_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM2);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=100-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=720-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  23. /*配置输出比较单元*/
  24. TIM_OCInitTypeDef TIM_OCInitStructure;
  25. TIM_OCStructInit(&TIM_OCInitStructure);//给结构体成员赋初始值
  26. TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较模式
  27. TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//输出比较极性
  28. TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态
  29. TIM_OCInitStructure.TIM_Pulse=0;//设置CCR寄存器的值
  30. TIM_OC1Init(TIM2,&TIM_OCInitStructure);
  31. /*启动定时器*/
  32. TIM_Cmd(TIM2,ENABLE);
  33. }
  34. /*封装设定CCR值函数*/
  35. void PWM_SetCompare1(uint16_t Compare)
  36. {
  37. TIM_SetCompare1(TIM2,Compare);
  38. }
  39. /*封装设定PSC值函数*/
  40. void PWM_SetPrescaler(uint16_t Prescaler)
  41. {
  42. TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Update);
  43. }

IC.c:

  1. #include "stm32f10x.h" // Device header
  2. void IC_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOB,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM4);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=65536-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=72-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM4,&Tim_InitStructure);
  23. /*初始化输入捕获单元*/
  24. TIM_ICInitTypeDef TIM_InitStructure;
  25. TIM_InitStructure.TIM_Channel=TIM_Channel_1;//选择通道
  26. TIM_InitStructure.TIM_ICFilter=1111;//配置输入捕获滤波器
  27. TIM_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//配置极性
  28. TIM_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//配置分频器
  29. TIM_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//选择触发信号从哪个引脚输入
  30. TIM_ICInit(TIM4,&TIM_InitStructure);
  31. /*配置TRGI的触发源为TI1FP1*/
  32. TIM_SelectInputTrigger(TIM4,TIM_TS_TI1FP1);
  33. /*配置从模式为Reset*/
  34. TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset);
  35. /*调用TIM_Cmd函数*/
  36. TIM_Cmd(TIM4,ENABLE);
  37. }
  38. /*读取频率函数*/
  39. uint32_t IC_GetFreq(void)
  40. {
  41. return 1000000/(TIM_GetCapture1(TIM4)+1);
  42. }

main函数:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "Delay.h"
  4. #include "PWM.h"
  5. #include "IC.h"
  6. int main(void)
  7. {
  8. OLED_Init();
  9. PWM_Init();
  10. IC_Init();
  11. OLED_ShowString(1,1,"Freq:00000Hz");
  12. PWM_SetPrescaler(720-1); //Freq = 72M / (PSC+1) / (ARR+1)
  13. PWM_SetCompare1(50); //Duty = CCR /100
  14. while(1)
  15. {
  16. OLED_ShowNum(1,6,IC_GetFreq(),5);
  17. }
  18. }

PWMI的基本结构:

与上图相比,多了一个分频器以及另一个捕获/比较器。具体的工作原理是:当出现上升沿电平时,CCR1开始计数,同时CNT清零。而加入了CCR2后,当电平由高转低时,CCR2捕获CNT的值,此时,CCR2的值就是高电平时CNT的值,而当到达下一个周期时,CCR1捕获CNT的值,那么CCR1的值就是一个周期内的值,那么CCR2/CCR1就是占空比。

根据上图,配置PWMI的步骤为:

1、RCC开启时钟,将GPIO和TIM的时钟都打开。

2、GPIO初始化,将GPIO配置为输入模式。

3、配置时基单元,让CNT计数器在内部时钟的驱动下自增运行。

4、配置输入捕获初始化为两个通道同时捕获同一引脚模式

PWMI模式测频率占空比:

IC.c:

  1. #include "stm32f10x.h" // Device header
  2. void IC_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOB,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM4);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=65536-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=72-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM4,&Tim_InitStructure);
  23. /*初始化输入捕获单元*/
  24. TIM_ICInitTypeDef TIM_InitStructure;
  25. TIM_InitStructure.TIM_Channel=TIM_Channel_1;//选择通道
  26. TIM_InitStructure.TIM_ICFilter=1111;//配置输入捕获滤波器
  27. TIM_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//配置极性
  28. TIM_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//配置分频器
  29. TIM_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//选择触发信号从哪个引脚输入
  30. TIM_PWMIConfig(TIM4,&TIM_InitStructure);//自动将剩下的通道初始化为相反的配置
  31. /*配置TRGI的触发源为TI1FP1*/
  32. TIM_SelectInputTrigger(TIM4,TIM_TS_TI1FP1);
  33. /*配置从模式为Reset*/
  34. TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset);
  35. /*调用TIM_Cmd函数*/
  36. TIM_Cmd(TIM4,ENABLE);
  37. }
  38. /*读取频率函数*/
  39. uint32_t IC_GetFreq(void)
  40. {
  41. return 1000000/(TIM_GetCapture1(TIM4)+1);
  42. }
  43. /*获取占空比函数*/
  44. uint32_t IC_GetDuty(void)
  45. {
  46. return (TIM_GetCapture2(TIM4)+1) * 100 / (TIM_GetCapture1(TIM4)+1);
  47. }

PWM.c:

  1. #include "stm32f10x.h" // Device header
  2. void PWM_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM2);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=100-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=720-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  23. /*配置输出比较单元*/
  24. TIM_OCInitTypeDef TIM_OCInitStructure;
  25. TIM_OCStructInit(&TIM_OCInitStructure);//给结构体成员赋初始值
  26. TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较模式
  27. TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//输出比较极性
  28. TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态
  29. TIM_OCInitStructure.TIM_Pulse=0;//设置CCR寄存器的值
  30. TIM_OC1Init(TIM2,&TIM_OCInitStructure);
  31. /*启动定时器*/
  32. TIM_Cmd(TIM2,ENABLE);
  33. }
  34. /*封装设定CCR值函数*/
  35. void PWM_SetCompare1(uint16_t Compare)
  36. {
  37. TIM_SetCompare1(TIM2,Compare);
  38. }
  39. /*封装设定PSC值函数*/
  40. void PWM_SetPrescaler(uint16_t Prescaler)
  41. {
  42. TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Update);
  43. }

main函数:

  1. #include "stm32f10x.h" // Device header
  2. void PWM_Init(void)
  3. {
  4. /*RCC开启时钟*/
  5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  7. /*配置GPIO*/
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//只有选择复用推挽输出,引脚的控制权才能转交给片上外设
  10. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_Init(GPIOA,&GPIO_InitStructure);
  13. /*选择时基单元的时钟*/
  14. TIM_InternalClockConfig(TIM2);
  15. /*配置时基单元*/
  16. TIM_TimeBaseInitTypeDef Tim_InitStructure;
  17. Tim_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
  18. Tim_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择计数模式-向上计数
  19. Tim_InitStructure.TIM_Period=100-1;//选择周期-ARR值
  20. Tim_InitStructure.TIM_Prescaler=720-1;//预分频器-PSC值
  21. Tim_InitStructure.TIM_RepetitionCounter=0;//重复计数器-高级定时器专用
  22. TIM_TimeBaseInit(TIM2,&Tim_InitStructure);
  23. /*配置输出比较单元*/
  24. TIM_OCInitTypeDef TIM_OCInitStructure;
  25. TIM_OCStructInit(&TIM_OCInitStructure);//给结构体成员赋初始值
  26. TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较模式
  27. TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//输出比较极性
  28. TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//输出状态
  29. TIM_OCInitStructure.TIM_Pulse=0;//设置CCR寄存器的值
  30. TIM_OC1Init(TIM2,&TIM_OCInitStructure);
  31. /*启动定时器*/
  32. TIM_Cmd(TIM2,ENABLE);
  33. }
  34. /*封装设定CCR值函数*/
  35. void PWM_SetCompare1(uint16_t Compare)
  36. {
  37. TIM_SetCompare1(TIM2,Compare);
  38. }
  39. /*封装设定PSC值函数*/
  40. void PWM_SetPrescaler(uint16_t Prescaler)
  41. {
  42. TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Update);
  43. }

6.8 TIM编码器接口

Encoder Interface 编码器接口

编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度

每个高级定时器和通用定时器都拥有1个编码器接口

两个输入引脚借用了输入捕获的通道1和通道2

编码器接口的基本结构:

由上图,编码器接口初始化可分为以下几步:

1、RCC开启时钟。

2、配置GPIO。

3.配置时基单元。

4、配置输入捕获单元。

5、配置编码器接口模式。

6.调用TIM_Cmd函数启动定时器。

 编码器接口的工作模式:

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号