我正在尝试使用 DMA 和 tiM6 外设将波形表写入 DAC 外设。
TIM6 确实按预期工作。
我还可以看到 DMA 通过 TIM6_TRGO 触发。
但是 DMA 传输会导致传输错误,从而导致 DAC 欠载运行。由于前者的错误,后者是预期的。
某些东西,我在导致 TE IRQ 被提升的 DMA 设置中丢失,但不知何故我对错误视而不见。有人可以再借一套眼球吗?
- static void SystemClock_Config(void)
- {
- LL_FLASH_SetLatency(LL_FLASH_LATENCY_7);
- LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
- LL_RCC_HSI_Enable();
- while (LL_RCC_HSI_IsReady() != 1) {} /* Wait till HSI is ready */
- LL_RCC_HSI_SetCalibTrimming(64);
- LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 75, LL_RCC_PLLR_DIV_2);
- LL_RCC_PLL_EnableDomain_SYS();
- LL_RCC_PLL_Enable();
- while (LL_RCC_PLL_IsReady() != 1) {} /* Wait till PLL is ready */
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
- /* Wait till System clock is ready */
- while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {}
- /* ensure 1µs transition state at intermediate medium speed clock based on DWT */
- CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- DWT->CYCCNT = 0;
- while (DWT->CYCCNT < 100);
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); /* Set AHB prescaler*/
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
- LL_RCC_SetAPB2Prescaler(LL_RCC_APB1_DIV_1);
- LL_Init1msTick(150000000);
- LL_SetSystemCoreClock(150000000);
- }
- int main(void)
- {
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG); /* SYSCFGEN */
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); /* PWREN */
- NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
- SystemClock_Config();
- uart_init();
- led_init();
- printf("nt------------------n");
- printf("tSTM32G474 DAC Testn");
- printf("t------------------n");
- dma_init();
- tim_init();
- dac_init();
- dac_enable(); /* Enable DAC */
- while (1) {}
- }
- static void dma_init(void)
- {
- LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); /* DMAMUX clk enable */
- LL_DMA_SetPeriphRequest(DMA1,
- LL_DMA_CHANNEL_1,
- LL_DMAMUX_REQ_DAC1_CH1); /* DMAMUX: DMA1_Ch1->DAC1_Ch1 */
- LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); /* enable DMA1 clock */
- /* DAC1_CH1 Init */
- LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
- LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
- LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
- LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
- LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);
- LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
- LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);
- /* Set DMA transfer addresses of source and destination */
- LL_DMA_ConfigAddresses(DMA1,
- LL_DMA_CHANNEL_1,
- (uint32_t ) sin_tbl_12b_32samples,
- LL_DAC_DMA_GetRegAddr(DAC1,
- LL_DAC_CHANNEL_1,
- LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED),
- LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
- LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, TABLE_SIZE);
- NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* enable DMA1 CH1 IRQ */
- LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); /* Enable TX error DMARQ */
- LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); /* Enable TC DMARQ */
- LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); /* Enable DMA transfer */
- }
- static void tim_init(void)
- {
- uint32_t clk, per, psc;
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM6); /* enable TMR clock */
- NVIC_EnableIRQ(TIM6_DAC_IRQn); /* enable TMR IRQ */
- if (LL_RCC_GetAPB1Prescaler() == LL_RCC_APB1_DIV_1)
- clk = __LL_RCC_CALC_PCLK1_FREQ(SystemCoreClock, LL_RCC_GetAPB1Prescaler());
- else
- clk = (__LL_RCC_CALC_PCLK1_FREQ(SystemCoreClock, LL_RCC_GetAPB1Prescaler()) * 2);
- /**
- * Timer prescaler calculation
- * Computation for timer 16 bits, additional + 1 to round the prescaler up
- */
- psc = ((clk / (TMR_PSC_MAX * TMR_FREQ_MIN)) + 1);
- per = (clk / (psc * TMR_FREQ)); /* Timer reload calculation */
- LL_TIM_SetPrescaler(TIM6, (psc - 1)); /* set timer pre-scaler value */
- LL_TIM_SetAutoReload(TIM6, (per - 1)); /* set timer auto-reload value */
- LL_TIM_SetCounterMode(TIM6, LL_TIM_COUNTERMODE_UP); /* set counter mode */
- LL_TIM_SetRepetitionCounter(TIM6, 0); /* set the repetition counter */
- LL_TIM_DisableARRPreload(TIM6);
- LL_TIM_SetTriggerOutput(TIM6, LL_TIM_TRGO_UPDATE); /* DAC trigger output */
- LL_TIM_DisableMasterSlaveMode(TIM6);
- LL_TIM_EnableIT_UPDATE(TIM6); /* enable Update IRQ */
- LL_TIM_EnableCounter(TIM6); /* enable counter */
- }
- static void dac_init(void)
- {
- LL_GPIO_InitTypeDef gpio = {0};
- LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_DAC1); /* enable DAC1 clock */
- LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); /* enable GPIOA clock */
- NVIC_EnableIRQ(TIM6_DAC_IRQn); /* enable DAC1 IRQ */
- gpio.Pin = LL_GPIO_PIN_4; /* PA.4 */
- gpio.Mode = LL_GPIO_MODE_ANALOG; /* PA.4 -> DAC1_OUT1 */
- gpio.Pull = LL_GPIO_PULL_NO;
- LL_GPIO_Init(GPIOA, &gpio);
- LL_DAC_SetSignedFormat(DAC1,
- LL_DAC_CHANNEL_1,
- LL_DAC_SIGNED_FORMAT_DISABLE); /* DAC channel OUT1 config */
- LL_DAC_SetWaveAutoGeneration(DAC1, /* diasble waveform generator */
- LL_DAC_CHANNEL_1,
- LL_DAC_WAVE_AUTO_GENERATION_NONE);
- LL_DAC_SetTriggerSource(DAC1,
- LL_DAC_CHANNEL_1,
- LL_DAC_TRIG_EXT_TIM6_TRGO); /* Select trigger source */
- LL_DAC_ConfigOutput(DAC1, /* Set the DAC channel output */
- LL_DAC_CHANNEL_1,
- LL_DAC_OUTPUT_MODE_NORMAL,
- LL_DAC_OUTPUT_BUFFER_ENABLE,
- LL_DAC_OUTPUT_CONNECT_GPIO);
- LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_1); /* Enable DAC DMARQ */
- // LL_DAC_EnableIT_DMAUDR1(DAC1); /* DAC Channel1 underrun IRQ */
- }
- void DMA1_Channel1_IRQHandler(void)
- {
- if (LL_DMA_IsActiveFlag_TE1(DMA1)) {
- printf("- TE -n");
- debug_dac();
- debug_dma();
- debug_dmach();
- LL_DMA_ClearFlag_TE1(DMA1);
- }
- if (LL_DMA_IsActiveFlag_TC1(DMA1)) {
- LL_DMA_ClearFlag_GI1(DMA1);
- LL_DMA_ClearFlag_TC1(DMA1);
- printf("- TC -n");
- }
- }
- void TIM6_DAC_IRQHandler(void)
- {
- if (LL_DAC_IsActiveFlag_DMAUDR1(DAC1)) { /* Check for DAC Ch1 underrun IRQ */
- // printf("- UDR -n");
- LL_DAC_ClearFlag_DMAUDR1(DAC1); /* Clear flag DAC Ch1 underrun */
- LL_DAC_DisableIT_DMAUDR1(DAC1);
- }
- if (LL_TIM_IsActiveFlag_UPDATE(TIM6)) {
- LL_TIM_ClearFlag_UPDATE(TIM6);
- LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
- }
- }
这导致以下输出:
- ------------------
- STM32G474 DAC Test
- ------------------
- - TE -
- --------------* DAC1 Debug *--------------
- Debug> DAC1->CR :0x101f
- Debug> DAC1->SWTRIGR :0x00
- Debug> DAC1->DHR12R1 :0x00
- Debug> DAC1->DHR12L1 :0x00
- Debug> DAC1->DHR8R1 :0x00
- Debug> DAC1->DHR12R2 :0x00
- Debug> DAC1->DHR12L2 :0x00
- Debug> DAC1->DHR8R2 :0x00
- Debug> DAC1->DHR12RD :0x00
- Debug> DAC1->DHR12LD :0x00
- Debug> DAC1->DHR8RD :0x00
- Debug> DAC1->DOR1 :0x00
- Debug> DAC1->DOR2 :0x00
- Debug> DAC1->SR :0x2800
- Debug> DAC1->CCR :0x1f001f
- Debug> DAC1->MCR :0x00
- Debug> DAC1->SHSR1 :0x00
- Debug> DAC1->SHSR2 :0x00
- Debug> DAC1->SHHR :0x10001
- Debug> DAC1->SHRR :0x10001
- Debug> DAC1->STR1 :0x00
- Debug> DAC1->STR2 :0x00
- Debug> DAC1->STMODR :0x00
- ------------------------------------------
- --------------* DMA1 Debug *--------------
- Debug> DMA1->ISR :0x09
- Debug> DMA1->IFCR :0x00
- ------------------------------------------
- --------------* DMA Chx Debug *--------------
- Debug> DMA_Ch1->CCR :0x5ba
- Debug> DMA_Ch1->CNDTR:0x20
- Debug> DMA_Ch1->CPAR :0x50000808
- Debug> DMA_Ch1->CMAR :0x8001cbe
- ------------------------------------------
有什么想法吗 ?
0
|
|
1个回答
|
|
|
|