1.18 Cubemx_STM32F4 TIM(四)----输出比较(步进电机)

一、原理

计数器的值到达CCRx_1设置值时,电平会进行一次翻转。而后进入中断,输出比较回调函数函数HAL_TIM_OC_DelayElapsedCallback。如果在回调函数里重新设值CCRx_2,那么进行到达CCRx_2电平再次翻转。

二、配置

1.18 Cubemx_STM32F4 TIM(四)----输出比较(步进电机)_第1张图片

1.18 Cubemx_STM32F4 TIM(四)----输出比较(步进电机)_第2张图片
计数器时钟频率CK_CNT=fck_psc/(PSC[15:0]+1)
16位分频器设置位84-1,分频后计数器时钟频率位1MHZ,周期1uS

TIM_OCMode_Toggle TIM输出比较触发模式
翻转––TIMx_CNT=TIMx_CCR1 时,OC1REF 发生翻转。至于跟PWM模式的区别见总结篇

1.18 Cubemx_STM32F4 TIM(四)----输出比较(步进电机)_第3张图片

三、代码

keil ver. V5.29.0.0
cubemx ver. v5.6.0
firmware ver. FW_F4 V1.25.1

file_name: ALIENTEK_PWM
pin discreble: CLK 84M


PH3 | KEY0 |
PH2 | KEY1 |
PC13 | KEY2 |
PA0 | KEY_UP |
PB1 | TIM3_CH4 | √ (脉冲)STEP
PB0 | LED1 | 电机方向
PA10 | USART1_RX |
PA9 | USART1_TX |


bsp_ocompare.c

#include "bsp_ocompare.h"

/*全局变量*/
uint8_t dir = 0;//0:顺时钟   1:逆时钟
uint8_t ena = 0;//0:正常运行 1:停机
uint32_t Toggle_Pulse=500;

__IO uint32_t pulse_count=0;/*脉冲计数,一个完整的脉冲会增加2*/

//定时器比较输出中断回调函数,在定时器计数值与捕获比较寄存器值相等时发送中断,就会调用该函数
输出比较回调,进入中断后翻转,重新设置下一次翻转值,脉冲周期位T=2*Toggle_Pulse
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
     
	__IO uint16_t count;
	count = __HAL_TIM_GET_COUNTER(&htim3);
	__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,count+Toggle_Pulse);
	pulse_count++;
}

void bsp_InitOcompare(void)
{
     
		/*初始化设置了通道的脉冲数位Toggle_Pluse,启动定时器后计数器达到Toggle_Pulse,产生中断翻转通道引脚*/
	__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,Toggle_Pulse);
	
	HAL_TIM_Base_Start(&htim3);
	HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_4);//启动比较输出使能中断
	
}

bsp_ocompare.h

#ifndef _BSP_OCOMPARE_H
#define _BSP_OCOMPARE_H

#include "stm32f4xx_hal.h"
#include "main.h"
#include "pub_gpio.h"
#include "tim.h"
#include "bsp_led.h"


/*宏定义*/
//STEPMOTOR_OUTPUT_DISABLE() HAL_GPIO_WritePin(STEPMOTOR_ENA_PORT,STEPMOTOR_ENA_PIN,GPIO_SET);
//STEPMOTOR_OUTPUT_DISABLE() HAL_GPIO_WritePin(STEPMOTOR_ENA_PORT,STEPMOTOR_ENA_PIN,GPIO_RESET);

#define STEPMOTOR_DIR_REVERSAL()  LED1_OFF() //翻转
#define STEPMOTOR_DIR_FORWARDL()  LED1_ON()  //正转
#define STEPMOTOR_MICRO_STEP 32 //步进电机驱动器细分,必须与驱动器实际设置对应

extern  uint32_t Toggle_Pulse;
extern	uint8_t dir;//0:顺时钟   1:逆时钟
extern	uint8_t ena;//0:正常运行 1:停机
extern	__IO uint32_t pulse_count;/*脉冲计数,一个完整的脉冲会增加2*/
void bsp_InitOcompare(void);

#endif

main函数

void main_task (void * arg) 
{
     
	uint8_t ucKeyCode;

	 while(1)
	{
     	
		ucKeyCode = bsp_GetKey(); 
		if (ucKeyCode != KEY_NONE)
		{
     
			switch (ucKeyCode)	
			{
     
				/* K1键按下,打印调试说明 */
				case KEY_DOWN_K0:/*功能选择*/
					printf("K1键按下\r\n");
					key1_count++;
					if(key1_count == 5)
						key1_count = 1;
					break;
					
				case KEY_UP_K0:
					printf("K1键松开\r\n");
					break;
				case KEY_LONG_K0:
					printf("K1键长按\r\n");
					break;
				
				case KEY_DOWN_K1://功能调节
					printf("K2键按下\r\n");
					switch(key1_count)
					{
     
						case 1://加速
							Toggle_Pulse -=50;
							if( Toggle_Pulse<300 )
								Toggle_Pulse = 300;
							break;
						case 2://减速
							Toggle_Pulse +=100;
							if(Toggle_Pulse >3500 )
								Toggle_Pulse = 3500;
							break;
						case 3:		//方向控制
							if(dir == 0)
							{
     
								STEPMOTOR_DIR_REVERSAL(); //反转
								dir = 1;
							}
							else
							{
     
								STEPMOTOR_DIR_FORWARDL();// 正转
								dir = 0;
							}
						  break;
						case 4:
							if(ena == 0)
							{
     
//								STEPMOTOR_OUTPUT_ENABLE();
								ena=1;
							}
							else
							{
     
								pulse_count=0;
//								STEPMOTOR_OUTPUT_DISABLE();
							}
							break;
						default:
							break;
					}
					break;
				case KEY_UP_K1:
					printf("K2键松开\r\n");
					break;
				case KEY_LONG_K1:
					printf("K2键长按\r\n");
					break;
				
				case KEY_DOWN_K2:
					printf("K3键按下\r\n");
					break;
				case KEY_UP_K2:
					printf("K3键松开\r\n");
					break;
				case KEY_LONG_K2:
					printf("K3键长按\r\n");
					break;
				
				case KEY_DOWN_K3:
					printf("K4键按下\r\n");
					break;
				case KEY_UP_K3:
					printf("K4键松开\r\n");
					break;
				case KEY_LONG_K3:
					printf("K4键长按\r\n");
					break;
				
				case SYS_DOWN_K0K2:
					printf("K0K2键按下\r\n");
					break;
				case SYS_UP_K0K2:
					printf("K0K2键松开\r\n");
					break;
				case SYS_LONG_K0K2:
					printf("K0K2键长按\r\n");
					break;
				
				case SYS_DOWN_K1K3:
					printf("K1K3键按下\r\n");
					break;
				case SYS_UP_K1K3:
					printf("K1K3键松开\r\n");
					break;
				case SYS_LONG_K1K3:
					printf("K1K3键长按\r\n");
					break;
				default:
					break;
			}	
		}
		if(pulse_count == STEPMOTOR_MICRO_STEP*200*2*10)//转10圈后停止  一圈200步
//		STEPMOTOR_OUTPUT_DISABLE();
		
		osThreadYield();
	}
}

你可能感兴趣的:(Cubemx,stm32,嵌入式,time)