打印
[技术问答]

hc32f460的PWM输出问题

[复制链接]
1143|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yangjiaoshai|  楼主 | 2022-6-1 08:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在用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[31:0] = 0x0FF0 0FFF*****************************/
    if (TIMER4_OCO_UL_CH % 2u)
    {
        /* OCMR[31:0] Ox 0FF0 0FFF    0000 1111 1111 0000   0000 1111 1111 1111 */
        stcLowChCmpMode.enCntZeroLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit[27:26]  11 */
        stcLowChCmpMode.enCntZeroLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit[11:10]  11 */
        stcLowChCmpMode.enCntZeroLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit[31:30]  00 */
        stcLowChCmpMode.enCntZeroLowNotMatchHighNotMatchLowChOpState = OcoOpOutputHold;      /* bit[15:14]  00 */

        stcLowChCmpMode.enCntUpCntLowMatchHighMatchLowChOpState = OcoOpOutputReverse;        /* bit[25:24]  11 */
        stcLowChCmpMode.enCntUpCntLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;     /* bit[9:8]    11 */
        stcLowChCmpMode.enCntUpCntLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;        /* bit[19:18]  00 */

        stcLowChCmpMode.enCntPeakLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit[23:22]  11 */
        stcLowChCmpMode.enCntPeakLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit[7:6]    11 */
        stcLowChCmpMode.enCntPeakLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit[29:28]  00 */
        stcLowChCmpMode.enCntPeakLowNotMatchHighNotMatchLowChOpState = OcoOpOutputHold;      /* bit[13:12]  00 */

        stcLowChCmpMode.enCntDownLowMatchHighMatchLowChOpState = OcoOpOutputReverse;         /* bit[21:20]  11 */
        stcLowChCmpMode.enCntDownLowMatchHighNotMatchLowChOpState = OcoOpOutputReverse;      /* bit[5:4]    11 */
        stcLowChCmpMode.enCntDownLowNotMatchHighMatchLowChOpState = OcoOpOutputHold;         /* bit[17:16]  00 */

        stcLowChCmpMode.enCntZeroMatchOcfState = OcoOcfSet;    /* bit[3] 1 */
        stcLowChCmpMode.enCntUpCntMatchOcfState = OcoOcfSet;   /* bit[2] 1 */
        stcLowChCmpMode.enCntPeakMatchOcfState = OcoOcfSet;    /* bit[1] 1 */
        stcLowChCmpMode.enCntDownCntMatchOcfState = OcoOcfSet; /* bit[0] 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  设置死区 PDAR  PDBR
    TIMER4_PWM_WriteDeadRegionValue(TIMER4_UNIT, TIMER4_PWM_CHV, 20u,20u );//u16OcoOccrVal  设置死区 PDAR  PDBR
    TIMER4_PWM_WriteDeadRegionValue(TIMER4_UNIT, TIMER4_PWM_CHW, 20u,20u );//u16OcoOccrVal  设置死区 PDAR  PDBR




    /* 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 | 只看该作者
还是找个例程吧~~

使用特权

评论回复
5
liguohong| | 2022-6-16 15:07 | 只看该作者
请问,您贴的源码部分“Timer4-SEVT”,在哪,没找到!

使用特权

评论回复
6
liguohong| | 2022-6-16 15:12 | 只看该作者
andygirl 发表于 2022-6-7 21:04
还是找个例程吧~~

例程太少,说明还不清楚

使用特权

评论回复
7
andygirl| | 2022-6-18 15:34 | 只看该作者
460的例程,真实的比较多~~
只是不像ST那样有讲解文档,不过,耐心看代码,还是比较有条理的

使用特权

评论回复
8
cyclefly| | 2022-6-20 20:47 | 只看该作者
问题解决的怎么样了

使用特权

评论回复
9
tpgf| | 2022-7-1 10:28 | 只看该作者
应该是可以设置的啊

使用特权

评论回复
10
qcliu| | 2022-7-1 10:39 | 只看该作者
只能自己啃代码了

使用特权

评论回复
11
gwsan| | 2022-7-1 11:03 | 只看该作者
这个代码好像不是很全啊

使用特权

评论回复
12
tfqi| | 2022-7-1 11:09 | 只看该作者
占空比在哪里设置的 呀

使用特权

评论回复
13
nawu| | 2022-7-1 11:17 | 只看该作者
对比一下其他例程

使用特权

评论回复
14
zljiu| | 2022-7-1 11:44 | 只看该作者
楼主是占空比的问题

使用特权

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

本版积分规则

11

主题

43

帖子

2

粉丝