PSC=2,则定时器T4的时钟是84M/(2+1)=28M,计数的心跳时基=1/28M=0.036us。
PSC=83,则定时器,84M/(83+1)=1M,心跳时基=1us,
最大计数65535.。。。这里用定时器T4的B6,B7,B8,B9,四个通道产生PWM。
__IO uint16_t Tim4CCR1_Val;
__IO uint16_t Tim4CCR2_Val;
__IO uint16_t Tim4CCR3_Val;
__IO uint16_t Tim4CCR4_Val;
改变这个数,就能改变频率。计数不断提高,周期变大,频率变慢。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"
#include "stepper.h"
int main(void)
{
int i;
Tim4CCR1_Val=20000;
Tim4CCR2_Val=10000;
Tim4CCR3_Val=5000;
Tim4CCR4_Val=2500;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200);//初始化串口波特率为115200
LED_Init();
LED0=0; LED1=0; LED2=0; LED3=0;
delay_ms(1000);
LED0=1; LED1=1; LED2=1; LED3=1;
delay_ms(1000);
LED0=0; LED1=0; LED2=0; LED3=0;
delay_ms(1000);
LED0=1; LED1=1; LED2=1; LED3=1;
delay_ms(1000);
LED0=0; LED1=0; LED2=0; LED3=0;
delay_ms(1000);
LED0=1; LED1=1; LED2=1; LED3=1;
delay_ms(1000);
Stepper_Tim4_2Init(65535,83);
// TIM10_PWM_Init(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
{
}
}
、、-----------------------------------------------------
#ifndef __STEPPER_H
#define __STEPPER_H
#include “sys.h”
#include “stm32f4xx.h”
#include “led.h”
/*
说明:使用定时器T4的CH1,CH2,CH3,CH4,T2的CH1和CH2
使用定时器捕获比较输出产生PWM。
设定周期,当计数器加法器加到设定值,捕获,反转
然后再次设置捕获值,进行再一次反转。
https://blog.csdn.net/oxiaoxue123456789/article/details/110496155?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242
https://blog.csdn.net/dainifeixiang/article/details/5494355?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control
端口分配:
PUL脉冲输出,DIR方向,EN使能,采用共阳接法
----T4CH1 T4CH2 T4CH3 T4CH4 T2CH1 T2CH2
PUL B6 B7 B8 B9 A0 A1
DIR F3 F5 F6 F4 F10 A6
EN G3 G2 G4 G0 G1 A7
*/
//变量
//这个和驱动器的细分数字有关,因此经过测试之后,细分数不能乱动!
//切记。
//比例,200个脉冲,走一个mm,或者是1度。
extern int StepKX;
extern int StepKY;
extern int StepKZ;
extern int StepKA;
extern int StepKB;
extern int StepKC;
//速度,mm/s======
extern float StepVx;
extern float StepVy;
extern float StepVz;
extern float StepVa;
extern float StepVb;
extern float StepVc;
//控制端口定义
//方向
#define StepDirX PFout(3) // DS0
#define StepDirY PFout(5) // DS0
#define StepDirZ PFout(6) // DS0
#define StepDirA PFout(4) // DS0
#define StepDirB PFout(10) // DS0
#define StepDirC AFout(6) // DS0
//使能
#define StepEnaX PGout(3) // DS0
#define StepEnaY PGout(2) // DS0
#define StepEnaZ PGout(4) // DS0
#define StepEnaA PGout(0) // DS0
#define StepEnaB PGout(1) // DS0
#define StepEnaC PAout(7) // DS0
extern uint16_t Tim4Capture;//捕获
extern __IO uint16_t Tim4CCR1_Val;
extern __IO uint16_t Tim4CCR2_Val;
extern __IO uint16_t Tim4CCR3_Val;
extern __IO uint16_t Tim4CCR4_Val;
//---------------------------
void Stepper_Tim4_2Init(u32 arr,u32 psc);//初始化
void Stepper_Move(u8 Axisii,u8 Dirii,u8 Speedii,float Mmii);
void Stepper_Stop(u8 Axisii);
#endif
00000000000000000000000000000000000000000000000000000000
#include "stepper.h"
//----比例,200个脉冲,一个mm,或者1度
//和细分数有关
int StepKX=200;
int StepKY=200;
int StepKZ=200;
int StepKA=200;
int StepKB=200;
int StepKC=200;
//电机速度mm/s
float StepVx;
float StepVy;
float StepVz;
float StepVa;
float StepVb;
float StepVc;
uint16_t Tim4Capture = 0;
__IO uint16_t Tim4CCR1_Val;
__IO uint16_t Tim4CCR2_Val;
__IO uint16_t Tim4CCR3_Val;
__IO uint16_t Tim4CCR4_Val;
//定时器T4和T2比较捕获输出,产生PWM波形
void Stepper_Tim4_2Init(u32 arr,u32 psc)//初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//--------------------------
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_TIM4); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_TIM4); //========GPIOE5复用为定时器14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
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_UP; //上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
//-------------------------
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//中断优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//----------------------------------
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//初始化TIM2时钟
TIM_TimeBaseStructure.TIM_Period = arr; //这里必须是65535
TIM_TimeBaseStructure.TIM_Prescaler = psc; //3分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化TIM4
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //输出比较翻转模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能通道1
TIM_OCInitStructure.TIM_Pulse = Tim4CCR1_Val; //待装入输出比较寄存器中的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出为正逻辑
TIM_OC1Init(TIM4, &TIM_OCInitStructure); //写入配置
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable); //使能或者失能TIMx在CCR1上的预装载寄存器
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = Tim4CCR2_Val;
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = Tim4CCR3_Val;
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = Tim4CCR4_Val;
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM4, ENABLE); //开启计数器
/* TIM IT enable */ //TIM1中断源设置,开启相应通道的捕捉比较中断
TIM_ITConfig(TIM4, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
}
void TIM4_IRQHandler(void)
{
static u16 capture = 0;
if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);//清除标志位
capture = TIM_GetCapture1(TIM4);
LED0=!LED0;
TIM_SetCompare1(TIM4, capture + Tim4CCR1_Val);//重新设置比较值
}
if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);//清除标志位
capture = TIM_GetCapture2(TIM4);
LED1=!LED1;
TIM_SetCompare2(TIM4, capture + Tim4CCR2_Val);//重新设置比较值
}
if (TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);//清除标志位
capture = TIM_GetCapture3(TIM4);
LED2=!LED2;
TIM_SetCompare3(TIM4, capture + Tim4CCR3_Val);//重新设置比较值
}
if (TIM_GetITStatus(TIM4, TIM_IT_CC4) != RESET)//通道1检测到比较事件
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);//清除标志位
capture = TIM_GetCapture4(TIM4);
LED3=!LED3;
TIM_SetCompare4(TIM4, capture + Tim4CCR4_Val);//重新设置比较值
}
}
//-------------------------------------------
void Stepper_Move(u8 Axisii,u8 Dirii,u8 Speedii,float Mmii)
{
}
void Stepper_Stop(u8 Axisii)
{
}