STM32输出1PPS 可调相位和脉宽

/* Includes ------------------------------------------------------------------*/
#include "tim.h"

uint32_t  plus_value = 8000000;//100ms

uint32_t  gCmpTbl[2]  = {80000000-1,8000000-1};
uint32_t  gCmpTb2[2]  = {80000000-1,8000000-1+20};	//lc 20220826
//uint32_t  gCmpTb2[2]  = {80000000-1,8000000-1+8};


uint8_t   gPosiOrNega_Out = 0;
uint8_t   gPosiOrNega_Clr = 0;

uint8_t		Led_Flag = 0;

void Mcu_Timer_SetCmpTbl(uint32_t *pCmp,uint32_t *pCmp4)
{
	gCmpTb2[0] = *pCmp++;
	gCmpTb2[1] = *pCmp++;

	gCmpTbl[0] = *pCmp4++;
	gCmpTbl[1] = *pCmp4++;
}

/* USER CODE BEGIN 0 */
void Mcu_Timer2_PinCfg(void)
{
    /* input capture */
    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA|LL_AHB2_GRP1_PERIPH_GPIOB);
		/*PPS INPUT*/
    LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_0, LL_GPIO_PULL_UP);
    LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_0, LL_GPIO_SPEED_FREQ_HIGH);
    LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_0, LL_GPIO_AF_1);
		/*PPS OUTPUT*/
    LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_10, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_10, LL_GPIO_PULL_UP);
    LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_10, LL_GPIO_SPEED_FREQ_HIGH);
    LL_GPIO_SetAFPin_8_15(GPIOB, LL_GPIO_PIN_10, LL_GPIO_AF_1);
		/*PPS CLR*/
    LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_1, LL_GPIO_PULL_UP);
    LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_1, LL_GPIO_SPEED_FREQ_HIGH);
    LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_1, LL_GPIO_AF_1);
}
/* USER CODE END 0 */

/* TIM2 init function */
void MX_TIM2_Init(void)
{
	Mcu_Timer2_PinCfg();
 
	NVIC_SetPriority(TIM2_IRQn, 1);
	NVIC_EnableIRQ(TIM2_IRQn);
	/* Peripheral clock enable */
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);

	LL_TIM_SetPrescaler(TIM2, __LL_TIM_CALC_PSC(SystemCoreClock , 80000000));
	LL_TIM_SetAutoReload(TIM2, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM2), 1));
	LL_TIM_EnableARRPreload(TIM2);
	/************************************/
	/* Input capture mode configuration */
	/************************************/
	LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);

	/* Configure the input filter duration: no filter needed */
	LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);

	/* Set input prescaler: prescaler is disabled */
	LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);

	/* Select the edge of the active transition on the TI1 channel: rising edge */
	LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);


	/*********************************/
	/* Output waveform configuration */
	/*********************************/
	LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);

	/* Set output channel polarity: OC is active high */
	LL_TIM_OC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCPOLARITY_HIGH);

	/* Set output compare active/inactive delay to half of the auto-reload value */
	LL_TIM_OC_SetCompareCH4(TIM2, (LL_TIM_GetAutoReload(TIM2) / 2));

	/*********************************/
	/* CLR waveform configuration */
	/*********************************/
	LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCMODE_ACTIVE);

	/* Set output channel polarity: OC is active high */
	LL_TIM_OC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCPOLARITY_HIGH);

	/* Set output compare active/inactive delay to half of the auto-reload value */
	LL_TIM_OC_SetCompareCH2(TIM2, (LL_TIM_GetAutoReload(TIM2) / 2));

	LL_TIM_EnableIT_CC1(TIM2);
	LL_TIM_EnableIT_CC2(TIM2);
	LL_TIM_EnableIT_CC3(TIM2);

	LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
	LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
	LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);
	LL_TIM_EnableCounter(TIM2);
}

/* USER CODE BEGIN 1 */
void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
	/*INPUT*/
    if(LL_TIM_IsActiveFlag_CC1(TIM2))
    {
        LL_TIM_ClearFlag_CC1(TIM2);
				if(LL_TIM_IsEnabledIT_CC1(TIM2))
				{
					sys_str.cnt_for_in_pps_index++;
					if(sys_str.cnt_for_in_pps_index>=0xffffff)
					{
						sys_str.cnt_for_in_pps_index = 0xffffff;
					}
					sys_str.cnt_for_local_pps_index = 0;
					sys_str.capVlaue_last = sys_str.capVlaue_cur;
					sys_str.capVlaue_cur = LL_TIM_IC_GetCaptureCH1(TIM2);
				}	
		 }
	/*OUTPUT*/
    if(LL_TIM_IsActiveFlag_CC3(TIM2))
    {
        LL_TIM_ClearFlag_CC3(TIM2);
		if(LL_TIM_IsEnabledIT_CC3(TIM2))
		{
			   gPosiOrNega_Out = 1 - gPosiOrNega_Out;
				LL_TIM_OC_SetCompareCH3(TIM2,gCmpTbl[gPosiOrNega_Out]%80000000);
				if(gPosiOrNega_Out)
				{
					sys_str.cnt_for_local_pps_index++;
					if(sys_str.cnt_for_local_pps_index>=0xffffff)
					{
						sys_str.cnt_for_local_pps_index = 0xffffff;
					}								
					sys_str.cnt_for_in_pps_index = 0;	
					LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
				}
				else
				{
					LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_INACTIVE);
				}
		}
	}	
	/*CLR*/
    if(LL_TIM_IsActiveFlag_CC2(TIM2))
    {
        LL_TIM_ClearFlag_CC2(TIM2);
				if(LL_TIM_IsEnabledIT_CC2(TIM2))
				{
						gPosiOrNega_Clr = 1 - gPosiOrNega_Clr;
						LL_TIM_OC_SetCompareCH2(TIM2,gCmpTb2[gPosiOrNega_Clr]%80000000);
						if(gPosiOrNega_Clr)
						{
							LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCMODE_ACTIVE);
						}
						else
						{
							sys_str.flag_for_1s = 1; 
							fsk_sync();
							LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCMODE_INACTIVE);
						}
				}
	}
  /* USER CODE END TIM2_IRQn 1 */
}

