目前使用HC32L176调试了一个通过TIMER5+DMA驱动WS2812B的软件,现在出现一个问题是DMA更改占空比时会出现第一个占空比丢失的情况,比如DMA实际传输的占空比数据是[16,16,16,44,44,16,16,44,44],TIMER5实际输出的PWM波形会出现只有[16,16,16,44,16,44]这样的,每次占空比值变化时就会丢失第一个变化的占空比值。
哪位有用过HC32L176的TIMER5+DMA驱动WS2812B的,给个参考,谢谢。
补充下内容:


定时器和DMA初始化:
void BspLed_DmaInit()
{
stc_dma_cfg_t stcDmaCfg;
DDL_ZERO_STRUCT(stcDmaCfg); //结构体变量 初始值清零
// 使能 DMA时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE);
stcDmaCfg.enMode = DmaMskBlock; //选择块传输
stcDmaCfg.u16BlockSize = 0x01u; //块传输个数
stcDmaCfg.u16TransferCnt = 300; //Block模式,一次传输数据大小为 3,传输三次
stcDmaCfg.enTransferWidth = DmaMsk8Bit; //传输数据的宽度,此处选择字(32Bit)宽度
stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc; //源地址自增
stcDmaCfg.enDstAddrMode = DmaMskDstAddrFix; //目的地址自增
stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable; //禁止重新加载传输目的地址
stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable; //使能重新加载传输源地址
stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable; //使能重新加载BC/TC值
stcDmaCfg.u32SrcAddress = (uint32_t) (&tim5_ocl_pwmdmabuff[0]);//指定传输源地址
stcDmaCfg.u32DstAddress = (uint32_t)&M0P_ADTIM5->GCMBR; //指定传输目的地址
//stcDmaCfg.u32DstAddress = (uint32_t)(&tim5_ocl_pwmdmabuff2[0]); //指定传输目的地址
stcDmaCfg.enTransferMode = DmaMskOneTransfer; //DMAC 在传输完成时不清除 CONFA:ENS 位。这个功能允许连续传输而不需要 CPU 干预。
stcDmaCfg.enRequestNum = DmaTIM5BTrig; //设置为ADC SQR触发
Dma_InitChannel(DmaCh0,&stcDmaCfg); //初始化DMA通道0
}
void BspLed_AdvTimerInit(uint16_t u16Period,uint16_t u16CHB_PWMDuty)
{
en_adt_compare_t enAdtCompareB;
stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
stc_adt_CHxX_port_cfg_t stcAdtTIM5BCfg;
stc_adt_irq_trig_cfg_t stcAdtTrigCfg;
DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
DDL_ZERO_STRUCT(stcAdtTIM5BCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdvTim, TRUE); //ADT外设时钟使能
stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode; //锯齿波模式
stcAdtBaseCntCfg.enCntDir = AdtCntUp;
stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0;
Adt_Init(M0P_ADTIM5, &stcAdtBaseCntCfg); //ADT载波、计数模式、时钟配置
Adt_SetPeriod(M0P_ADTIM5, u16Period); //周期设置
enAdtCompareB = AdtCompareB;
Adt_SetCompareValue(M0P_ADTIM5, enAdtCompareB, u16CHB_PWMDuty); //通用比较基准值寄存器B设置
stcAdtTIM5BCfg.enCap = AdtCHxCompareOutput;
stcAdtTIM5BCfg.bOutEn = TRUE;
stcAdtTIM5BCfg.enPerc = AdtCHxPeriodHigh;
stcAdtTIM5BCfg.enCmpc = AdtCHxCompareLow;
stcAdtTIM5BCfg.enStaStp = AdtCHxStateSelSS;
stcAdtTIM5BCfg.enStaOut = AdtCHxPortOutLow;
stcAdtTIM5BCfg.enStpOut = AdtCHxPortOutLow;
Adt_CHxXPortCfg(M0P_ADTIM5, AdtCHxB, &stcAdtTIM5BCfg); //端口CHB配置
stcAdtTrigCfg.bAdtCntMatchBTrigDmaEn = TRUE;
Adt_IrqTrigCfg(M0P_ADTIM5,&stcAdtTrigCfg);
}