电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【dsPIC33】多路ADC同时采样
分 享
扫描二维码分享
【dsPIC33】多路ADC同时采样
dsPIC
ADC同时采样
KVIN
关注
发布时间: 2019-12-03
丨
阅读: 2937
# 前言 上篇文章讲到使用PWM来触发ADC,进而控制ADC采样的时刻,这在电机控制中是非常重要的一步,但上篇文章没有细讲多路ADC的同时采样,本文就单独把这一部分拉出来进行分析。 读取ADC值有两种方式,一种使用DMA,另一种不使用DMA。 #### 使用DMA: ![](https://cf03.ickimg.com/bbsimages/201911/43386371685822f2c08ca7fdb931cf9e.png) 翻译过来就是:使能DMA模块(ADDMAEN = 1)时,每个ADC外设ADC模块仅具有1个ADC结果缓冲器(即ADC1BUF0),并且在下一次ADC转换之前,必须由CPU或DMA控制器读取ADC转换结果。 可以避免覆盖先前的值。 #### 不使用DMA: ![](https://cf03.ickimg.com/bbsimages/201911/e6b909c8b461ab7b84c28f067a2693ff.png) 翻译过来就是:禁用DMA模块时(ADDMAEN = 0),ADC具有16个结果缓冲区.ADC转换结果按顺序存储在ADC1BUF0-ADC1BUFF中,无论使用哪个模拟输入取决于SMPIx位和1c中描述的条件 以上。 被测ANx输入与转换结果将放置在哪个ADC缓冲器(ADC1BUF0-ADC1BUFF)之间没有关系。 也就是ADxCON4寄存器中的ADDMAEN位为DMA使能位,如果使用了DMA,则数据都会存储在ADC1BUF0,需要在下次采样之前取出数据,避免数据覆盖掉之前的值。 ![](https://cf03.ickimg.com/bbsimages/201911/5c080009f3449e27d7706622428c0862.png) ![](https://cf03.ickimg.com/bbsimages/201911/ed0b9de4bdb5e7003fda1a1bb02f7f20.png) 那么结合我们实际的情况,对于电机电流采样,每次采样就那几个数据采集一个就行,因此不使用DMA会更方便一些,可以直接读取相应的存储寄存器即可。 大多数应用,使用分时采样,或者叫顺序采样即可,但是在一些特殊场合,比如需要同步采样来消除模拟信号之间的相位差时,就必须有多个采样电路同时工作,dsPIC内部的10位AD转换器前端一共有4个可以同时工作的采样保持电路。可以通过ADCON2中的CHPS位来配置: ![](https://cf03.ickimg.com/bbsimages/201911/6e967c4e593c5c849b9a3146f329ee13.png) 看一下我的原理图: ![](https://cf03.ickimg.com/bbsimages/201911/83e69629d304a04ad5993ea30f42cc8d.png) 由于项目中有6个模拟信号,而且不使用DMA,因此可以参照手册中的 "使用同时采样对8个输入进行采样(不使用DMA)" 章节: ![](https://cf03.ickimg.com/bbsimages/201911/e1173e4185df035215e62a792432b6cb.png) 由上图可知,需要使能同时采样: ```c AD1CON1bits.SIMSAM = 1; //同步采样 ``` ![](https://cf03.ickimg.com/bbsimages/201911/0bab8b640f159754b2e2d3829840b49e.png) 由上图可知,8通道同时采样实际是分为两部分,因为每个ADC只有4个通道,CH0-CH3,但是可以选择这四个通道连通的是哪四个输入引脚,第一个一个触发信号到来时,会使配置的MUXA的CH0-CH3同时采样,然后顺序转换,之后下一个触发信号到来时,会使配置的MUXB的CH0-CH3同时采样,然后顺序转换,依次存储在内存中。也就是说8通道同时采样是有两组,一组是MUXA,另一组是MUXB,虽说是8通道,但每个触发信号只能同时采样4个引脚,也就是交替采样这个概念。手册中的配置如图: ![](https://cf03.ickimg.com/bbsimages/201911/f8f461dde1046ecc198ce94bb5bb1e94.png) 手册中的配置是4次采样后产生中断,也就是说,4个触发信号之后会产生一个ADC中断,也就是说,8个模拟输入,每个都采样了两遍,因为ADC的缓存空间有16个,因此可以存储两遍。而我在实际项目中,不需要每个通道采集两遍,因此通过配置SMPI位更改,而BUFM位也一样配置为0: ![](https://cf03.ickimg.com/bbsimages/201911/f8b7b6540a12a550d7434a085c73a1f0.png) 显然我是希望总是从起始地址开始填充缓冲区的。 按照手册上的配置,存储空间的示意图如下: ![](https://cf03.ickimg.com/bbsimages/201911/6804ebf4913fed825f0d6aac167e39c6.png) 之后,我们可以参照手册上的配置来配置自己的,这时,需要再细看输入通道寄存器,dsPIC33E芯片中是有两个输入通道寄存器的,一个是ADxCHS0,用来进行CH0通道的配置;另一个是ADxCHS123,用来进行CH1,2,3的配置,CH1,2,3是同时配置的,由此可见对于CH0通道的使用是更加灵活的。 ![](https://cf03.ickimg.com/bbsimages/201911/08db3d4a5fdd15a4eabb872795ee2dd6.png) 由上面的寄存器介绍可知:CH0通道可以配置为任意的AD引脚。 ![](https://cf03.ickimg.com/bbsimages/201911/87f79d64a10cae5f49eafee34522fa6e.png) 而CH1,2,3则稍微有些固定,不过也还算是灵活,也可以满足需要。 接下来就要理解交替采样的概念,手册上有一句话说的比较清楚: ![](https://cf03.ickimg.com/bbsimages/201911/9156dcf14929abf57c94d8f43bd75ea5.png) 就是说,第一个触发信号使用配置的MUXA通道进行采样,第二个触发信号使用配置的MUXB通道进行采样。之后再循环。 而我使用的是SVPWM,因此,只有触发时间点比PWM周期值小,便会在每个周期都会有两个触发信号: ![](https://cf03.ickimg.com/bbsimages/201911/e4ea8979aef7a966126bc590c842069e.png) 到这里,便可以看我的实际电路图,来进行配置了。 我有6个通道,可以将MUXA的CH1,2,3通道配置为AN0,1,2,然后将MUXB的CH1,2,3通道配置为AD3,4,5,至于两个CH0,便可以随便指定。(注:这里我测试如果MUXA与MUXB的CH0通道都配置为同一个引脚的话,采集会有问题,因此避免两个CH0采集同一个通道)当然,在配置ADC之前,不要忘记将引脚配置为输入模式。 配置如下: ```c void sensor_SensorAdc_Init (void) { AD1CON1bits.DONE = 0; //确保没有任何正在进行的转换 /@@*端口初始化*/ ANSELA = 0; ANSELB = 0; ANSELAbits.ANSA0 = 1; // U相电流采样 ANSELAbits.ANSA1 = 1; // V相电流采样 ANSELBbits.ANSB0 = 1; // 总电流采样 ANSELBbits.ANSB1 = 1; // 电位器 ANSELBbits.ANSB2 = 1; // 偏移电压1.65V采样 ANSELBbits.ANSB3 = 1; // 总线电压采样 TRISAbits.TRISA0 = 1; //配置为输入 TRISAbits.TRISA1 = 1; TRISBbits.TRISB0 = 1; TRISBbits.TRISB1 = 1; TRISBbits.TRISB2 = 1; TRISBbits.TRISB3 = 1; /@@*控制寄存器配置*/ AD1CON1 = 0x0000; //清零 AD1CON1bits.ADON = 0; //ADC关闭 AD1CON1bits.ADSIDL = 0; //在空闲模式下模块继续工作 AD1CON1bits.AD12B = 0; //10位,4通道ADC工作 AD1CON1bits.FORM = 0; //输出整数(0000 00dd dddd dddd) AD1CON1bits.SSRC = 0x00; //当SSRCG=1时 SSRC=0即为由PWM发生器1主触发比较结束采样并启动转换 AD1CON1bits.SSRCG = 1; AD1CON1bits.SAMP = 1; //同时采样 CH0,CH1,CH2,CH3 AD1CON1bits.ASAM = 1; //上一次转换后立即开始采样,即SAMP位自动置1 AD1CON1bits.SIMSAM = 1; //同步采样 AD1CON2 = 0x0000; //清零 AD1CON2bits.CHPS = 0x03; //多通道采样 CH0 - CH3 AD1CON2bits.VCFG = 0x00; //参考电压选择AVdd与AVss AD1CON2bits.CSCNA = 0; //不扫描输入 AD1CON2bits.SMPI = 0x01; //每完成2次采样/转换操作后产生ADC中断a AD1CON2bits.ALTS = 1; //MUXA与MUXB交替采样 AD1CON2bits.BUFM = 0; //总是从起始地址开始填充缓冲区 AD1CON3 = 0x0000; //清零 /@@*短暂延时,让寄存器有充分时间写入*/ Nop(); /@@*不使用DMA*/ AD1CON4 = 0x0000; /@@**************************MUXA输入选择****************************/ /@@*输入CH0选择寄存器配置*/ AD1CHS0bits.CH0SA = 4; //CH0同向输入端选择 AN4 (偏移电压采集) AD1CHS0bits.CH0NA = 0; //CH0反向输入端选择 Vrefl /@@*输入CH1,CH2,CH3选择寄存器配置*/ AD1CHS123bits.CH123SA = 0; //CH1,2,3同向输入端对应 AN0,1,2 AD1CHS123bits.CH123NA = 0; //CH1,2,3反向输入端都为 Vrefl /@@**************************MUXB输入选择***************************/ /@@*输入CH0选择寄存器配置*/ AD1CHS0bits.CH0SB = 5; //CH0同向输入端选择 AN3 (电源电压采集) AD1CHS0bits.CH0NB = 0; //CH0反向输入端选择 Vrefl /@@*输入CH1,CH2,CH3选择寄存器配置*/ AD1CHS123bits.CH123SB = 1; //CH1,2,3同向输入端对应 AN3,4,5 AD1CHS123bits.CH123NB = 0; //CH1,2,3反向输入端都为 Vrefl // AD1CSSL = 0x001f; //输入扫描时跳过ANx IFS0bits.AD1IF = 0; //清楚ADC中断标志 IEC0bits.AD1IE = 1; //使能中断 IPC3bits.AD1IP = 0x01; //ADC中断优先级设置为1 AD1CON1bits.ADON = 1; //使能ADC } void sensor_UpdateSensor (SENSOR_DATA *pSensor) { /@@***************************************************************************************************************************************** * ADC采集程序 ****************************************************************************************************************************************/ pSensor->i16_speedVol = ADC1BUF5; pSensor->i16_current_U = ADC1BUF1; pSensor->i16_current_V = ADC1BUF2; pSensor->i16_current_All = ADC1BUF3; pSensor->i16_offsetV = ADC1BUF0; pSensor->i16_vin = ADC1BUF4; } ```
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
2
)
KVIN
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交