DAC - dma

本 demo 主要介绍基于 DAC DMA 模式生成正弦波。

硬件连接

本 demo 使用到的 gpio 参考 board_dac_gpio_init

软件实现

更详细的代码请参考 examples/peripherals/dac/dac_dma

1board_init();
  • board_init 中会开启 DAC IP 时钟,并选择 DAC 时钟源和分频。

1board_dac_gpio_init();
  • 配置相关引脚为 DAC 功能

1dac = bflb_device_get_by_name("dac");
2
3/* 512K / 1 = 512K */
4bflb_dac_init(dac, DAC_CLK_DIV_1);
5bflb_dac_channel_enable(dac, DAC_CHANNEL_A);
6bflb_dac_channel_enable(dac, DAC_CHANNEL_B);
7bflb_dac_link_txdma(dac, true);
  • 获取 dac 句柄,并初始化 dac 频率为 512K

  • bflb_dac_channel_enable 配置 dac 通道信息,当前使用的 A 通道和 B 通道

  • bflb_dac_link_txdma 开启 dac txdma 功能

 1dma0_ch0 = bflb_device_get_by_name("dma0_ch0");
 2
 3struct bflb_dma_channel_config_s config;
 4
 5config.direction = DMA_MEMORY_TO_PERIPH;
 6config.src_req = DMA_REQUEST_NONE;
 7config.dst_req = DMA_REQUEST_DAC;
 8config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
 9config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
10config.src_burst_count = DMA_BURST_INCR1;
11config.dst_burst_count = DMA_BURST_INCR1;
12config.src_width = DMA_DATA_WIDTH_16BIT;
13config.dst_width = DMA_DATA_WIDTH_16BIT;
14bflb_dma_channel_init(dma0_ch0, &config);
15
16bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL);
  • 配置 DMA CH0DAC

  • 注册 dma 通道中断

 1struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */
 2struct bflb_dma_channel_lli_transfer_s transfers[1];
 3
 4transfers[0].src_addr = (uint32_t)SIN_LIST;
 5transfers[0].dst_addr = (uint32_t)DMA_ADDR_DAC_TDR;
 6transfers[0].nbytes = sizeof(SIN_LIST);
 7bflb_l1c_dcache_clean_range((void*)SIN_LIST,sizeof(SIN_LIST));
 8
 9bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1);
10bflb_dma_channel_start(dma0_ch0);
11
12while (dma_tc_flag0 != 1) {
13    bflb_mtimer_delay_ms(1);
14}
  • 分配一块 lli 内存池,个数为1,最多可以传输 4064 * 1 字节

  • 配置一块内存进行传输

  • 调用 bflb_dma_channel_lli_reload 初始化

  • 调用 bflb_dma_channel_start 启动传输

  • 等待传输完成并进入中断

编译和烧录

参考 环境搭建

实验现象

DAC Channel A 和 B 对应的 GPIO 输出正弦波。