32F4 tim8 toggle stepcontrol diy

stepper.h

#ifndef __STEPMOTOR_H 
#define __STEPMOTOR_H 

#include "sys.h" 
#include "stm32f4xx_tim.h" 
//使用定时器8 C6、C7/C8/C9
//端口定义 

#define STEPMOTOR1_DIR PGout(5)  // DS0 
#define STEPMOTOR1_ENA PGout(6)// DS1   
 
/*---------------------- 配置宏 ------------------------*/

#define STEPMOTOR1_DIR_PIN           GPIO_Pin_5       		 // KEY 引脚      
#define STEPMOTOR1_DIR_PORT          GPIOG                    // KEY GPIO端口     
#define STEPMOTOR1_DIR_CLK           RCC_AHB1Periph_GPIOG	    // KEY GPIO端口时钟
#define STEPMOTOR1_DIR_CLK_ENA()    {RCC_AHB1PeriphClockCmd( STEPMOTOR1_DIR_CLK ,ENABLE);}//根据实际修改:时钟线,时钟使能

#define STEPMOTOR1_ENA_PIN           GPIO_Pin_6       		 // KEY 引脚      
#define STEPMOTOR1_ENA_PORT          GPIOG                    // KEY GPIO端口     
#define STEPMOTOR1_ENA_CLK           RCC_AHB1Periph_GPIOG	    // KEY GPIO端口时钟
#define STEPMOTOR1_ENA_CLK_ENA()    {RCC_AHB1PeriphClockCmd( STEPMOTOR1_ENA_CLK ,ENABLE);}//根据实际修改:时钟线,时钟使能

#define CW 0  //正转
#define CCW 1 //反转
extern u32 Toggle_Pulse[4];


void stepmotor1234_gpio_Init(void);//初始化  
void stepmotor1234_timer8_Init(u32 arr,u32 psc);//初始化 
#endif 

stepper.c


#include "stepmotor.h" 


u32 Toggle_Pulse[4]={900,500,500,500};   


void stepmotor1234_gpio_Init(void)//初始化 
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
	
	STEPMOTOR1_DIR_CLK_ENA(); 	//初始化KEY时钟	
	GPIO_InitStructure.GPIO_Pin   = STEPMOTOR1_DIR_PIN;	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz 
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
	GPIO_Init(STEPMOTOR1_DIR_PORT, &GPIO_InitStructure);	
	
	
		
	STEPMOTOR1_ENA_CLK_ENA(); 	//初始化KEY时钟	
	GPIO_InitStructure.GPIO_Pin   = STEPMOTOR1_ENA_PIN;	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz 
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
	GPIO_Init(STEPMOTOR1_ENA_PORT, &GPIO_InitStructure);	
	
	
}


//(1)    TIM_OCMode:比较输出模式选择,总共有八种,常用的为PWM1/PWM2。它设定CCMRx寄存器OCxM[2:0]位的值。

//(2)    TIM_OutputState:比较输出使能,决定最终的输出比较信号OCx是否通过外部引脚输出。它设定TIMx_CCER寄存器CCxE/CCxNE位的值。

//(3)    TIM_OutputNState:比较互补输出使能,决定OCx的互补信号OCxN是否通过外部引脚输出。它设定CCER寄存器CCxNE位的值。

//(4)    TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器CCR的值,决定脉冲宽度。可设置范围为0至65535。

//(5)    TIM_OCPolarity:比较输出极性,可选OCx为高电平有效或低电平有效。它决定着定时器通道有效电平。它设定CCER寄存器的CCxP位的值。

//(6)    TIM_OCNPolarity:比较互补输出极性,可选OCxN为高电平有效或低电平有效。它设定TIMx_CCER寄存器的CCxNP位的值。

//(7)    TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出1或输出0,即在空闲状态(BDTR_MOE位为0)时,经过死区时间后定时器通道输出高电平或低电平。它设定CR2寄存器的OISx位的值。

//(8)    TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出1或输出0,即在空闲状态(BDTR_MOE位为0)时,经过死区时间后定时器互补通道输出高电平或低电平,
//设定值必须与TIM_OCIdleState相反。它设定是CR2寄存器的OISxN位的

void stepmotor1234_timer8_Init(u32 arr,u32 psc)//初始化 
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);  	//TIM1时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 	//使能PORTA时钟	
	
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8); //GPIOA8复用为定时器1
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //GPIOA8复用为定时器1
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8); //GPIOA8复用为定时器1
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8); //GPIOA8复用为定时器1

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 |GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;           //GPIOA8--
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;        //上拉  GPIO_PuPd_DOWN;      //下拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);              //初始化PA8
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频0
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值  65535最大值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //    ((uint16_t)0x0000)
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;  //20201020
	TIM_TimeBaseInit(TIM8,&TIM_TimeBaseStructure);//初始化定时器8
	
//-------------------
//选择定时器模式

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	//输出极性:TIM输出比较极性低TIM_OCPolarity_High
	TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High; 
	TIM_OCInitStructure.TIM_OCNPolarity= TIM_OCNPolarity_Low;
 
 // TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出1或输出0
	 TIM_OCInitStructure.TIM_OCIdleState=  TIM_OCIdleState_Reset ;//      ((uint16_t)0x0000) 
		TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Set;//((uint16_t)0x0000)
	
	 
		TIM_OCInitStructure.TIM_Pulse        =Toggle_Pulse[0];
	 	TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Enable; //比较输出使能
	  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//	
	 	TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1
		TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Disable);  
		//禁止使能TIM1在CCR1上的预装载寄存器
    TIM_OC1FastConfig(TIM8,  TIM_OCFast_Disable); 
		
		
	 	TIM_OCInitStructure.TIM_Pulse=Toggle_Pulse[1];
	 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//	
	 	TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1
		TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Disable);  //使能TIM1在CCR1上的预装载寄存器
 
