ADC学习笔记
前言
第一章 ADC基本功能介绍
第二章 SOC工作原理
第三章 单次转换
第四章 ADC转换优先级
第五章 采样模式
第六章 中断
第七章 上电步骤
第八章 ADC校准
第九章 ADC时序
第十章 内部温度传感器
文章目录
前言
ADC采样几乎是每一个项目必不可少的环节,本文根据个人日常学习和TI芯片手册整理了部分学习笔记,仅供参考。
一、ADC基本功能介绍
- 12位精度ADC模块(不同芯片有所区别),支持采样保持双通道;
- 支持顺序采样和同步采样模式;
- 输入电压范围可以0~3.3V(内部参考电压),或者 VREFHI和VREFLO 之间的电压差(外部参考电压);
- 16路采样通道(不同的芯片采样通道数量不一样)
- 16个SOC可以配置不同的触发源采样窗口和输入通道(不同芯片数量有所区别)
- 16个结果寄存器可以保存采样值(不同芯片数量有所区别)
- 支持多种不同触发方式(软件触发,EPWM触发,GPIO中断触发,定时器触发,ADC中断触发)
- 9 组灵活的PIE中断,可配置任意转换后的中断请求
二、SOC工作原理
1.触发源
- 触发源可以选择 ADCSOCxCTL ,ADCINTSOCSEL1 或者ADCINTSOCSEL2寄存器,软件触发可以选择ADCSOCFRC1寄存器;
- 触发源包括软件触发,定时器中断触发,ADC中断触发,EPWM1~8 SOCA和SOCB触发
2.采样窗口长度
- 采样窗口大小通过ADCSOCxCTL 寄存器中的 ACQPS 位进行配置
- 采样窗口的长度等于ACQPS+1
- 整个采样时间为采样窗口时间加上13个ADC时钟周期时间,采样时间如下图
3.采样通道
- 采样通过ADCSOCxCTL 寄存器中的 CHSEL 位进行配置
- 当将SOC配置为顺序采样模式时,ADCSOCxCTL寄存器的四位CHSEL字段定义了要转换的信道。
- 当SOC配置为同步采样模式时,CHSEL字段的最显著位被删除,较低的3位决定哪对通道被转换。
三、单次转换
- 单次转换支持
- 此模式将允许您在轮询方案中对下一个触发的SOC执行单个转换。
- ONESHOT模式仅对轮询轮中存在的通道有效。
- 在轮询方案中未为触发SOC配置的通道将根据ADCSOCPRIORITYCTL寄存器中的SOCPRIORITY字段的内容获得优先级。
四、转换优先级
1,默认优先级模式
在这个方案中,没有SOC具有比其他SOC更高的固有优先级。
优先级取决于轮询指针(RRPOINTER)。
反映在ADCSOCPRIORITYCTL寄存器中的RRPOINTER指向最后转换的SOC。
最高优先级的SOC被分配给下一个比RRPOINTER值大的值,在SOC15之后绕回SOC0。
在重置时,该值为16,因为0表示已经发生了转换。
当RRPOINTER等于16时,优先级最高的是SOCO。.
当ADCCTL1复位时,RRPOINTER被设备复位。
RESET位被设置,或者当SOCPRICTL寄存器被写入时。
2,高优先级模式
ADCSOCPRIORITYCTL寄存器中的SOCPRIORITY字段可用于从单个SOC分配高优先级到所有SOC。
当配置为高优先级时,SOC将在任何当前转换完成后中断轮询轮,并将自己插入下一个转换。
转换完成后,轮询轮将继续在它被中断的地方。
如果两个高优先级的SoC同时被触发,编号小的SoC将优先
五,采样模式
1,顺序采样
ADC的默认行为是将触发的soc视为顺序处理的单个转换。
顺序采样可以同时转换a通道和b通道,而不受顺序的限制。
2,同步采样
- 在某些应用中,保持两个信号采样之间的延迟最小是很重要的。
ADC包含双采样和保持电路,允许同时对两个不同的通道进行采样。
同时采样模式为一对带有ADCSAMPLEMODE寄存器的SOCx配置。
偶数SOCx和后面的奇数SOCx (SOCO和SOC1)通过一个启用位(在本例中是SIMULENO)耦合在一起。
耦合行为如下:任一SOCx的触发器都将启动一对转换。
转换的通道对将由a通道和b通道组成,对应于触发的SOCx的CHSEL字段的值。取值范围为0 ~ 7。
两个通道将同时采样。A通道总是首先转换。
偶数EOCx脉冲将基于a通道转换产生,奇数EOCx脉冲将由b通道转换产生。
a通道转换的结果被放在偶数ADCRESULTx寄存器中,b通道转换的结果被写到奇数ADCRESULTx寄存器中。- 通常在应用程序中,期望只使用对的偶数SOCx。
但是,也可以使用奇数的SOCx,或者两者都使用。
在后一种情况下,两个SoCx触发器都将启动转换。
因此,两个SOCx将把它们的结果存储到相同的ADCRESULTx寄存器中,可能会相互覆盖,因此需要谨慎。- SOCx的优先级规则与顺序采样模式中保持相同
六,中断
- 正如有16个独立的SOCx配置集一样,也有16个EOCx脉冲。在顺序采样模式下,EOCx与SOCx直接关联。
- 在同步采样模式下,偶数和下面的奇EOCx对与偶数和下面的奇SOCx对相关联,如第8.6节所述。这取决于ADCCTL1。插入设置,EOCx脉冲将发生在转换开始或结束。关于EOCx脉冲的精确计时,请参见第8.11节。
- ADC包含9个中断,可以被标记和/或传递给PIE。每个这些中断都可以被配置为接受任何可用的EOCx信号作为其源。以EOCx为源的配置是在INTSELxNy寄存器中完成的。此外,ADCINT1和ADCINT2信号可以被配置为生成SOCx触发器。这有利于创建一个连续的转换流。
- 当设置附件中的中断溢出位时,非连续转换模式可能会中断混乱。
七,上电步骤
- 如果需要一个外部引用,请使用ADCCTL1寄存器中的第3位(ADCREFSEL)来启用此模式。
- 通过在ADCCTL1寄存器中设置7-5位((ADCPWDN, ADCBGPWD, ADCREFPWD),一起启动参考、带隙和模拟电路。
- 通过设置ADCCTL1寄存器的第14位(可附加)来启用ADC。
- 在执行第一次转换之前,需要在步骤2之后进行1毫秒的延迟。
- 这种类型的ADC在所有电路通电后需要1 ms的延迟。这与以前类型的ADC不同。
- 当关闭ADC时,步骤2中的所有三个位可以同时清除。ADC的功率水平必须通过软件进行控制,并且它们独立于设备功率模式的状态。
八,ADC校准
1,零偏校准
- 零偏移误差定义为在VREFLO转换电压时产生的数字值。该基本误差影响ADC的所有转换,并与满量程增益和线性规格一起决定转换器的直流精度。零偏移误差可以是正的,这意味着当VREFLO出现时输出一个正的数字值,也可以是负的,这意味着高于VREFLO一步的电压仍然读取为数字零值。为了纠正这个错误,将错误的二进制补码写入ADCOFFTRIM寄存器中。该寄存器中包含的值将在ADC结果寄存器中可用之前应用。此操作完全包含在ADC核心中,因此结果的时序不会受到影响,并且对于任何修剪值都将保持ADC的完整动态范围。调用Device_cal()函数用出厂校准的偏移量纠错写入ADCOFFTRIM寄存器,但是用户可以修改ADCOFFTRIM寄存器来补偿由应用程序环境引起的额外偏移量错误。这可以通过使用ADCCTRL1寄存器中VREFLOCONV位在不牺牲ADC通道的情况下完成。
- Set ADCOFFTRIM to 80 (50h). 这增加了一个人为偏移量,以考虑可能驻留在的负偏移量ADC核心。
- Set ADCCTL1.VREFLOCONV to 1.这内部连接VREFLO到输入通道B5。看到ADCCTL1寄存器描述。
- Perform multiple conversions on B5 (sample VREFLO) and take an average to account for board noise.
- Set ADCOFFTRIM to 80 (50h) minus the average obtained in step 3.这消除了人为偏移从步骤1开始,并创建一个2的偏移误差恭维。
- Set ADCCTL1.VREFLOCONV to 0. 这将B5连接回外部ADCINB5输入引脚。
- 位于公共头文件中F2806x_Adc.c中的F2806x_Adc offfcal()函数执行这些步骤。
2, 增益校准
增益误差随着输入电压的增加而增加。全量程增益误差发生在
最大输入电压。与偏移误差一样,增益误差可以是正的,也可以是负的。正的满量程增益误差意味着在最大电压输入之前达到全量程数字结果。负的满量程误差意味着完全数字化的结果将永远无法实现。校准函数Device_cal()写一个工厂校正ADC满量程增益误差到ADCREFTRIM寄存器。这个寄存器不应该是在Device_cal()函数被调用后修改。
3,偏置电流校准
为了进一步提高ADC的精度,校准函数Device_cal()还写入了一个工厂修剪值到ADC寄存器获取ADC偏置电流。这个寄存器不应该在Device_cal()函数之后被修改被称为。
九,ADC时序
顺序采样模式 :AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;// 完成转换结果后再产生EOCx信号
顺序采样模式 :AdcRegs.ADCCTL1.bit.INTPULSEPOS = 0;// 未完成转换结果后再产生EOCx信号
同步采样模式 :AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;// 完成转换结果后再产生EOCx信号
同步采样模式 :AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;// 完成转换结果后再产生EOCx信号
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 0; // 允计采样保持器进行覆盖
十,内部温度传感器
内部温度传感器测量设备的连接温度。传感器输出可以通过使用由ADCCTL1控制的开关对通道A5上的ADC进行采样。该开关允许A5同时用作外部ADC输入引脚和温度传感器接入点。当对温度传感器进行采样时,ADCINA5上的外部电路不能用作外部采样。
总结
废话不说上代码!!!
int AdcWin=0X06;
InitAdc();
AdcOffsetSelfCal(); // 修正ADC偏置
EALLOW;
AdcRegs.ADCINTSOCSEL1.all = 0; // 修正ADC偏置后,清除SOCx ADC中断触发源
AdcRegs.ADCINTSOCSEL2.all = 0;
EDIS;
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 完成转换结果后再产生EOCx信号
AdcRegs.ADCCTL1.bit.VREFLOCONV = 0; // ADCINB5引脚被接入ADC采样转换
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 0; // 允计采样保持器进行覆盖
AdcRegs.INTSEL1N2.bit.INT1E = 1; // 使能ADCINT1中断,目的是用于触发DMA1,并不是进入ADCINT1中断服务函数
AdcRegs.INTSEL1N2.bit.INT1CONT = 1; // 使能连续采样模式(即每当发生EOCx信号时,ADCINT1就会发生中断)
AdcRegs.INTSEL1N2.bit.INT1SEL = 15; // EOC15信号(INT1SEL=15)触发ADCINT1中断
AdcRegs.SOCPRICTL.all = 0; //
AdcRegs.ADCSAMPLEMODE.all = 0; // 顺序采样
// 选择采样通道
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // 选择ADCINA0引脚(CHSEL=0)作为SOC0通道并被采样转换
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; // 选择ADCINA1引脚(CHSEL=1)作为SOC1通道并被采样转换
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; // 选择ADCINA2引脚(CHSEL=2)作为SOC2通道并被采样转换,其它同理
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3;
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4;
AdcRegs.ADCSOC5CTL.bit.CHSEL = 5;
AdcRegs.ADCSOC6CTL.bit.CHSEL = 6;
AdcRegs.ADCSOC7CTL.bit.CHSEL = 7;
AdcRegs.ADCSOC8CTL.bit.CHSEL = 8; // 选择ADCINB0引脚(CHSEL=8)作为SOC8通道并被采样转换
AdcRegs.ADCSOC9CTL.bit.CHSEL = 9; // 选择ADCINB1引脚(CHSEL=9)作为SOC9通道并被采样转换
AdcRegs.ADCSOC10CTL.bit.CHSEL = 10; // 选择ADCINB2引脚(CHSEL=10)作为SOC10通道并被采样转换,其它同理
AdcRegs.ADCSOC11CTL.bit.CHSEL = 11;
AdcRegs.ADCSOC12CTL.bit.CHSEL = 12;
AdcRegs.ADCSOC13CTL.bit.CHSEL = 13;
AdcRegs.ADCSOC14CTL.bit.CHSEL = 14;
AdcRegs.ADCSOC15CTL.bit.CHSEL = 15;
// 选择触发
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0X05; // ePWM1A产生ePWM1SOCA信号触发SOCA转换
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 0X05;
AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 0X05;
// 选择采样保持窗口时间
AdcRegs.ADCSOC0CTL.bit.ACQPS = AdcWin; // 采样/保持窗口时间为(AdcWin+1)个周期
AdcRegs.ADCSOC1CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC2CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC3CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC4CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC5CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC6CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC7CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC8CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC9CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC10CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC11CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC12CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC13CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC14CTL.bit.ACQPS = AdcWin;
AdcRegs.ADCSOC15CTL.bit.ACQPS = AdcWin;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 允许ePWM1A产生ePWM1SOCA信号触发ADC转换
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // TBCTR=0时,产生ePWM1SOCA信号
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 每个事件触发一次
EDIS;