#include "bsp_TB6600_TIM.h"
//频率 8细分，转一周要1600个脉冲 pwm周期是：prescaler*2 us
//频率计算公式：如果每分钟N转,每秒钟=N/60 r/s
//N/60需要的脉冲数：N/60*1600个，即频率就是：N/60*1600
//如：现在测试300r/min,频率就是8000，周期就是125us，prescaler=125/2/0.5=125
__IO uint16_t prescaler=125;
static void TB6600_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 使能定时器通道引脚GPIO时钟 */
  TB6600_TIM_GPIO_APBxClock_FUN(TB6600_TIM_GPIO_CLK, ENABLE); 
  RCC_APB2PeriphClockCmd(TB6600_DIR_GPIO_CLK|TB6600_ENA_GPIO_CLK,ENABLE);
  //配置定时器通道1输出引脚模式：复用推挽输出
  GPIO_InitStructure.GPIO_Pin =  TB6600_TIM_CH1_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(TB6600_TIM_CH1_PORT, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin =  TB6600_DIR_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(TB6600_DIR_PORT, &GPIO_InitStructure);
  GPIO_ResetBits(TB6600_DIR_PORT,TB6600_DIR_PIN);
  
  GPIO_InitStructure.GPIO_Pin =  TB6600_ENA_PIN;
  GPIO_Init(TB6600_ENA_PORT, &GPIO_InitStructure);
  GPIO_ResetBits(TB6600_ENA_PORT,TB6600_ENA_PIN);
}
static void TB6600_TIMx_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;	//定义相关结构体
	TIM_OCInitTypeDef  TIM_OCInitStructure;  
  NVIC_InitTypeDef NVIC_InitStructure;
	TB6600_TIM_APBxClock_FUN (TB6600_TIM_CLK, ENABLE); //时钟使能
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //NVIC中断向量配置
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;  //比较中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;   //设置抢占式优先级为2 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;  //设置子优先级为3 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	  //使能外部中断通道 
  NVIC_Init(&NVIC_InitStructure);   //初始化配置嵌套向量中断控制器 
  //定时器基本参数设置	 
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //计数时尽可能最大
  TIM_TimeBaseStructure.TIM_Prescaler =35;   //(35+1)/72MHz=0.5us计数一次
  TIM_TimeBaseStructure.TIM_RepetitionCounter=0;//重复计数，重复多少次溢出来一次中断，必须配置，如果不配置上电的随机的，一般配置为0，如果要脉冲周期很大，可以配置不为0
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置时钟分频系数：不分频(这里用不到) 
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
  TIM_TimeBaseInit(TB6600_TIMx, &TIM_TimeBaseStructure);
  //定时器输出通道1模式配置 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;  //模式配置：输出比较模式
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    // 输出状态设置：使能输出 
  TIM_OCInitStructure.TIM_Pulse = prescaler;//设置跳变值，当计数器计数到这个值时，电平发生跳变 ，以此来产生占空比为百分之五十的pwm
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM输出比较极性高
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;//空闲时输出高(高级定时器才有的，通用定时器不用配置)
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//空闲时互补输出低
  //初始化定时器通道1输出PWM 
  TIM_OC1Init(TB6600_TIMx, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TB6600_TIMx, TIM_OCPreload_Disable); //定时器比较输出通道1预装载配置：禁止预装载。否侧计数到65535会重装载65535，这个在pwm模式下要使能
  TIM_ITConfig(TB6600_TIMx,TIM_IT_CC1,ENABLE);     //中断使能
  TIM_Cmd(TB6600_TIMx, ENABLE);//使能定时器 
 // TIM_CtrlPWMOutputs(TB6600_TIMx, ENABLE);//TIM主输出使能,相当于PWM输出总开关，只有它有效，pwm才会输出，这个功能只有在高级定时器才会有操作TIM->BDTR[MOE]这个寄存器
 TIM1->BDTR=TIM1->BDTR&0x3fff;
 TIM1->BDTR=TIM1->BDTR|0x8000;

}
void TB6600_TIMx_PWM_Init(void)
{
	TB6600_GPIO_Config();
	TB6600_TIMx_Configuration();	
}
//定时比较中断服务函数 
void TIM1_CC_IRQHandler(void)
{
  if(TIM_GetITStatus(TB6600_TIMx,TIM_IT_CC1)!=RESET)//判断中断标志
  {
    TIM_ClearITPendingBit(TB6600_TIMx,TIM_IT_CC1);//清除中断标志
    TIM_SetCounter(TB6600_TIMx,0);                //计数器清零，重新计数，否则每次会叠加，到了65535后有从0计数，频率就会不断改变
    TIM_SetCompare1(TB6600_TIMx,prescaler);				//重新赋值比较值，以此改变频率
  }
}

