[范例教程] 【M0】 MG32F02A 学习笔记④ 定时器26 PWM 调光

[复制链接]
1462|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初始化的内容复制保存起来,以后要用的时候直接贴上去,完了修改你要的参数就好。

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

  3. typedef uint8_t u8;
  4. typedef uint16_t u16;
  5. typedef uint32_t u32;
  6. typedef uint64_t u64;

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


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

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

  28.     TM_DeInit(TM26);
  29.    
  30.     // ----------------------------------------------------
  31.     // 1.TimeBase structure initial
  32.     TM_TimeBaseStruct_Init(&TM_TimeBase_InitStruct);
  33.    
  34.     // modify parameter
  35.     TM_TimeBase_InitStruct.TM_MainClockDirection =TM_UpCount;
  36.     TM_TimeBase_InitStruct.TM_Period = TM26_MainCounter_Range-1;
  37.     TM_TimeBase_InitStruct.TM_Prescaler = TM26_PrescalerCounter_Range-1;
  38.     TM_TimeBase_InitStruct.TM_CounterMode = Cascade;
  39.    
  40.     TM_TimeBase_Init(TM26, &TM_TimeBase_InitStruct);
  41.    
  42.     // ----------------------------------------------------
  43.     // 2.config TM26 channel 1 function
  44.     TM_CH1Function_Config(TM26, TM_16bitPWM);

  45.    
  46.     // ----------------------------------------------------
  47.     // 3.Enable TM26 channel 1 Output (just output TM26_OC11)
  48.     TM_OC11Output_Cmd(TM26,ENABLE);   
  49.     TM_InverseOC1z_Cmd(TM26, DISABLE);
  50.     TM_OC1zOutputState_Init(TM26, CLR);
  51.                
  52.                 // ----------------------------------------------------
  53.                 // 3.Enable TM26 channel 1 Output (just output TM26_OC12)
  54.     TM_OC12Output_Cmd(TM26,ENABLE);   
  55.     TM_InverseOC1z_Cmd(TM26, DISABLE);
  56.     TM_OC1zOutputState_Init(TM26, CLR);
  57.    
  58.     // ----------------------------------------------------
  59.     // 4.set match point (Duty cycle %) for PWM channel0.Less value of CCnA/CCnB,more lighten (1~100(decided by MainCounter_Range you set))
  60.                
  61.     TM_SetCC1A(TM26,90);        
  62.     TM_SetCC1B(TM26,90);                // reload value when overflow


  63.     // ----------------------------------------------------
  64.     // 9.select Edge Align
  65.     TM_AlignmentMode_Select(TM26, TM_EdgeAlign);   
  66.    
  67.     // ----------------------------------------------------
  68.     // 10.clear flag
  69.     TM_ClearFlag(TM26, TMx_CF0A | TMx_CF1A | TMx_CF2A);
  70.    
  71.     // ----------------------------------------------------
  72.     // 11.Timer enable
  73.     TM_Timer_Cmd(TM26,ENABLE);
  74.    
  75.    
  76. }

  77. void CSC_Init (void)
  78. {

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

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

  85.         
  86.         /* CK_HS selection */
  87.         CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
  88.         CSC_IHRCO_Cmd(ENABLE);
  89.         while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
  90.         CSC_ClearFlag(CSC_IHRCOF);
  91.         CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO
  92.         
  93.         /* CK_MAIN */
  94.         CSC_CK_MAIN_Select(MAIN_CK_HS);        


  95.         /* Configure ICKO function */
  96.                
  97.         /* Configure peripheral clock */
  98.         CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);                                          // Enable Port E clock
  99.         
  100.         CSC_PeriphProcessClockSource_Config(CSC_TM26_CKS, CK_APB);
  101.         CSC_PeriphOnModeClock_Config(CSC_ON_TM26, ENABLE);                                          // Enable TIM26 module clock
  102.         
  103.   ProtectModuleReg(CSCprotect);
  104.    
  105. }


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

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

  121.         Sample_TM26_PWM();

  122.     while(1);
  123.                
  124. }
     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

粉丝
快速回复 在线客服 返回列表 返回顶部