yangjiaoshai 发表于 2022-6-1 08:29

hc32f460的PWM输出问题

最近在用hc32f460做舵机,用的Timer4的1单元的互补PWM,发现PWM输出时,不能设置占空比为0%和100%。设置成0或者100时,应该直接输出为低电平或者高电平,但是芯片输出的是波特率为三角波频率一半的方波。不知道需要还需要怎么设置。


    /* Enable peripheral clock */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM41 | PWC_FCG2_PERIPH_TIM42 | PWC_FCG2_PERIPH_TIM43, Enable);

    /* Timer4 CNT : Initialize CNT configuration structure */
    stcCntInit.enBufferCmd = Disable;//禁止CPSR缓存
    stcCntInit.enClk = Timer4CntPclk;//inter clk use pclk 选择时钟源,内部
    stcCntInit.enClkDiv = Timer4CntPclkDiv1;/* CNT clock divide *///16倍分频
    stcCntInit.u16Cycle = TIMER4_CNT_CYCLE_VAL;//CPSR计数器的周期值
    stcCntInit.enCntMode = Timer4CntTriangularWave;//WAVE 锯齿波   //三角波
    stcCntInit.enZeroIntMsk = Timer4CntIntMask0;
    stcCntInit.enPeakIntMsk = Timer4CntIntMask0;
    TIMER4_CNT_Init(TIMER4_UNIT, &stcCntInit); /* Initialize CNT */ //配置CCSR和CVPR 和CPSR

    /* Timer4 OCO : Initialize OCO configuration structure *///配置 OCER OCSR
    stcOcoInit.enOcoIntCmd = Disable;
    stcOcoInit.enPortLevel = OcPortLevelLow;
    stcOcoInit.enOccrBufMode = OccrBufTrsfByCntZero;//OccrBufDisable;//使能缓存,OCCR 和OCMR都使能,在0点写入数据
    stcOcoInit.enOcmrBufMode = OcmrBufTrsfByCntZero;//OcmrBufDisable;
    TIMER4_OCO_Init(TIMER4_UNIT, TIMER4_OCO_UL_CH, &stcOcoInit);/* Initialize OCO low channel */
    TIMER4_OCO_Init(TIMER4_UNIT, TIMER4_OCO_VL_CH, &stcOcoInit);/* Initialize OCO low channel */
    TIMER4_OCO_Init(TIMER4_UNIT, TIMER4_OCO_WL_CH, &stcOcoInit);/* Initialize OCO low channel */

    /*************Timer4 OCO ocmr1 = 0x0FF0 0FFF*****************************/
    if (TIMER4_OCO_UL_CH % 2u)
    {
      /* OCMR Ox 0FF0 0FFF    0000 1111 1111 0000   0000 1111 1111 1111 */
      stcLowChCmpMode.enCntZeroLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit11 */
      stcLowChCmpMode.enCntZeroLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit11 */
      stcLowChCmpMode.enCntZeroLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit00 */
      stcLowChCmpMode.enCntZeroLowNotMatchHighNotMatchLowChOpState = OcoOpOutputHold;      /* bit00 */

      stcLowChCmpMode.enCntUpCntLowMatchHighMatchLowChOpState = OcoOpOutputReverse;      /* bit11 */
      stcLowChCmpMode.enCntUpCntLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;   /* bit    11 */
      stcLowChCmpMode.enCntUpCntLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;      /* bit00 */

      stcLowChCmpMode.enCntPeakLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit11 */
      stcLowChCmpMode.enCntPeakLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit    11 */
      stcLowChCmpMode.enCntPeakLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit00 */
      stcLowChCmpMode.enCntPeakLowNotMatchHighNotMatchLowChOpState = OcoOpOutputHold;      /* bit00 */

      stcLowChCmpMode.enCntDownLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit11 */
      stcLowChCmpMode.enCntDownLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit    11 */
      stcLowChCmpMode.enCntDownLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit00 */

      stcLowChCmpMode.enCntZeroMatchOcfState = OcoOcfSet;    /* bit 1 */
      stcLowChCmpMode.enCntUpCntMatchOcfState = OcoOcfSet;   /* bit 1 */
      stcLowChCmpMode.enCntPeakMatchOcfState = OcoOcfSet;    /* bit 1 */
      stcLowChCmpMode.enCntDownCntMatchOcfState = OcoOcfSet; /* bit 1 */

      TIMER4_OCO_SetLowChCompareMode(TIMER4_UNIT, TIMER4_OCO_UL_CH, &stcLowChCmpMode);/* Set OCO low channel compare mode */
      TIMER4_OCO_SetLowChCompareMode(TIMER4_UNIT, TIMER4_OCO_VL_CH, &stcLowChCmpMode);/* Set OCO low channel compare mode */
      TIMER4_OCO_SetLowChCompareMode(TIMER4_UNIT, TIMER4_OCO_WL_CH, &stcLowChCmpMode);/* Set OCO low channel compare mode */
    }

    /* Enable OCO */ //OCSR端口使能,一个通道同时使能H和L两个端口
    TIMER4_OCO_OutputCompareCmd(TIMER4_UNIT, TIMER4_OCO_UL_CH, Enable);//
    TIMER4_OCO_OutputCompareCmd(TIMER4_UNIT, TIMER4_OCO_VL_CH, Enable);//
    TIMER4_OCO_OutputCompareCmd(TIMER4_UNIT, TIMER4_OCO_WL_CH, Enable);//

    /* Initialize PWM I/O */   //设置管脚功能
    PORT_SetFunc(TIMER4_1UPWM_H_PORT, TIMER4_1UPWM_H_PIN, Func_Tim4, Disable);
    PORT_SetFunc(TIMER4_1UPWM_L_PORT, TIMER4_1UPWM_L_PIN, Func_Tim4, Disable);
               
    PORT_SetFunc(TIMER4_1VPWM_H_PORT, TIMER4_1VPWM_H_PIN, Func_Tim4, Disable);
    PORT_SetFunc(TIMER4_1VPWM_L_PORT, TIMER4_1VPWM_L_PIN, Func_Tim4, Disable);
               
    PORT_SetFunc(TIMER4_1WPWM_H_PORT, TIMER4_1WPWM_H_PIN, Func_Tim4, Disable);
    PORT_SetFunc(TIMER4_1WPWM_L_PORT, TIMER4_1WPWM_L_PIN, Func_Tim4, Disable);

    /* Timer4 PWM: Initialize PWM configuration structure *///,POCR基本控制寄存器
    stcPwmInit.enRtIntMaskCmd = Enable;//配置RCSR ,重载功能有效时,屏蔽掉中断。
    stcPwmInit.enClkDiv = PwmPlckDiv1;                //计算器分频 16分频POCR
    stcPwmInit.enOutputState = PwmHPwmLHold;//输出极性,H和L 都不反转
    stcPwmInit.enMode = PwmDeadTimerMode;//01 死区定时器模式   00 就是直通模式
    TIMER4_PWM_Init(TIMER4_UNIT, TIMER4_PWM_CHU, &stcPwmInit); /* Initialize timer4 pwm */
    TIMER4_PWM_Init(TIMER4_UNIT, TIMER4_PWM_CHV, &stcPwmInit); /* Initialize timer4 pwm */
    TIMER4_PWM_Init(TIMER4_UNIT, TIMER4_PWM_CHW, &stcPwmInit); /* Initialize timer4 pwm */
    TIMER4_PWM_WriteDeadRegionValue(TIMER4_UNIT, TIMER4_PWM_CHU, 20u,20u );//u16OcoOccrVal设置死区 PDARPDBR
    TIMER4_PWM_WriteDeadRegionValue(TIMER4_UNIT, TIMER4_PWM_CHV, 20u,20u );//u16OcoOccrVal设置死区 PDARPDBR
    TIMER4_PWM_WriteDeadRegionValue(TIMER4_UNIT, TIMER4_PWM_CHW, 20u,20u );//u16OcoOccrVal设置死区 PDARPDBR




    /* Timer4-SEVT: Initialize SEVT configuration structure */
    stcSevtInit.enBuf = SevtBufDisable;//缓存无限,直接写入寄存器
    stcSevtInit.enMode = SevtCompareTrigMode;//选择比较触发,还可以选择延时触发
    stcSevtInit.enTrigEvt = SevtTrgEvtSCMUL;//产生触发事件,比如AD模块可以去选择此触发来开始AD转换
    TIMER4_SEVT_Init(TIMER4_UNIT, Timer4SevtCh1, &stcSevtInit); /* Initialize SEVT */
    TIMER4_SEVT_WriteSCCR(TIMER4_UNIT, Timer4SevtCh1, 1000); /* Set SEVT compare value */

    stcSevtTrgCond.enUpMatchCmd = Disable;//Enable;//在上升沿与SCCR匹配时,产生事件输出
    stcSevtTrgCond.enDownMatchCmd = Enable;//Disable;
    stcSevtTrgCond.enZeroMatchCmd = Disable;
    stcSevtTrgCond.enPeakMatchCmd = Disable;
    TIMER4_SEVT_SetTriggerCond(TIMER4_UNIT, Timer4SevtCh1, &stcSevtTrgCond); /* Set SEVT operation condition */




    /* Clear && Start CNT */
    TIMER4_CNT_ClearCountVal(TIMER4_UNIT);
    TIMER4_CNT_Start(TIMER4_UNIT);

