|
Projects\NUCLEO-L432KC\Examples\TIM\TIM_DMA\STM32CubeIDE.project smt32l432kcu6 TIM_DMA 例程,TimHandle.Init.RepetitionCounter = 3; 应该输出4个波形,但是启动时第一次会输出8个波形后面才会正常输出4个波形
|
motor profiler 链接nucleo 476rg时提示如图所示的通信错误,此时未连接IHM08M1,电脑上有476RG产生的串口,STLINK,U盘标识
STM32L496要加热才能运行
请教下,使用 filex 文件系统需要支持中文的目录及文件名要怎么配置呀 ?
50台设备共用一条CAN总线,会概率性丢包
STM32L431RCT6中文数据手册
STM32L431内部温度AD值不随温度变化
STM32L设置CAN一直卡在HAL_CAN_START(),上拉两个引脚依然卡在这里
使用CubeMX能配置STM32L4XX芯片的低功耗模式吗?
STM32L476 使用Quad spi 4线制访问MX25L25645 失败
小白求助!STM32L476使用VREF、VBAT采集模块电压,计算出的VBAT值偏大
微信公众号
手机版
[md]呵呵
是的,我发现了这个问题。
其实,这个地方涉及的细节好几个,难以几句说清楚。我整理了一下,你可以阅读参考。
一个STM32 TIMER例程的输出波形之解析
hi
我这边找到相应开发板及例程做了验证测试,的确可以发现你反馈的情况。细致~!
这个例程设计得还是有些巧妙的,不过也存在些瑕疵。代码里有两个地方稍微做下调整。
见下面粗体字符的地方。
/ Configure TIM1_Channel3 in output, push-pull & alternate function mode /
GPIO_InitStruct.Pin = GPIO_PIN_CHANNEL3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull =GPIO_NOPULL;**
/##-2- Configure the PWM channel 3 ########################################/
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.Pulse = 00;//aCCValue_Buffer[0];**
下面是我的最终输出结果:
非常感谢您的回答。但是又存在一个新的问题,占空比的顺序25%-75%-50%-25%,感觉应该75%-50%-25%,开头多了一个25%。你给出的图像中也可以看出。
[md]我把参数改成下方,第一个占空比变成了30%
[md]好厉害!图文并茂,深入浅出。我已经工作几年了。修改回答没有小铃铛提醒,要点进来才看到。大佬,是ST的官方人员吗
我有两个疑问点:
一、文章中有提到“程序在初始化代码里开启了CCR的预装功能”,我看初始化代码中没有 TimHandle.Init.AutoReloadPreload 这个参数。可能是固件库版本的原因,我用的是STM32Cube_FW_L4_V1.18.1,通过STM32CubeIDE自动下载的。
二、文章中有提到在占空比为0的情况下,在第1个周期发生比较事件时,因定时器通道的DMA请求能力还未使能而不能触发DMA传输。
我看到 HAL_TIM_PWM_Start_DMA 函数中,在定时器未开启的时候,有使能的代码,为什么说“定时器通道的DMA请求能力还未使能”呢。
HAL_TIM_PWM_Start_DMA(&TimHandle, TIM_CHANNEL_3, aCCValue_Buffer, 4) != HAL_OK
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length) != HAL_OK)
……
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
……
__HAL_TIM_ENABLE(htim);
同时还发现了一个新的现象,我修改了些参数,将预分频调整到了80-1,最后得到1us周期的计数(系统时钟调整到80Mhz);循环计数值调整到0;调整了一下占空比数组;DMA改为了单次传输;周期调整为了100us。
uwTimerPeriod = (uint32_t)100 - 1; // 100us
TimHandle.Init.Prescaler = 80 - 1;
TimHandle.Init.RepetitionCounter = 0;
uint32_t aCCValue_Buffer[100] = {0, 0, 0}; // 把这个数组的范围值调大了
aCCValue_Buffer[0] = 75;
aCCValue_Buffer[1] = 50;
aCCValue_Buffer[2] = 25;
aCCValue_Buffer[3] = 0; // 关闭
HAL_TIM_PWM_Start_DMA(&TimHandle, TIM_CHANNEL_3, aCCValue_Buffer, 4)
之后的波形就正常了。可以通过调整aCCValue_Buffer数组内容输出指定个数的脉冲,占空比也可以进行变化。比如
aCCValue_Buffer[0] = 75;
aCCValue_Buffer[1] = 50;
aCCValue_Buffer[2] = 25;
aCCValue_Buffer[3] = 25;
aCCValue_Buffer[4] = 50;
aCCValue_Buffer[5] = 75;
aCCValue_Buffer[6] = 0;
HAL_TIM_PWM_Start_DMA(&TimHandle, TIM_CHANNEL_3, aCCValue_Buffer, 7)
[md]呵呵
这个论坛的确还有可以完善的地方。
关于你提到的两个疑问点,这里一起交流下。
一、文章中有提到“程序在初始化代码里开启了CCR的预装功能”,我看初始化代码中没有 TimHandle.Init.AutoReloadPreload 这个参数。可能是固件库版本的原因,我用的是STM32Cube_FW_L4_V1.18.1,通过STM32CubeIDE自动下载的。
è 1、我目前使用的版本跟你一样的。
2、你提到的AutoReloadPreload 这个参数是针对ARR寄存器的不是针对CCR寄存器的。ARR和CCR寄存器都是带有预装控制位的。CCR的预装控制位由CCMR寄存器的OCxPE位控制。
3、在例程里,你可以通过阅读函数HAL_TIM_PWM_ConfigChannel()可知,CCR是先被赋值,然后才开启它的与装功能。
二、文章中有提到在占空比为0的情况下,在第1个周期发生比较事件时,因定时器通道的DMA请求能力还未使能而不能触发DMA传输。
我看到 HAL_TIM_PWM_Start_DMA 函数中,在定时器未开启的时候,有使能的代码,为什么说“定时器通道的DMA请求能力还未使能”呢。
==》这个疑问有普遍性。对于输出通道而言,当我们开启他们的输出功能时,比较输出功能就生效了,跟你是否开启计数器、是否使能相关中断或DMA触发能力没有关系。
具体到这里,如果CCR=0,当使能通道的输出功能时如果CNT也刚好等于0,比较输出事件就立即产生了。你知道,在调用HAL_TIM_PWM_Start_DMA()函数使能该比较事件的DMA请求能力已经是后面的事情了,所以第一个周期的比较事件就没能触发DMA。
至于你提到的现象,在我看来是可以理解的。你完全可以基于STM32手册和我分享的信息自行分析其来龙去脉。STM32 TIMER里有很多小细节,使用也很灵活。比方该例程的功能实现,方案可以有很多。你可以测试后回头去研读手册,这样可以事半功倍。
[md]好的,非常感谢~