
STM32F103C8T6 TIM1 CH2输入捕获触发DMA的问题 最近在基于STM32F103C8T6同时使用LL库调试 TIM1 CH2输入捕获触发DMA的时候遇到点问题: 我的期望是,通过TIM1 CH2捕获到上升沿后,触发DMA传输,将内存数据搬运到TIM1 CCR1寄存器,以修改PWM占空比; 现状是: 1.DMA TC中断远比我想象来的慢,表现为触发脉冲以及经过数十个后,才能进入一次TC中断; 2.在整个过程中TIM1 CCR1寄存器的值没有改变,那为什么还会触发DMA TC中断呢?整个过程中传输的数据去哪了? 3.在DMA请求映像中 DMA1 CH3可以被TIM1 CH2所触发,但是在CUBEMX中却没有对应的配置,是否意味着这样操作不可行亦或是CUBEMX本身的问题? 期待路过的诸位能帮忙解答,不胜感激! 相关代码如下: “/* TIM1 init function */void MX_TIM1_Init(void){ /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ LL_TIM_InitTypeDef TIM_InitStruct = {0}; LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /**TIM1 GPIO Configuration PA9 ------> TIM1_CH2 */ GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ TIM_InitStruct.Prescaler = 0; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 2; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; TIM_InitStruct.RepetitionCounter = 0; LL_TIM_Init(TIM1, &TIM_InitStruct); LL_TIM_EnableARRPreload(TIM1); LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; TIM_OC_InitStruct.CompareValue = 0; TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); LL_TIM_OC_EnableFast(TIM1, LL_TIM_CHANNEL_CH1); LL_TIM_SetTriggerInput(TIM1, LL_TIM_TS_TI2FP2); LL_TIM_SetSlaveMode(TIM1, LL_TIM_SLAVEMODE_RESET); LL_TIM_CC_DisableChannel(TIM1, LL_TIM_CHANNEL_CH2); LL_TIM_IC_SetFilter(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); LL_TIM_DisableIT_TRIG(TIM1); LL_TIM_DisableDMAReq_TRIG(TIM1); LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET); LL_TIM_DisableMasterSlaveMode(TIM1); LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; TIM_BDTRInitStruct.DeadTime = 0; TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_LOW; TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct); /* USER CODE BEGIN TIM1_Init 2 */ /* TIM1 OC配置修正 */ TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; // 启用主通道 TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_ENABLE; // 启用互补通道 LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH2);// 启用TIM1通道2的捕获功能/* DMA触发配置修正 */ LL_TIM_SetSlaveMode(TIM1, LL_TIM_SLAVEMODE_TRIGGER); LL_TIM_DisableDMAReq_UPDATE(TIM1); LL_TIM_EnableDMAReq_CC2(TIM1); // 使用通道2的捕获事件触发DMA LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE); LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_3, (uint32_t)&TIM1->CCR1); LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_3, (uint32_t)line_buffer0); LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, (sizeof(line_buffer0) / sizeof(line_buffer0[0]))); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3); NVIC_SetPriority(DMA1_Channel3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); NVIC_EnableIRQ(DMA1_Channel3_IRQn); LL_TIM_EnableAllOutputs(TIM1); LL_TIM_EnableCounter(TIM1); /* USER CODE END TIM1_Init 2 */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /**TIM1 GPIO Configuration PB13 ------> TIM1_CH1N PA8 ------> TIM1_CH1 */ GPIO_InitStruct.Pin = CURSOR_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(CURSOR_GPIO_Port, &GPIO_InitStruct); GPIO_InitStruct.Pin = CROSSHAIR_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(CROSSHAIR_GPIO_Port, &GPIO_InitStruct); }” |
触发波形
关于stm32cubeide下载问题
使用cubemx更新代码时,自己添加的文件丢失如何解决
STM32CubeMX 6.14版本来了
无法在STM32CubeMX中找到STM32H723ZGT6的USB_OTG_FS配置?
yolov5 转onnx 在cubeAI进行部署的时候 部署失败 我想一下大佬们这是什么原因
STM32U575 串口接收+GPDMA 波特率不匹配导致失败
依然是老问题STM32CubeMX升级问题
STM32H523中FLASH扇区擦除到0x8020000后面时擦除不干净,前面的扇区擦除是正常的,是芯片原因吗?
stm32的同一个定时器,不同的通道,可以不同时的输出pwm波形吗
USB Device + FatFS + 外挂 flash
这里就你的问题逐一做些交流:
1.DMA TC中断远比我想象来的慢,表现为触发脉冲以及经过数十个后,才能进入一次TC中断;
==》应该没有这个说法。DMA TC中断基于DMA传输完成事件而产生,它的快慢跟一轮传输中请求个数和快慢有关。
比方一轮传输涉及5个请求和50个请求的TC产生时间自然不一样,每1秒产生1个请求和每10秒产生1个请求使得最终产生DMA TC事件的时间肯定也不一样。
具体到你这里,到底触发几次后进TC中断是你决定的。当然,前提是DMA已经正常工作了。
2.在整个过程中TIM1 CCR1寄存器的值没有改变,那为什么还会触发DMA TC中断呢?整个过程中传输的数据去哪了?
==》这个要具体看。首先要看硬件上是否支持,即所选择的DMA通道是否能前往源端和目的端。如果硬件上支持而你实际上又没实现,那就得检查你的配置。
我这边查阅了技术手册相关内容,硬件是支持的。那么问题可能就出在你的配置方面。
3.在DMA请求映像中 DMA1 CH3可以被TIM1 CH2所触发,但是在CUBEMX中却没有对应的配置,是否意味着这样操作不可行亦或是CUBEMX本身的问题?
==》估计你看漏了,或者是哪里理解错了。使用cubeMx配置,可以看到基于TIM1-CH2事件所申请的DMA通道正是DMA1-CH3.
针对上面第2点,我找到F1系列开发板做了进一步验证确认,的确是可以实现的。即TIM1-CH2的捕获事件触发DMA,DMA将内存数据搬运到TIM1-CCR1寄存器以调整PWM输出。我使用HAL库验证,而不是LL库。验证结果可以给你信心。这里特意提醒的是,DMA的源端、目的端别配置错了,尤其是别配反了。
我这里基于CH2的捕获事件触发DMA传输,DMA做4次传输后就 停下,那么CCR1的数据应该停止0x12ab。
另外改变CCR去调整PWM,不能立刻生效,否则会引起脉冲过长或过短。 通常都是用更新事件触发的。
感谢!
请问你的意思是通过TI2FP2捕获,产生更新事件,之后由更新事件触发DMA,将内存数据写入CCR1寄存器吗?
感谢帮助!** **我也用示波器测试过,脉冲的时间间隔约32us,目前使用TIM1 CC2事件触发DMA传输,但现象仍为触发脉冲数十个后才完成TC中断,为此我做了如下验证:
修改DMA触发后传输的数据量为20,LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, 20);
此时经过20个脉冲后,DMA TC中断触发;
同样的,修改DMA触发后传输的数据量为10,LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, 10);
此时经过10个脉冲后,DMA TC中断触发;
也就意味着DMA的传输周期变为了单个触发事件只能传输一次数据,达到预设的数据量后,才完成中断,而不是我设想的每次捕获到脉冲上升沿,触发DMA 传输,将缓冲区内的数据全部传输至CCR1寄存器,请问是什么原因?
配置代码如下:
“
/ TIM1 init function /** void MX_TIM1_Init(void) **{
//** LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, (sizeof(line_buffer0) / sizeof(line_buffer0[0]))); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);**
}
”
DMA中断函数如下:
“
/**
”
而不是我设想的每次捕获到脉冲上升沿,触发DMA 传输,将缓冲区内的数据全部传输至CCR1寄存器,请问是什么原因?**
你说 触发1次 要将缓冲区的数据全部传输到CCR1寄存器,如何理解? 触发1次对CCR1连续写N次? 你具体什么意思,能详细点吗?
是这样的,我的期望是假设缓冲区内有10个数据,我需要在TIM1 CH2捕获到上升沿后,将这10个数据通过DMA传输至TIM1 CCR1,并且这个操作要在下一次TIM1 CH2的上升沿到来之前完成,也即在32us内完成这个操作;
而实际现象是,在TIM1 CH2的上升沿到来之际,DMA只传输了一个数据,经过10个上升沿之后,DMA才将数据传输完成,触发TC中断,此过程耗时为32*10us;
所以我的意思是,执行触发一次对CCR1连续写10次的操作;
[md]呵呵~
假设触发一次,DMA连续帮你搬10次,请问你连续对ccr1寄存器写10次的目的何在呢?
当然,你现在的设计也的确 不能一次触发请求,实现多次传输。
[md]我这个问题的背景是通过VGA信号的行频来同步RGB信号的传输,因为不需要考虑亮度,就只需要在对应行的像素点处置高低电平即可,然后我希望能通过捕获HSYNC信号上升沿来当作同步信号的开始,之后将一整行的像素点通过DMA同步传输至CCR1寄存器,但目前看这样配置不合适,
然后我想通过TIM1捕获后,触发TIM2从模式,通过TIM2的更新事件作为像素时钟用于DMA传输的同步,但目前按照想法配置之后,又出现了TIM2没有启动,CNT未增加的问题😢,不知大佬可否过目?
/ TIM1 init function / void MX_TIM1_Init(void) {
/ USER CODE BEGIN TIM1_Init 0 / LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); / USER CODE END TIM1_Init 0 /
LL_TIM_InitTypeDef TIM_InitStruct = {0}; LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/ Peripheral clock enable / LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /*TIM1 GPIO Configuration PA9 ------> TIM1_CH2 / GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/ USER CODE BEGIN TIM1_Init 1 /
/ USER CODE END TIM1_Init 1 / TIM_InitStruct.Prescaler = 0; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 2; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; TIM_InitStruct.RepetitionCounter = 0; LL_TIM_Init(TIM1, &TIM_InitStruct); LL_TIM_EnableARRPreload(TIM1); LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; TIM_OC_InitStruct.CompareValue = 0; TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); LL_TIM_OC_EnableFast(TIM1, LL_TIM_CHANNEL_CH1); LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_OC2REF); LL_TIM_EnableMasterSlaveMode(TIM1); LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); LL_TIM_IC_SetFilter(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; TIM_BDTRInitStruct.DeadTime = 0; TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_LOW; TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct); / USER CODE BEGIN TIM1_Init 2 / TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_ENABLE; LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH2);
LL_TIM_EnableAllOutputs(TIM1); LL_TIM_EnableCounter(TIM1);
/ USER CODE END TIM1_Init 2 / LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /*TIM1 GPIO Configuration PB13 ------> TIM1_CH1N PA8 ------> TIM1_CH1 / GPIO_InitStruct.Pin = CURSOR_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(CURSOR_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CROSSHAIR_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(CROSSHAIR_GPIO_Port, &GPIO_InitStruct); } / TIM2 init function / void MX_TIM2_Init(void) {
/ USER CODE BEGIN TIM2_Init 0 /
/ USER CODE END TIM2_Init 0 /
LL_TIM_InitTypeDef TIM_InitStruct = {0};
/ Peripheral clock enable / LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
/ TIM2 DMA Init /
/ TIM2_UP Init / LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_VERYHIGH);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_HALFWORD);
/ USER CODE BEGIN TIM2_Init 1 /
/ USER CODE END TIM2_Init 1 / TIM_InitStruct.Prescaler = 0; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 2; TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; LL_TIM_Init(TIM2, &TIM_InitStruct); LL_TIM_EnableARRPreload(TIM2); LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_ITR0); LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_TRIGGER); LL_TIM_DisableIT_TRIG(TIM2); LL_TIM_DisableDMAReq_TRIG(TIM2); LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE); LL_TIM_EnableMasterSlaveMode(TIM2); / USER CODE BEGIN TIM2_Init 2 /
LL_TIM_SetUpdateSource(TIM2, LL_TIM_UPDATESOURCE_REGULAR); LL_TIM_EnableDMAReq_UPDATE(TIM2); LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)&TIM1->CCR1); LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)line_buffer0); LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, 10); // LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, (sizeof(line_buffer0) / sizeof(line_buffer0[0]))); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); NVIC_EnableIRQ(DMA1_Channel2_IRQn); / USER CODE END TIM2_Init 2 / }
[md]对你应用需求不太清晰。
如果你确认是要对CCR1做写操作,最终目的应该是调整PWM的脉宽。检测到CH2上沿触发事件后,要按什么样的节奏去改写CCR1呢,随便多快多慢 只要32us内 改写10次就行?我想这里应该有个用来控制修改CCR1快慢的机制存在。
先把原理弄清楚,再来组织、整理代码。
[md]是的,我也这么想,目前的问题点就在如何让DMA的传输与CH2的捕获同步,以及如何让CCR1更新的周期满足我的期望