打印

MM32 MCU互补PWM输出使能带死区、带刹车功能(一)

[复制链接]
818|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FCCdsp|  楼主 | 2017-12-28 10:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MM32 MCU互补PWM输出使能带死区、带刹车功能


   脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM最基本的调节就是频率和占空比,通过调节频率和占空比对外部元件进行控制或者捕捉外部信号源。
  在大功率电机、变频器、开关电源等方案中,末端都是由大功率管、IGBT等元件组成的H桥或3相桥。每个桥的上半桥和下半桥是是绝对不能同时导通的,但高速的PWM驱动信号在达到功率元件的控制极时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。死区就是在上半桥关断后,延迟一段时间再打开下半桥或在下半桥关断后,延迟一段时间再打开上半桥,从而避免功率元件烧毁。
  MM32L0系列MCU有多达9个定时器,高级定时器TIM1可以产生互补的PWM高级定时器TIM1是1 个 16位4通道高级控制定时器,有 4 通道 PWM 输出,以及死区生成和紧急停止功能,可以通过相关寄存器的设置使能或关闭PWM的输出。
   高级控制定时器(TIM1)能够输出两路互补信号,并且能够管理输出的瞬时关断和接通。这段时间通常被称为死区,用户应该根据连接的输出器件和它们的特性(电平转换的延时、电源开关的延时等)来调整死区时间。
  使用紧急停止功能,使能输出信号和无效电平都会被改变,关闭PWM输出,能够有效的预防突发事件造成外部电机等不可控的状态,刹车源既可以是刹车输入管脚又可以是一个时钟失败事件。时钟失败事件由复位时钟控制器中的时钟安全系统产生。在安全方面,你可以把刹车输入连到电源驱动的报警输出、热敏传感器或者其他安全器件上。
  在编写电机的驱动程序时,需要利用TIM1的Channel1,2,3三个通道生成三路互补的PWM波形,TIM1需要配置的寄存器有:捕捉/比较模式寄存器 1TIMx_CCMR1)、捕捉/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~3)和刹车和死区寄存器(TIMx_BDTR.
程序配置流程如下:
void TIM1_PWM_Init(u16 arr,u16 psc)
{  
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStruct;
      
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB ,ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;//TIM3_CH1  TIM3_CH1N
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
      
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;//TIM3_CH1  TIM3_CH1N
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
      
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //TIM3_CH1  TIM3_CH1N
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
      
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_2);
              
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_2);
              
GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_2);
      
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter =0;
TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStruct.TIM_DeadTime = 0x99;
//TDTS = 125nS(8MHz)
//DTG[7: 5] = 0xx => DT = DTG[7: 0] * Tdtg, Tdtg = TDTS;
//DTG[7: 5] = 10x => DT =(64+DTG[5: 0]) * Tdtg, Tdtg = 2 * TDTS;
//DTG[7: 5] = 110 => DT =(32+DTG[4: 0]) * Tdtg, Tdtg = 8 * TDTS;
//DTG[7: 5] = 111=> DT =(32 + DTG[4: 0]) *  Tdtg, Tdtg = 16 * TDTS;
TIM_BDTRInitStruct.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStruct.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig( TIM1, &TIM_BDTRInitStruct);      
      
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset;
              
TIM_OC1Init(TIM1, &TIM_OCInitStructure);  
TIM_OC2Init(TIM1, &TIM_OCInitStructure);  
TIM_OC3Init(TIM1, &TIM_OCInitStructure);  
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);  
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);  
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
      
}
第一步:开定时器TIM1的时钟和GPIOA\GPIOB的时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB ,ENABLE);
第二步:配置GPIO的模式,根据UM_MM32L0系列手册的8.1.11外设的 GPIO 配置查表可以知配置CHx的输出比较通道x和互补输出通道x功能时,需将GPIO配置成推挽复用输出模式,配置定时器的刹车输入功能时GPIO需配置成浮空输入功能。

  根据DS_MM32L0系列手册的表4和表5的端口功能复用列表可知,PA8\PA9\PA10AF2TIM1CH1\CH2\CH3通道,PB13\PB14\PB15AF2TIM1CH1N\CH2N\CH3N通道,所以在配置GPIO的复用功能选择时通过软件写入配置IO的复用功能为AF2
  在本试验中,通过配置PB12作为刹车信号源的输入脚。根据端口功能复用列表可知,PB12AF2TIM1的刹车输入功能。




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

967

主题

1447

帖子

9

粉丝