最近有用这个芯片弄一些东西,记录一下调试DMA串口搬运数据的过程。

和其他芯片有所不同,这个一定得要配置DMAMUX的时钟,两个DMA的时钟才能激活DMA(调试1天的辛苦感悟。。。)其余的正常配置,这个芯片的DMA通道比较厉害,不需要指定,填地址就行;

串口就正常配置 ,DMA的有所不同,这里我配置的是串口6,以下是示例:

 void uart6_config(void)
{
    /* enable GPIO clock */ 
    rcu_periph_clock_enable(RCU_GPIOE);  

    /* enable USART clock */
    rcu_periph_clock_enable(RCU_UART6);    

    /* connect port to USART0 TX */
    gpio_af_set(GPIOE, GPIO_AF_7, GPIO_PIN_8);   

    /* connect port to USART0 RX */
    gpio_af_set(GPIOE, GPIO_AF_7, GPIO_PIN_7);   

	 /* configure UART TX as alternate function push-pull */  
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);

    /* configure UART RX as alternate function push-pull */
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7);

    /* USART配置 */
    usart_deinit(UART6); // 重置UART6
    usart_word_length_set(UART6, USART_WL_8BIT); // 设置字长为8位
    usart_stop_bit_set(UART6, USART_STB_1BIT); // 设置停止位为1位
    usart_parity_config(UART6, USART_PM_NONE); // 设置无奇偶校验
    usart_baudrate_set(UART6, 115200U); // 设置波特率为115200
    usart_receive_config(UART6, USART_RECEIVE_ENABLE); // 使能接收
    usart_transmit_config(UART6, USART_TRANSMIT_ENABLE); // 使能发送
    usart_enable(UART6); // 使能UART6
		
}
	
void usart6_dma_cfg(void)
{
    uart6_config();
		// DMA单数据传输参数结构体
    dma_single_data_parameter_struct dma_init_struct;
		    /* enable USART clock */
    rcu_periph_clock_enable(RCU_DMA1); 
    rcu_periph_clock_enable(RCU_DMAMUX);
		//nvic6_config();
    /* clean d-cache by address before DMA transmission */   //在DMA传输之前清除D-cache
    SCB_CleanDCache_by_Addr((uint32_t*)txbuffer6, BUFFER_SIZE6);
    /* initialize DMA channel 0 */
    dma_deinit(DMA1, DMA_CH4);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.request      = DMA_REQUEST_UART6_TX;    // 请求源为USART6 TX
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;    // 内存到外设
    dma_init_struct.memory0_addr = (uint32_t)txbuffer6;       // 内存地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // 外设数据宽度8位
    dma_init_struct.number       = ARRAYNUM6(txbuffer6);       // 传输数据量
    dma_init_struct.periph_addr  = (uint32_t)UART6_TDATA_ADDRESS; // 外设地址
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
    dma_init_struct.priority     = DMA_PRIORITY_MEDIUM; // 优先级中等
    dma_single_data_mode_init(DMA1, DMA_CH4, &dma_init_struct);  //
    usart_dma_transmit_config(UART6, USART_TRANSMIT_DMA_ENABLE); //配置USART DMA传输
		//nvic_irq_enable(DMA1_Channel4_IRQn, 5, 0);
    /* configure DMA mode */
    dma_circulation_disable(DMA1, DMA_CH4);  // 禁用循环模式
    dma_interrupt_enable(DMA1, DMA_CH4, DMA_CHXCTL_FTFIE);
    /* enable DMA channel 4 */
    dma_channel_enable(DMA1, DMA_CH4);
}

激活通道的瞬间:   dma_channel_enable(DMA1, DMA_CH4);  DMA就会去搬运数据啦

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