STM32F103移相全桥PWM寄存器实现
由于项目需求需要使用单片做一个移相全桥的DCDC电源。采用STM32F103芯片,采用直接控制寄存器实现PWM移相控制
基本原理
两桥臂分别使用定时器TIM1和TIM8产生互补输出信号,TIM8作为从定时器,其计数器复位由TIM1控制
TIM1初始化
void time1_pwm_init(u16 arr,u16 ccr1,u16 ccr2)
{
//
//调整ccr1从0 到500,实现移相角度从0到180度
RCC->APB2ENR|=1<<0;//辅助功能IO时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟,IO口A时钟使能
RCC->APB2ENR|=1<<3; //使能PORTB时钟,IO口B时钟使能
RCC->APB2ENR|=1<<11;//TIM1时钟使能
GPIOA->CRH&=0XFFFFFF0F; //PA9 推挽输出CHZ
GPIOA->CRH|=0X000000B0; //输出
GPIOB->CRH&=0XF0FFFFFF; //PB14 推挽输出
GPIOB->CRH|=0X0B000000; //输出
TIM1->ARR=arr;//自动重装载寄存器(TIM1_ARR)
TIM1->PSC=0;//预分频器(TIM1_PSC),等于fCK_PSC/( PSC[15:0]+1)
TIM1->CCMR1|=6<<12;//PWM模式1
TIM1->CCMR1|=1<<11;//开启TIM1_CCR1寄存器的预装载功能
// TIM1->RCR=0x0000;//在边沿对齐模式下, PWM周期的数目(REP+1)对应着
//使TIME1的OC1为TIM8的复位信号
TIM1->CCMR1|=7<<4;//OC1M[2:0]:输出比较1模式- 在向上计数时PWM2
TIM1->CCMR1|=1<<3;//开启TIM1_CCR1 OC1PE输出比较1预装载使能
TIM1->CR2|=4<<4;//MMS[1:0]:主模式选择100:比较 – OC1REF信号被用于作为触发输出(TRGO)。
TIM1->CCMR1|=1<<10;//OC2FE 01: 输出比较2快速使能
TIM1->CCER|=1<<4;//开启- OC2信号输出到对应的输出引脚
TIM1->CCER|=1<<6;//开启- OC2N信号输出到对应的输出引脚
TIM1->CR1&=~(1<<4);//向上计数 TIM1->CR1&=~(1<<4);//向上计数
TIM1->CR1&=~(3<<5);//边沿对齐模式
TIM1->CCR1=ccr1;//(1599+1)/2-1
TIM1->CCR2=ccr2;//(1599+1)/2-1
TIM1->CR1|=1<<7;//TIM1_ARR寄存器被装入缓冲器
TIM1->CR1|=1<<0;//开启计数器
TIM1->EGR|=1<<0;
TIM1->BDTR|=0<<13;//刹车极性
TIM1->BDTR|=0<<12;//刹车使能
TIM1->BDTR|=90<<0;//Tdtg = 1× TDTS
TIM1->BDTR|=1<<15;//则开启OC和OCN输出
}
TIM8初始化
void time8_pwm_init(u16 arr,u16 ccr2)
{
RCC->APB2ENR|=1<<0; //辅助功能IO时钟使能
RCC->APB2ENR|=1<<3; //使能PORTB时钟,IO口B时钟使能
RCC->APB2ENR|=1<<4; //使能PORTC时钟,IO口C时钟使能
RCC->APB2ENR|=1<<13; //TIM8时钟使能
GPIOB->CRL&=0XFFFFFFF0; //PB0 推挽输出CHZ
GPIOB->CRL|=0X0000000B; //输出
GPIOC->CRL&=0X0FFFFFFF; //PC7 推挽输出
GPIOC->CRL|=0XB0000000; //输出
TIM8->ARR=arr;//自动重装载寄存器(TIM1_ARR)
TIM8->PSC=0;//预分频器(TIM1_PSC),等于fCK_PSC/( PSC[15:0]+1)
TIM8->CCMR1|=6<<12;//PWM模式1- 在向上计数时,一旦TIM1_CNT<TIM1_CCR1时通道1为有效电平,否
//则 为 无 效 电 平 ; 在 向 下 计 数 时 , 一 旦 TIM1_CNT>TIM1_CCR1 时 通 道 1 为 无 效 电 平
//(OC1REF=0),否则为有效电平(OC1REF=1)。
TIM8->CCMR1|=1<<11;//开启TIM1_CCR1寄存器的预装载功能
//使TIME8的接收TIME1的OCref信号
TIM8->SMCR|=1<<7;//主/从模式
TIM8->SMCR|=4<<0;//SMS:从模式选择,100 复位模式 ,选中的触发输入(TRGI)的上升沿重新初始化计数器
TIM8->SMCR|=0<<4;//TS[2:0]:触发选择 000: ITR0 TIMx内触部触发连接
TIM8->SMCR|=0<<5;
TIM8->SMCR|=0<<6;
TIM8->CCER|=0<<0;
TIM8->CCMR1|=1<<0;
TIM8->CCMR1|=1<<10;//OC2FE 01: 输出比较2快速使能
TIM8->CCER|=1<<4;//开启- OC2信号输出到对应的输出引脚
TIM8->CCER|=1<<6;//开启- OC2N信号输出到对应的输出引脚
TIM8->CR1&=~(1<<4);//向上计数
TIM8->CR1|=1<<7;//TIM1_ARR寄存器被装入缓冲器
TIM8->CR1|=1<<0;//开启计数器
TIM8->CNT;
TIM8->CCR2=ccr2;//(1599+1)/2-1
TIM8->EGR|=1<<0;
TIM8->BDTR|=0<<13;//刹车极性
TIM8->BDTR|=0<<12;//刹车使能
TIM8->BDTR|=90<<0;//Tdtg = 1× TDTS
TIM8->BDTR|=1<<15;//则开启OC和OCN输出
}
代码的关键是如何让TIM1的CCR1产生的OC1REF去触发TIM8的计数复位
关键部分如下:
//使TIME1的OC1为TIM8的复位信号
TIM1->CCMR1|=7<<4;//OC1M[2:0]:输出比较1模式- 在向上计数时PWM2
TIM1->CCMR1|=1<<3;//开启TIM1_CCR1 OC1PE输出比较1预装载使能
TIM1->CR2|=4<<4;//MMS[1:0]:主模式选择100:比较 – OC1REF信号被用于作为触发输出(TRGO)。
//使TIME8的接收TIME1的OC1ref信号
TIM8->SMCR|=1<<7;//主/从模式
TIM8->SMCR|=4<<0;//SMS:从模式选择,100 复位模式 ,选中的触发输入(TRGI)的上升沿重新初始化计数器
TIM8->SMCR|=0<<4;//TS[2:0]:触发选择 000: ITR0 TIMx内触部触发连接
TIM8->SMCR|=0<<5;
TIM8->SMCR|=0<<6;
TIM8->CCER|=0<<0;
TIM8->CCMR1|=1<<0;
通过调整TIM1->CCR1的值从0到500即可调整占空比从0到100%变化
当TIM1->CCR1=100时的波形: