搜索

[学习笔记] ADC学习笔记

[复制链接]
147|8
 楼主 | 2021-2-5 11:30 | 显示全部楼层 |阅读模式
AD, dc, IO, TI
ADC模块总结
AC7801 ADC特性:
12位分辨率
输入电压范围:AVSS-AVDD
最大转换速率:1Msps
支持12路外部通道、1路内部温度传感器通道、1路内部带隙基准电压通道
工作模式:
1、规则组单通道单次转换
2、规则组单通道连续转换
3-1、规则组扫描+注入组扫描模式多通道单次转换
3-2、规则组扫描+注入组间隔模式多通道单次转换
4、规则组扫描+自动触发注入组扫描模式多通道单次转换
5-1、规则组扫描+注入组扫描模式多通道连续转换
5-2、规则组扫描+注入组间隔模式多通道连续转换
6、规则组扫描+自动触发注入组扫描模式多通道连续转换
7、规则组子组扫描模式转换
8、注入组子组扫描模式转换
AC7801 ADC时钟及转换速率计算:
AC7801时钟由总线时钟(BUS Clock)分频得到的,分频单元为Clock Divisor的PSC[3:0]寄存器设置。
ADC模块通过使用若干个ADC-CLOCK周期对输入电压进行采样,采用周期通过ADC_SPT寄存器中的SPT[2:0]位进行更改。每个通道可以分别使用不同的采样时间。
转换公式为:(SPT+12)*ADC_CLOCK_CYCLE+5*APB_CLOCK_CYCLE
功能实现:使用TIMER1触发ADC规则组多通道(通道7,8)采样
代码是在官网示例代码1的基础上修改的。代码除基础的初始化代码外,采用TIMER1触发ADC采样,ADC采样可采用软件触发和硬件触发,这里采用CTU功能链接TIMER1触发,初始化代码如下:
  1. void CTU_Config(void)
  2. {
  3.     CTU_ConfigType ctuConfig;
  4.     memset(&ctuConfig, 0x00, sizeof(ctuConfig));
  5.     ctuConfig.uart0RxFilterEn = DISABLE;
  6.     ctuConfig.rtcCaptureEn = DISABLE;
  7.     ctuConfig.acmpCaptureEn = DISABLE;
  8.     ctuConfig.uart0RxCaptureEn = DISABLE;
  9.     ctuConfig.uartTxModulateEn = DISABLE;
  10.     ctuConfig.clkPsc = CTU_CLK_PRESCALER_1;
  11.     ctuConfig.adcRegularTriggerSource = CTU_TRIGGER_ADC_TIMER_CH1_OVERFLOW;
  12.     ctuConfig.delay0Time = 0;
  13.     CTU_Init(&ctuConfig);
  14. }
复制代码
初始化CTU后,接下来就是初始化ADC,ADC初始化代码如下:
  1. void ADC_init()
  2. {
  3.     ADC_ConfigType tempAdcConfig;
  4.     ADC_ConfigType* adcConfig;
  5.     adcConfig = &tempAdcConfig;
  6.     //配置复用功能引脚
  7.     GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);///<ADC_IN8 Analog function enable
  8.                 GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN2);///<ADC_IN7 Analog function enable
复制代码
初始化ADC硬件时需要注意的是,采用多通道采样时每个通道的引脚都需要复用为ADC功能,同时需要注意规则组的采样顺序,这里我在修改代码的时候出现了一点失误,没有注意到ADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 1)这个函数第三个参数实际代表的意义,默认把1copy成了0,导致只有一个通道在采样,另一个通道**,所以一定要记得设置规则组的组序。另外,这里我们使能了DMA功能,需要对DMA初始化,并设置DMA的链接地址,DMA初始化代码如下:
  1. void ADC_DMAInit(void)
  2. {
  3.     uint32_t tmpMemStartAddr = (uint32_t)&g_ADCValueBuffer[0];
  4.     uint32_t tmpMemEndAddr = (uint32_t)&g_ADCValueBuffer[DMA_TRANSFER_NUM + 1]; ///<Setting memory DMA address
  5.     DMA_ConfigType tmpDMAConfig;
  6.     memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));
  7.    
  8.     tmpDMAConfig.memStartAddr = tmpMemStartAddr; //初始地址
  9.     tmpDMAConfig.memEndAddr = tmpMemEndAddr;//终止地址
  10.     tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///<Move ADC DR to memory
  11.     tmpDMAConfig.channelEn = ENABLE;
  12.     tmpDMAConfig.finishInterruptEn = ENABLE;
  13.     tmpDMAConfig.halfFinishInterruptEn = DISABLE;
  14.     tmpDMAConfig.errorInterruptEn = ENABLE;
  15.     tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;
  16.     tmpDMAConfig.circular = ENABLE;
  17.     tmpDMAConfig.direction = DMA_READ_FROM_PERIPH;
  18.     tmpDMAConfig.MEM2MEM = DISABLE;
  19.     tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME;
复制代码
DMA正常配置就可以了,只要注意到初始地址和终止地址链接正常,方便后续读取以及数据处理就可以实现DMA功能。最后需要初始化的是TIMER1,因为我们是采用TIMER1触发ADC采样,因此需要在TIMER中设置触发时间,保证触发时间不小于采样转换时间,这里我们设置的是500微秒timerConfig.periodValue = 100*Delay5us;最后将采集的数据读取出来,通过串口打印就可以实现我们的需求功能了。



TimerTrigerRegularADC-Timer1-double channel.rar

1.22 MB, 下载次数: 4

工程代码如下:

使用特权

评论回复
| 2021-2-5 11:57 | 显示全部楼层
谢谢分享,非常详细

使用特权

评论回复
| 2021-2-5 23:30 | 显示全部楼层
很不错 多通道采样确实需要用到这些知识

使用特权

评论回复
| 2021-2-5 23:47 | 显示全部楼层
这个板子的采样率怎么样

使用特权

评论回复
| 2021-2-6 23:50 | 显示全部楼层
这边用的是哪个板子啊 板子的主频能到多少

使用特权

评论回复
 楼主 | 2021-2-7 09:05 | 显示全部楼层
x史可法 发表于 2021-2-5 23:47
这个板子的采样率怎么样

最大转换速率是1M

使用特权

评论回复
 楼主 | 2021-2-7 09:06 | 显示全部楼层
正圆椭圆 发表于 2021-2-6 23:50
这边用的是哪个板子啊 板子的主频能到多少

AC7801X的板子,主频是48M

使用特权

评论回复
| 2021-2-8 08:25 | 显示全部楼层
学习了,感谢楼主分享经验。

使用特权

评论回复
| 2021-2-19 18:48 | 显示全部楼层
感谢分享,十分详细的说明,不错的。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表