打印
[范例教程]

【M0】 MG32F02A 学习笔记④ 定时器26 PWM 调光

[复制链接]
957|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
noctor|  楼主 | 2018-9-19 11:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 noctor 于 2018-9-19 11:36 编辑
     上回我们说到了MG32F02A的TIM00的使用来进行精准延时1ms的实验,初步的使用了一下我们的定时器,那么我们这次就来学习一下如何使用PWM吧。
      上次的TIM精准延时1ms实验帖子链接:https://bbs.21ic.com/icview-2554558-1-1.html


      首先,我们的EV板上面是有LED的,那么最直观的观察PWM的方式除了示波器就是看LED灯光亮度了吧,看了一下,我们EV板上的LED是接在PE13、PE14上的,那么看看PE13或者PE14上面是否有PWM的输出呢?
      
      查了一下,PE14和PE15都是有TIM的OC的,那么就可以直接使用了。
      对了,前段时间在玩这块板子的时候出现了一些问题,我使用Configure Wizard初始化完成后依然不能输出PWM,查了无数次代码后依旧找不到问题,初始化设置也检查了,自认为没有设置错误,但是PWM死活出不来,后来就尝试自己进行初始化,不使用Configure Wizard,结果PWM就出来了。。所以我现在还是推荐如果要使用的外设比较多,设置比较复杂,那还是自己进行初始化吧,不要使用Configure Wizard了,因此,这次我的代码就不放上使用了Wizard的代码,只放手动初始化的代码,如果嫌麻烦就直接把我CSC_init()和GPIO初始化的内容复制保存起来,以后要用的时候直接贴上去,完了修改你要的参数就好。

      程序如下:
#include "MG32x02z_DRV.H"
#include <stdio.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

//if user wants to set PWM period 1ms and CK_TM00_PR is 12MHz.
//The Total clocks is 12M*1ms = 12000.
//User can set "clock prescaler"=100 and "pulse width"=120 .   
#define TM26_PrescalerCounter_Range 120
#define TM26_MainCounter_Range      100


void Sample_TM26_PWM(void)
{  
    TM_TimeBaseInitTypeDef TM_TimeBase_InitStruct;
     
        
                //        The period = (prescaler*main counter)/12MHz (CK_TM26_PR=12MHz) (s)
    //  User can update duty cycle by replace CCxB register.

    // make sure :
        
    //===Set CSC init====
    //MG32x02z_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 12M
    //Select CK_MAIN Source = CK_HS
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->TM36 = Enable

    TM_DeInit(TM26);
   
    // ----------------------------------------------------
    // 1.TimeBase structure initial
    TM_TimeBaseStruct_Init(&TM_TimeBase_InitStruct);
   
    // modify parameter
    TM_TimeBase_InitStruct.TM_MainClockDirection =TM_UpCount;
    TM_TimeBase_InitStruct.TM_Period = TM26_MainCounter_Range-1;
    TM_TimeBase_InitStruct.TM_Prescaler = TM26_PrescalerCounter_Range-1;
    TM_TimeBase_InitStruct.TM_CounterMode = Cascade;
   
    TM_TimeBase_Init(TM26, &TM_TimeBase_InitStruct);
   
    // ----------------------------------------------------
    // 2.config TM26 channel 1 function
    TM_CH1Function_Config(TM26, TM_16bitPWM);

   
    // ----------------------------------------------------
    // 3.Enable TM26 channel 1 Output (just output TM26_OC11)
    TM_OC11Output_Cmd(TM26,ENABLE);   
    TM_InverseOC1z_Cmd(TM26, DISABLE);
    TM_OC1zOutputState_Init(TM26, CLR);
               
                // ----------------------------------------------------
                // 3.Enable TM26 channel 1 Output (just output TM26_OC12)
    TM_OC12Output_Cmd(TM26,ENABLE);   
    TM_InverseOC1z_Cmd(TM26, DISABLE);
    TM_OC1zOutputState_Init(TM26, CLR);
   
    // ----------------------------------------------------
    // 4.set match point (Duty cycle %) for PWM channel0.Less value of CCnA/CCnB,more lighten (1~100(decided by MainCounter_Range you set))
               
    TM_SetCC1A(TM26,90);        
    TM_SetCC1B(TM26,90);                // reload value when overflow


    // ----------------------------------------------------
    // 9.select Edge Align
    TM_AlignmentMode_Select(TM26, TM_EdgeAlign);   
   
    // ----------------------------------------------------
    // 10.clear flag
    TM_ClearFlag(TM26, TMx_CF0A | TMx_CF1A | TMx_CF2A);
   
    // ----------------------------------------------------
    // 11.Timer enable
    TM_Timer_Cmd(TM26,ENABLE);
   
   
}

void CSC_Init (void)
{

  UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  ProtectModuleReg(MEMprotect);

  UnProtectModuleReg(CSCprotect);
        CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
        CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

        
        /* CK_HS selection */
        CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
        CSC_IHRCO_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
        CSC_ClearFlag(CSC_IHRCOF);
        CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO
        
        /* CK_MAIN */
        CSC_CK_MAIN_Select(MAIN_CK_HS);        


        /* Configure ICKO function */
               
        /* Configure peripheral clock */
        CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);                                          // Enable Port E clock
        
        CSC_PeriphProcessClockSource_Config(CSC_TM26_CKS, CK_APB);
        CSC_PeriphOnModeClock_Config(CSC_ON_TM26, ENABLE);                                          // Enable TIM26 module clock
        
  ProtectModuleReg(CSCprotect);
   
}


int main()
{
        
        PIN_InitTypeDef PINX_InitStruct;
        CSC_Init();
                //==Set GPIO init
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;                                                                 // Pin select Push Pull mode
        PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;                                  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                        
        PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;                                                         // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;                        // Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;                                                         // Pin input data not inverse

        PINX_InitStruct.PINX_Alternate_Function  = 7;                                                                                                                // Pin AFS = TIM26 OC
        GPIO_PinMode_Config(PINE(13),&PINX_InitStruct);                                                                                                   // Set PE13 to TIM26 OC11
        GPIO_PinMode_Config(PINE(14),&PINX_InitStruct);                                                                                                   // Set PE14 to TIM26 OC12

        Sample_TM26_PWM();

    while(1);
               
}
     OK,这样PWM就出来了,要调节占空比就调节TM_SetCC1A(TM26,x)和TM_SetCC1B(TM26,x)的x值,其中保持A、B的值均一致就行。一样的原理,其他的TIM20、36都是可以输出PWM的,直接自己改就好了。

沙发
344864311| | 2018-10-16 11:23 | 只看该作者
感谢,已实验成功。

使用特权

评论回复
板凳
noctor|  楼主 | 2018-10-16 13:02 | 只看该作者
344864311 发表于 2018-10-16 11:23
感谢,已实验成功。

OK,只是试验成功也不够哦,要自己也能做出来

使用特权

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

本版积分规则

26

主题

82

帖子

3

粉丝