//example_adc_circle.c
#ifdef IPS_ANALOG_IP
#include "example.h"
#include "analog_ip.h"
//
//开启DMA方式来循环读取ADC的多个channal的值
//读完后,数据放到adc_table数组。
//
//这里给出两个示例:
//一个是调用了DMAC_ConfigCircular,这个函数是SDK1.3.2以后新增的。一个是没使用这个函数的。
//其实两个示例最终走的流程都是一样的。
static uint32_t sclk_div = 9; // Divided by 20 = (9 + 1) * 2
static uint32_t adc_table[2]; //以下示例中只采集了两路,这里就给2就行了
// 测试循环读取ADC
DMAC_LLI_TypeDef circular_lli; //必须定义为全局或静态变量,不能是局部变量。因为DMA在运行中,会持续使用。局部变量在退出函数后会释放掉。
//使用了DMAC_ConfigCircular函数的。
void TestCircleAdc2()
{
PERIPHERAL_ENABLE(DMAC, 0);
DMAC_Init();
ADC_SetSeqLength(ADC0, ADC_SEQ_LENGTH2); // 设置DMA要读取的ADC的channal数
ADC_SetSeqChannel(ADC0, 0, ADC_CHANNEL3); // channal-A,配置第一个channal。第二个参数seq决定dma读完后放到 adc_table 的哪个位置。
ADC_SetSeqChannel(ADC0, 1, ADC_CHANNEL4); // channal-B,配置第二个channal
DMAC_ConfigCircular(DMAC_CHANNEL1, //DMA的channal(跟ADC的channal无关)
(uint32_t)&ADC0->DATA, //从哪个ADC读取
(uint32_t)adc_table, //存放数据的数组
DMAC_ADDR_INCR_OFF, DMAC_ADDR_INCR_ON,
DMAC_WIDTH_32_BIT, DMAC_WIDTH_32_BIT, //32位的,不能是16位
DMAC_BURST_1, DMAC_BURST_1,
2, //一轮读取几个。跟上边的channal数对应。
DMAC_PERIPHERAL_TO_MEM_DMA_CTRL, ADC0_DMA_REQ, 0,
&circular_lli); //lli,注意这里要加取值符&
ADC_StartDma(ADC0, sclk_div); //开启DMA
while(1)
{
printf("adc value:%d, %d\r\n", adc_table[0], adc_table[1]);
UTIL_IdleUs(200e3);
}
}
// 没有使用 DMAC_ConfigCircular 函数。
// 这里的配置方法,和上边的函数是一致的。注释部分参考上边的函数。
void TestCircleAdc()
{
PERIPHERAL_ENABLE(DMAC, 0);
DMAC_Init();
ADC_SetSeqLength(ADC0, ADC_SEQ_LENGTH2); // Scan channels number
ADC_SetSeqChannel(ADC0, 0, ADC_CHANNEL3); // channal-A
ADC_SetSeqChannel(ADC0, 1, ADC_CHANNEL4); // channal-B
circular_lli.SrcAddr = (uint32_t)&ADC0->DATA;
circular_lli.DstAddr = (uint32_t)adc_table;
circular_lli.LLI = (uint32_t)&circular_lli; // Points to itself for circular transfer
circular_lli.Control = DMAC_MakeControl(DMAC_ADDR_INCR_OFF, DMAC_ADDR_INCR_ON,
DMAC_WIDTH_32_BIT, DMAC_WIDTH_32_BIT, DMAC_BURST_1, DMAC_BURST_1, 2, DISABLE);
DMAC_ConfigLLI(DMAC_CHANNEL1, DMAC_PERIPHERAL_TO_MEM_DMA_CTRL, ADC0_DMA_REQ, 0, (uint32_t)&circular_lli);
ADC_StartDma(ADC0, sclk_div);
while(1)
{
printf("adc value:%d, %d\r\n", adc_table[0], adc_table[1]);
UTIL_IdleUs(200e3);
}
}
#endif