stm32F4定时器比较捕获输出PWM,做反转电平01

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)
{

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值