|
我想将lptim_wkup信号映射到EXTI模块,并在EXTI_CPUIMR2中屏蔽掉LPTIM5的中断输入,在EXTI_CPUEMR2开启LPTIM5的事件输入。根据Table 127. DMAMUX2: assignment of trigger inputs to resources,将LPTIM5的事件Lptim5_ait作为14号Trigger input输入到DMAMUX2 Request generator,将DMAMUX2_RequestGenerator0的DMAMUX2_RGxCR寄存器的SIG_ID[4:0]配置为14,并根据Table 126. DMAMUX2: assignment of multiplexer inputs to resources,将DMAMUX2_Channel0的DMAMUX2_CxCR寄存器的DMAREQ_ID[4:0]配置为1,使得dmamux2_req_gen0作为DMAMUX2_Channel0的DMA request MUX input,生成dmamux_req_outx后输入到BDMA channel 0。 RCC_D3CCIPR寄存器采用默认值,将 rcc_pclk4 时钟选作LPTIM3,4,5 内核时钟源。并在RCC的APB4ENR寄存器中配置RCC_APB4ENR_LPTIM5EN。 LPTIM5的CFGR寄存器bit0位CKSEL复位后默认为0,即LPTIM5 由内部时钟源(APB 时钟或任意内置振荡器)提供时钟,不需要额外配置。 我的配置代码如下: RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN; RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN; RCC->APB4ENR |= RCC_APB4ENR_LPTIM5EN; void lptim5_eps_lat_init(void) { GPIO_Set(GPIOA, PIN3, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_HIGH, GPIO_PUPD_PU); // 复用功能,上拉输出 GPIO_AF_Set(GPIOA, 3, 3); // PA3, AF3 LPTIM5->CFGR |= LPTIM_CFGR_PRELOAD; // bit22 = 1: 启用ARR预装载 LPTIM5->ARR = 7; // 设定计数器自动重装值 LPTIM5->CMP = 5; // 高电平为1/4占空比 } void lptim5_eps_lat_start(void) { LPTIM5->CR |= LPTIM_CR_ENABLE; // 使能定时器 LPTIM5->CR |= LPTIM_CR_CNTSTRT; // 定时器以连续模式启动 } void lptim5_eps_lat_stop(void) { LPTIM5->CR &= (~LPTIM_CR_ENABLE); // 停止定时器 } void EXTIX_Init(void) { EXTI->IMR2 &= ~EXTI_IMR2_IM53; // 0: 屏蔽来自 x 线的中断请求, 不生成中断 EXTI->EMR2 |= EXTI_EMR2_EM53; // 1: 取消屏蔽来自线 x 的事件请求, 生成wkup事件 触发DMA } void BDMA_Config(BDMA_Channel_TypeDef *BDMA_Channelx, u8 trg, u8 gen, u8 req, u32 par, u32 mar, u8 dir) { u8 chl = ((u32)BDMA_Channelx - (u32)BDMA_Channel0_BASE) / 0x14; // 得到通道号; DMAMUX_Channel_TypeDef *DMAMUX2ChannelxREQ_CCR = (DMAMUX_Channel_TypeDef *)(DMAMUX2_Channel0_BASE + chl * 4); // DMAMUX2 channel for BDMA, 偏移地址:0x04 * x(x = 0 到 7) DMAMUX_ChannelStatus_TypeDef *DMAMUX2ChannelxREQ_CSFR = (DMAMUX_ChannelStatus_TypeDef *)(DMAMUX2_ChannelStatus_BASE + chl * 4); BDMA_Channelx->CCR &= ~BDMA_CCR_EN; // 关闭BDMA传输 while (BDMA_Channelx->CCR & BDMA_CCR_EN_Msk); // 等待BDMA可配置 DMAMUX_RequestGen_TypeDef *DMAMUX2ChannelxRG = (DMAMUX_RequestGen_TypeDef *)(DMAMUX2_RequestGenerator0_BASE + gen * 4); DMAMUX_RequestGenStatus_TypeDef *DMAMUX2ChannelxRG_CSFR = (DMAMUX_RequestGenStatus_TypeDef *)(DMAMUX2_RequestGenStatus_BASE + chl * 4); DMAMUX2ChannelxRG_CSFR->RGCFR |= 1 << gen; // 溢出标志 OFx 清零 DMAMUX2ChannelxRG->RGCR |= trg & DMAMUX_RGxCR_SIG_ID_Msk; // 触发输入 Trigger input, 生成DMAMUX2 request generator信号 DMAMUX2ChannelxRG->RGCR |= DMAMUX_RGxCR_GE; // DMA request generator channel x enable DMAMUX2ChannelxREQ_CSFR->CFR |= 1 << chl; // 溢出标志 SOFx 清零 DMAMUX2ChannelxREQ_CCR->CCR |= req & DMAMUX_CxCR_DMAREQ_ID_Msk; // DMA 请求标识 (DMA request identification) BDMA->IFCR = 0xF << (4 * chl); // 清空之前该 channel 上的所有中断标志 (CGIFx, CTEIFx, CHTIFx, CTCIFx) BDMA_Channelx->CPAR = par; // BDMA 外设地址 BDMA_Channelx->CMAR = mar; // BDMA 存储器地址 BDMA_Channelx->CCR = 0; // 先全部复位CCR寄存器值 BDMA_Channelx->CCR |= dir; // 数据传输方向 BDMA_Channelx->CCR &= BDMA_CCR_CIRC_NO; // 非循环模式(即使用普通模式) BDMA_Channelx->CCR &= BDMA_CCR_PINC_NO; // 外设非增量模式 BDMA_Channelx->CCR |= BDMA_CCR_MINC; // 存储器增量模式 BDMA_Channelx->CCR |= BDMA_CCR_PSIZE_16; // 外设数据长度:16位 BDMA_Channelx->CCR |= BDMA_CCR_MSIZE_16; // 存储器数据长度:16位 BDMA_Channelx->CCR |= BDMA_CCR_PL_H; // 高优先级 BDMA_Channelx->CCR |= BDMA_CCR_TCIE; // 启用传输完成中断 } void BDMA_Enable(BDMA_Channel_TypeDef *BDMA_Channelx, u16 ndtr) { BDMA_Channelx->CCR &= ~BDMA_CCR_EN; // 关闭BDMA传输 while (BDMA_Channelx->CCR & BDMA_CCR_EN_Msk); // 确保BDMA可以被设置 BDMA_Channelx->CNDTR = ndtr; // 要传输的数据项数目 BDMA_Channelx->CCR |= BDMA_CCR_EN; // 开启BDMA传输 } void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group) { u32 temp, temp1; temp1 = (~NVIC_Group) & 0x07; // 取后三位 temp1 <<= 8; temp = SCB->AIRCR; // 读取先前的设置 temp &= 0X0000F8FF; // 清空先前分组 temp |= 0X05FA0000; // 写入钥匙 temp |= temp1; SCB->AIRCR = temp; // 设置分组 } void MY_NVIC_Init(u8 NVIC_PreemptionPriority, u8 NVIC_SubPriority, u8 NVIC_Channel, u8 NVIC_Group) { u32 temp; MY_NVIC_PriorityGroupConfig(NVIC_Group); // 设置分组 temp = NVIC_PreemptionPriority << (4 - NVIC_Group); temp |= NVIC_SubPriority & (0x0f >> NVIC_Group); temp &= 0xf; // 取低四位 NVIC->ISER[NVIC_Channel / 32] |= 1 << NVIC_Channel % 32; // 使能中断位(要清除的话,设置ICER对应位为1即可) NVIC->IP[NVIC_Channel] |= temp << 4; // 设置响应优先级和抢断优先级 } 并调用以下代码进行初始化: lptim5_eps_lat_init(); // 115.5Mhz/16.5MHz=7 EXTIX_Init(); BDMA_Config(BDMA_Channel0, 14, 0, 1, (u32)&GPIOD->ODR, (u32)buf_wdba_tx, BDMA_CCR_DIR); // Lptim5_ait=14 dmamux2_req_gen0=1 MY_NVIC_Init(0, 3, BDMA_Channel0_IRQn, 2); // 抢占0,子优先级3,组2 BDMA_Enable(BDMA_Channel0, BUF_SIZE_WDBA_TX); lptim5_eps_lat_start(); 但是在以下的BDMA_Channel0中断处理函数中,就没有收到完成中断,也没收到错误中断 void BDMA_Channel0_IRQHandler(void) { if (BDMA->ISR & BDMA_ISR_TCIF0) { BDMA->IFCR |= BDMA_IFCR_CTCIF0; // 清完成标志 lptim5_eps_lat_stop(); } if (BDMA->ISR & BDMA_ISR_TEIF0) { BDMA->IFCR |= BDMA_IFCR_CTEIF0; // 错误处理 } } |
【经验分享】STM32H7 DMA+UART不定长接收实战:解决缓存溢出与数据错位问题
STM32H747 D2域的问题
官方有没有成熟的FTL
STM32H743 以太网 为什么需要设置在0x30040000才能使用
DMAMUX 使用内部外设Request Event(不使用TIM12和LPTIM)
STM32H743 的ADC线性校准问题
NUCLEO-H7S3L8开发板,操作板载FLASH出错,无法进入APP
H743 ulpi phy 引脚配置
STM32H747XG下载一次仿真器就检测不到,运行不能正常
——STM32H747XG下载一次仿真器就检测不到,运行不能正常 原理图是否有问
微信公众号
手机版