使用灵动微 MM32SPIN580C 定时器捕获 PWM 占空比

1. SPIN580C 及其定时器介绍

    MM32SPIN0280 是基于 Arm®Cortex®-M0 处理器开发的 32 位微控制器产品, 它同时具备了高性能和低功耗的特点。MM32SPIN0280 采用矩阵总线结构,该矩阵包括两个 AHB 主机:CPU 和 DMA,三个从机分别是 SRAM、闪存存储、AHB 总线(含 AHB 到 APB 的总线桥)以及连接在 APB 总线的各种设备。

       其框图为:


    本文例程使用其 TIM2 定时器的捕获功能,用于测量低频率 PWM 输入信号的周期和占空比,使用此占空比作为电机速度输入指令,控制电机转速,信号输入通过 TIM2_CH1 对应的 GPIO 口输入,T1FP1 捕获下降沿,测量高电平大小。

T1FP2 捕获上升沿,测量 PWM 周期。

    TIM2 由一个 16 位可实时编程预分频器和一个 32 位计数方向可调的自动重装载计数器组成,可以为用户提供便捷的计数定时功能,计数器时钟由预分频器分频得到。通用定时器具有多种用途,如输入功能(测量输入信号的脉冲宽度、频率,PWM 输入等),输出功能(PWM 输出、单脉冲模式输出等)。

框图为:

2. TIM2 定时器配置

    定时器配置包括其输入信号 GPIO 口的初始化和定时器工作频率设置、信号捕获电平设置、工作模式、中断等,其主要函数如下代码所示:

//GPIO 口初始化:
void Bsp_TimerCapture_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
RCC_AHBPeriphClockCmd(TIM_CAPTURE_RCC_CLOCKGPIO, ENABLE);

GPIO_PinAFConfig(TIM_CAPTU_PORT, TIM_CAPTU_PIN_SOURCE, TIM_CAPTU_PIN_AF);
GPIO_InitStructure.GPIO_Pin = TIM_CAPTU_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TIM_CAPTU_PORT, &GPIO_InitStructure);
}
//定时器初始化函数 Drv_Timer_Init(TIM2,TIM2_PRIOD,TIM2_PRESCALER);

#define TIM2_TCY 1 //Time base unit of TIM2(us)
#define TIM2_PRESCALER SYSCLK_HSI_72MHz / 2000000 - 1 //TIM2 Prescaler
#define TIM2_PRIOD 0xFFFF //TIM2 Period Value

void Drv_Timer_Init(TIM_TypeDef * pTim, uint16_t u16Period,uint16_t u16Prescaler)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
/** Enable the TIM clock */
if (TIM2 == pTim)
{
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM2, ENABLE);
}
else if (TIM3 == pTim)
{
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3, ENABLE);
}
else
{
return;
}

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = u16Period;
TIM_TimeBaseStructure.TIM_Prescaler = u16Prescaler;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CR1_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(pTim, &TIM_TimeBaseStructure);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;

TIM_PWMIConfig(pTim, &TIM_ICInitStructure);
TIM_SelectInputTrigger(pTim, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(pTim, TIM_SlaveMode_Reset);
TIM_Cmd(pTim, ENABLE);
}

//中断函数:
//其中 TIM2Capture.u32PerDutyCmd 即为占空比,缩放到 8000 的数值范围。

void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{

TIM2Capture.u32PWMPeriodCmd = TIM_GetCapture1(TIM2); //get PWM period
TIM2Capture.u32PWMDutyCmd = TIM_GetCapture2(TIM2); ////get PWM duty
TIM2Capture.u32PerDutyCmd = (8000*TIM2Capture.u32PWMDutyCmd / TIM2Capture.u32PWMPeriodCmd);
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update);
}
}
3
. 测试验证

    本文使用在某宝购买的 PWM 频率发生器产生占空比可调的信号,输出 2KHz 占空比为 50% 的 PWM 信号,则变量 TIM2Capture.u32PerDutyCmd 如果为 4000 左右即为正确的,Keil 在 Debug 模式时在 Watch 窗口中查看 TIM2Capture.u32PerDutyCmd ,连接示意图和实际连接图如下图所示:




   读到的数值是 3998,和理论计算还是很接近的。




4. 参考文档

    UM_MM32SPIN0280_SC.pdf   参考手册:    

    https://www.mindmotion.com.cn/download/products/UM_MM32SPIN0280_SC.pdf

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论