//	 
	 	TIM_OCInitStructure.TIM_Pulse=Toggle_Pulse[2];
	 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//	
	 	TIM_OC3Init(TIM8, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1
		TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Disable);  //使能TIM1在CCR1上的预装载寄存器
 
	 
	 	TIM_OCInitStructure.TIM_Pulse=Toggle_Pulse[3];
	 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//	
	 	TIM_OC4Init(TIM8, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1
		TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Disable);  //使能TIM1在CCR1上的预装载寄存器
// 
//	 不对定时器做任何分频,并且让它满计数,即计数周期为65535。接下去再设置个
//	 通道的的工作模式为输出比较翻转模式,设置通道1的比较值为CCR1_Val、CCR3_Val、CCR3_Val、CCR4_Val,
//	 它们的值在OCToggle.h中定义。然后打开个通道的输出比较事件的中断。最后在打开定时器。这样的话,
//	 定时器这段就配置完成了。
  //主函数NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	    NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;  //TIM8中断
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级1级
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级1级
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
      NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
			 
			 TIM_ARRPreloadConfig(TIM8,DISABLE);//ARPE使能 
			TIM_ClearITPendingBit(TIM8, TIM_IT_CC1);//清除标志位TIM_IT_CC1

	 TIM_ITConfig(TIM8, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);//中断标志
  TIM_Cmd(TIM8, ENABLE);//打开定时器8,

	TIM_CtrlPWMOutputs(TIM8, ENABLE);    //20201020


}


void TIM8_CC_IRQHandler(void)
{
   

		static u16 capture = 0;
		if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET)//通道1检测到比较事件
		{
			STEPMOTOR1_DIR=!STEPMOTOR1_DIR;
			TIM_ClearITPendingBit(TIM8, TIM_IT_CC1);//清除标志位TIM_IT_CC1
			capture = TIM_GetCapture1(TIM8);
			TIM_SetCompare1(TIM8, capture + Toggle_Pulse[0]);//重新设置比较值
		}
		
		if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET)//通道1检测到比较事件
		{
			TIM_ClearITPendingBit(TIM8, TIM_IT_CC2);//清除标志位
			STEPMOTOR1_ENA=!STEPMOTOR1_ENA;
			capture = TIM_GetCapture2(TIM8);
			TIM_SetCompare2(TIM8, capture + Toggle_Pulse[1]);//重新设置比较值
		}
		
		if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET)//通道1检测到比较事件
		{
			TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);//清除标志位
			capture = TIM_GetCapture3(TIM8);
			TIM_SetCompare3(TIM8, capture + Toggle_Pulse[2]);//重新设置比较值
		}
		
		if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET)//通道1检测到比较事件
		{
			TIM_ClearITPendingBit(TIM8, TIM_IT_CC4);//清除标志位
			capture = TIM_GetCapture4(TIM8);
			TIM_SetCompare4(TIM8, capture + Toggle_Pulse[3]);//重新设置比较值
		}
				
  
}



main.c

#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "oled.h"
#include "key.h"
#include "EXTI.h"
#include "timer.h"
#include "pwm.h"
#include "dcmotor.h"
#include "linesensor.h"
#include "stepmotor.h" 

extern u32 Toggle_Pulse[4];

//全局变量,存储按键键码
u8 GLOKEYVAL=0;
u8 pwmflag=0;
u8 pwmaddsubflag=0;

int main(void)
{
	int shuzi=987;
	u8 keyval=0;
	float aa=123.456;
	float vvtemp=0.2;
	delay_init(168); 
  //LED_Init();
	OLED_Init();
	TIMER14_CH1_PWM1_Init(500-1,84-1);//初始化  2khz F9
	
	KEY_Init();
	//EXTIX_Init();
	TIMER13_Init(200-1,8400-1);
	//定时器时钟 84M,分频系数 8400,所以 84M/8400=10Khz ===0.1MS
  //的计数频率,计数 5000 次为 500ms   
	// TIM1_PWM_Init(500-1,84-1);//1US*500=500US====实际250us  300/500=0.6

	delay_ms(30);
	OLED_Clear();
	LineSensor_Init();
	TIM1_PWM_Init(600-1,84-1);
	 DCMotor1Init();
	  DCMotor2Init();
		 DCMotor3Init();
		  DCMotor4Init();
	TIM_Cmd(TIM13,ENABLE);
	TIM_Cmd(TIM14, DISABLE);
	
	Toggle_Pulse[0]=100;
		Toggle_Pulse[1]=1000;
	stepmotor1234_gpio_Init();
	stepmotor1234_timer8_Init(65535,168-1);//
	//168分频,168MHz/168=1Mhz,1us计算一次,那么计算Toggle_Pulse[0]=100次,100*1us=100us
	//反转一次电平。那么得到周期是100+100=200us
	
		
	while(1)
	{

		
			
	} 
}


		

在这里插入图片描述
在这里插入图片描述

注意,高级定时器挂在APB2总线上;是168M时钟;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值