|
这篇文章将通过NVIC来分析AT32A403A的ADC和DMA。
首先这里我要吐槽一点,雅特力的AT32A403A的参考手册和数据手册竟然都没有专门的篇幅讲NVIC,有也是散在了系统介绍中的《中断和异常向量》章节,像什么抢占优先级和子优先级都没介绍,这点对我来说是个不足的地方。
接着上一篇的的配置和程序,这次要开启NVIC中断。
一个是DMA的中断。DMA的中断总共有3种,这里我们选择传输完中断DMA_FDT_INT,使能方式也比较简单,就是在之前的代码上修改一下。
一个是ADC的中断,总共也有3种中断源,这里我选择通道转换结束标志位ADC_CCE_INT,使能要加一条语句:adc_interrupt_enable(ADC1, ADC_CCE_INT, TRUE);
然后要配置NVIC,这里选择NVIC_PRIORITY_GROUP_4,也就是16级的抢占优先级,数字越小优先级越高,系统级中断都是0级抢占优先级。
然后要在at32a403a_int.c里面添加对应的中断入口,当然了,这些WB都能生成的。在对应的中断入口函数中,首先要清零对应的中断标志位,这里为了查看中断发生的时间等参数,我在DMA传输完成后翻转LED2,ADC1转换好后翻转LED3.
这里注意一点,我发现在ADC的中断服务函数里面不加上adc_flag_clear(ADC1, ADC_CCE_INT);也就是不清零通道转换结束标志位也可以,刚开始我很奇怪,后来发现单片机内部在读取ADC的数据寄存器时就会自动清零了,而DMA已经设计好在转换好后读取ADC的数据寄存器,所以不软件清零也没关系,但是这只是这个标志位特殊,所以强烈建议在以后进入对应的中断服务函数后,一定首先要清零对应标志位。
最后用逻辑分析仪查看对应中断的时间。白色的是DMA中断、橙色的是ADC中断。
首先可以看到ADC每翻转一次的时间为30.25us,也就是说ADC1序列转换完成的间隔时间为30.25us,相对应的转换速率为33.06KHz。为什么是这个速率呢。首先我设置的采样时间为239.5个周期,加上固定的12.5周期,在25MHz的ADC时钟驱动下,单通道的转换速率为99.21KHz,因为是采集3个通道,所以理论上应为33.07KHz,与实际相符。
上图是DMA中断和ADC中断的时延,可以看到在ADC转换完成后,过了大约300ns,DMA也传输完成了,说明DMA从开始接收外设的请求到完成数据传输用了300ns,数据量为6个字节数据。速度不慢,估计数据量再大一些的话速度优势将更加明显。
这就是我对ADC采样的进一步分析,均符合理论设计。