STM32 关于定时器相关问题的探讨(二)

4.硬件设计

4.1LED驱动电路

利用单片机产生得PWM驱动电路直接驱动LED电路来验证,当输出PWM宽度变化时可以看到此时LED亮度变化,此时只需要将LED上拉就可以实现验证。当输入为低电平时,LED灯发光
1

4.2 SPWM滤波方案

利用高级定时器,我们能产生一系列PWM脉宽随时间变化的PWM波形,通过简单的RC滤波就可以将SPWM滤波成正弦波

5.软件设计过程

5.1 四路pwm输出配置

5.1.1 GPIO初始化

初始化引脚(PA6、PA7,PB0、PB1),这里拿出初始化PA6例子

GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);    

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;     
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;   
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        
GPIO_Init(GPIOA,&GPIO_InitStructure); 

5.1.2 定时器初始化配置

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ARRPreloadConfig(TIM3,ENABLE);

TIM_TimeBaseStructure.TIM_Prescaler=psc;  
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
TIM_TimeBaseStructure.TIM_Period=arr;   
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_Cmd(TIM3, ENABLE); 

5.1.3 pwm输出配置

这里同样拿出PA6引脚对应得配置过程

TIM_OCInitTypeDef  TIM_OCInitStructure;

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
TIM_OCInitStructure.TIM_Pulse=0;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);  
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); 

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 
TIM_CtrlPWMOutputs(TIM3,ENABLE);  

5.2 占空比实现

TIM3_PWM_Init(arr-1,7-1);//tim3初始化

TIM_SetCompare1(TIM3,duty1);
TIM_SetCompare2(TIM3,duty2);
TIM_SetCompare3(TIM3,duty3);
TIM_SetCompare4(TIM3,duty4);

实验现象对比图
3

5.3 输出显示

显示代码:

 OLED_ShowString(0,0,"Chann1:",16);
 OLED_ShowFloatNum(56,0,(float)duty1/arr*100,7,16);
 OLED_ShowString(112,0,"%",16);
 OLED_ShowString(0,16,"Chann2:",16);
 OLED_ShowFloatNum(56,16,(float)duty2/arr*100,7,16);
 OLED_ShowString(112,16,"%",16);
 OLED_ShowString(0,32,"Chann3:",16);
 OLED_ShowFloatNum(56,32,(float)duty3/arr*100,7,16);
 OLED_ShowString(112,32,"%",16);
 OLED_ShowString(0,48,"Chann4:",16);
 OLED_ShowFloatNum(56,48,(float)duty4/arr*100,7,16);
 OLED_ShowString(112,48,"%",16);

实验现象图:
4

5.4 占空比调节

5.4.1按键设计模块

case 1: if(chmode == 1)  chmode = 2;
        else if(chmode == 2)  chmode = 3;
        else if(chmode == 3)  chmode = 4;
        else if(chmode == 4)  chmode = 1;                
            key=0;break;
case 2: if(chmode == 1)  duty1 += duty_index;
        else if(chmode == 2)  duty2 += duty_index;
        else if(chmode == 3)  duty3 += duty_index;
        else if(chmode == 4)  duty4 += duty_index;
        key=0;break;                            
case 3: if(chmode == 1)  duty1 -= duty_index;
        else if(chmode == 2)  duty2 -= duty_index;
        else if(chmode == 3)  duty3 -= duty_index;
        else if(chmode == 4)  duty4 -= duty_index;
        key=0;break;//
case 4: if(duty_index == 1)  duty_index = 2;
        else if(duty_index == 2) duty_index = 4;
        else if(duty_index == 4) duty_index = 5;
        else if(duty_index == 5) duty_index = 6;    
        else if(duty_index == 6) duty_index = 10;    
        else if(duty_index == 10) duty_index = 40;
        else if(duty_index == 40) duty_index = 1;           
        key=0;break;//                                            
case 5: arr+=50;
        key=0;break;//
        case 6:   arr-=50;
        key=0;break;

5.4.2 显示模块

OLED_ShowString(0,0,"dutyIndex:",16);
OLED_ShowNum(80,0,duty_index,2,16);
OLED_ShowString(0,16,"Channel:",16);
OLED_ShowNum(64,16,chmode,1,16);
OLED_ShowString(0,32,"TIM1->ARR:",16);
OLED_ShowNum(80,32,arr,4,16);    

实物现象对比图
通过按键1来切换不同的通道,按键2/3控制占空比的增减
5

5.5 spwm设计

对于高级定时器,可以添加死区

5.5.1 死区初始化

    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

    TIM_BDTRInitStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;
    TIM_BDTRInitStructure.TIM_Break= TIM_Break_Disable;
    TIM_BDTRInitStructure.TIM_BreakPolarity=TIM_BreakPolarity_High;
    TIM_BDTRInitStructure.TIM_DeadTime=dead;//¸øËÀÇøʱ¼ä
    TIM_BDTRInitStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;
    TIM_BDTRInitStructure.TIM_OSSRState=TIM_OSSRState_Enable;
    TIM_BDTRInitStructure.TIM_OSSIState=TIM_OSSIState_Enable;
    TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);    

5.5.2 spwm波表选择

这里我们可以简单的用c语言代码生成对应点数值,生成SPWM波表

float sin_value[672]=
{0.500000,0.504207,0.508415,0.512621,0.516826,0.521030,0.525232,0.529431,
0.533629,0.537823,0.542014,0.546201,0.550384,0.554563,0.558737,0.562906,
0.567069,0.571227,0.575378,0.579522,0.583660,0.587791,0.591913,0.596028,
0.600134,0.604232,0.608320,0.612399,0.616469,0.620528,0.624576,0.628614,
0.632640,0.636655,0.640657,0.644648,0.648626,0.652590,0.656542,0.660480,
0.664403,0.668313,0.672208,0.676087,0.679951,0.683800,0.687632,0.691448,
0.695248,0.699030,0.702795,0.706542,0.710271,0.713982,0.717673,0.721346,
0.725000,0.728634,0.732248,0.735841,

... ... ...

0.304752,0.308552,0.312368,0.316200,0.320049,0.323913,0.327792,0.331687,
0.335597,0.339520,0.343458,0.347410,0.351374,0.355352,0.359343,0.363345,
0.367360,0.371386,0.375424,0.379472,0.383531,0.387601,0.391680,0.395768,
0.399866,0.403972,0.408087,0.412209,0.416340,0.420477,0.424622,0.428773,
0.432931,0.437094,0.441263,0.445437,0.449616,0.453799,0.457986,0.462177,
0.466371,0.470569,0.474768,0.478970,0.483174,0.487379,0.491585,0.495793};

5.5.3 spwm中断程序

void TIM1_UP_TIM10_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
    {
        spwm_duty = 1000*sin_value[cnt++];
        if(cnt == 672)
            cnt = 0;
        TIM_SetCompare1(TIM1,spwm_duty);
    }
    TIM_ClearITPendingBit(TIM1,TIM_IT_Update);  
}

实验现象图
5

扫描二维码关注公众号,回复: 2158761 查看本文章

猜你喜欢

转载自blog.csdn.net/klaus_x/article/details/81043702
今日推荐