同步函数

void Mcu_Timer_SetCmpTbl(uint32_t *pCmp,uint32_t *pCmp4);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: stm32输出带有相位差的pwm的具体步骤如下: 1. 首先,需要配置定时器的时钟源和分频系数。定时器的时钟源可以选择内部时钟源或外部时钟源,分频系数可以根据需求选择合适的值。 2. 然后,需要配置定时器的计数模式。定时器计数模式可以选择向上计数模式、向下计数模式或中央对齐计数模式。 3. 接着,需要设置pwm的周期和占空比。周期可以通过修改定时器的自动重装载寄存器来设置,占空比可以通过修改定时器的比较寄存器来设置。 4. 最后,需要设置相位差。设置相位差有两种方法:一种是通过修改定时器的触发源来实现,另一种是通过修改定时器的延迟源来实现。 在具体实现时,可以先使用stm32的hal库或者直接编写寄存器级别的代码进行配置和设置。需要注意的是,在设置相位差时要注意定时器的计数模式和延迟源的选择。 总的来说,stm32可以通过灵活的定时器配置实现带有相位差的pwm输出,具体实现方法可以根据需求进行选择。 ### 回答2: 要实现STM32输出相位差的PWM信号,需要按以下步骤进行设置: 1.选择使用定时器:STM32内部集成了多个定时器,其中定时器可以产生PWM信号。因此,首先需要确定使用哪个定时器,并在代码中进行相应的配置。在本例中,我们使用TIM1定时器。 2.配置定时器:对于输出相位差的PWM信号,定时器需要配置为多通道模式。要输出两路有相位差的PWM信号,则需要启用至少两个通道。对于TIM1定时器来说,需要启用CH1和CH2通道。此外,需要在定时器的输入捕获模式下设置两个通道的极性相反。 3.设置预分频器和计数器周期:预分频器和计数器周期的设置决定了PWM信号的频率和占空比。在本例中,我们要求输出PWM频率为1kHz,所以需要设置定时器的时钟频率为84MHz(使用的是STM32F407VG开发板),并将预分频器分频值设置为84,将计数器周期设置为1000。 4.设置两个通道的占空比和相位差:将CH1和CH2通道的占空比设置为需要的值,并使用定时器的硬件相位计功能来设置两路PWM信号的相位差。具体的相位差设置方法可参考 STM32官方文档。 5.启动定时器:完成前面的设置后,需要启动定时器输出PWM信号。在本例中,我们使用HAL库提供的函数“HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1)”和“HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2)”来启动两路PWM信号的输出。 以上是关于STM32输出相位差的PWM信号的简单介绍,更为详细的代码实现可以参考STM32官方文档及其HAL库的使用手册。 ### 回答3: 首先,PWM(调制)是一种用于模拟信号的技术,它允许一个数字控制器以数字方式调整输出信号的占空比,从而模拟一个模拟输出信号。在STM32中,我们可以使用TIMx模块来实现PWM控制。 要输出相位差的PWM信号,我们可以通过两个不同的TIMx模块分别控制两个输出引脚,并设置不同的相位差。具体步骤如下: 1. 初始化TIMx模块:使用HAL库或手动配置寄存器进行TIMx模块的初始化,设置频率、分频器等。 2. 配置TIMx的两个输出:使用HAL库或手动配置寄存器进行TIMx的两个输出端口的初始化,包括极性、输出模式、占空比、定时器模式等。 3. 设置相位差:通过使用TIMx的互补输出模式,我们可以设置两个输出端口的相位差。在互补输出模式下,TIMx会自动处理正常输出和互补输出相位差。 4. 启动TIMx定时器:最后,我们可以启动TIMx定时器,输出带有相位差的PWM信号,该信号可以用于控制电机、LED等应用。 在代码实现上,可以将上述步骤放在一个函数或者程序块中,并在主函数或事件中调用。使用TIMx模块控制PWM,可以实现精确控制输出信号的占空比和相位差,适用于各种控制器设备和系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值