wubangmi 发表于 2022-6-1 12:26

修改相对应的周期值你就应该能得到你想要的输出频率

sparrow054 发表于 2022-6-5 14:35

pwm不就是方波么?

andygirl 发表于 2022-6-7 21:04

还是找个例程吧~~

liguohong 发表于 2022-6-16 15:07

请问,您贴的源码部分“Timer4-SEVT”,在哪,没找到!

liguohong 发表于 2022-6-16 15:12

andygirl 发表于 2022-6-7 21:04
还是找个例程吧~~

例程太少,说明还不清楚

andygirl 发表于 2022-6-18 15:34

460的例程,真实的比较多~~
只是不像ST那样有讲解文档,不过,耐心看代码,还是比较有条理的

cyclefly 发表于 2022-6-20 20:47

问题解决的怎么样了

tpgf 发表于 2022-7-1 10:28

应该是可以设置的啊

qcliu 发表于 2022-7-1 10:39

只能自己啃代码了

gwsan 发表于 2022-7-1 11:03

这个代码好像不是很全啊

tfqi 发表于 2022-7-1 11:09

占空比在哪里设置的 呀

nawu 发表于 2022-7-1 11:17

对比一下其他例程

zljiu 发表于 2022-7-1 11:44

楼主是占空比的问题
页: [1]
查看完整版本: hc32f460的PWM输出问题