前言
DSP28335的ADC模块使用介绍:
- 12位ADC
- 2个采样保持器
- 同步采样或顺序采样,使用顺序采样
- 输入范围0-3V
- 时钟配置为最高25MHz
- 级联模式或双排序模式,采用级联模式,8状态排序器SEQ1和SEQ2构成16状态的SEQ
- 选择EPWMxSOCA作为触发源启动ADC转换,采样频率为10K
主要内容:
1、ADC原理+DSP的ADC原理
2、具体程序
ADC转换原理
ADC就是模数转换器,将模拟量转换为数字量,通常就是对电流、电压等进行采样,然后进行转换,得到数字量,再在软件中进行编程换算得到实际的值。
A/D转换一般要经过取样、保持、量化及编码4个过程。28335的ADC模块如Figure1-1所示。采样数据通过通过传输至Analog MUX,然后送到EPWM SOCA处理,然后送至12位ADC转换器模组进行转换,输出到结果寄存器。
转换公式如下:
RealValue= SampleValue * 3.0f / 4096.0f
触发方式
三种触发方式可以开始ADC转换,具体如下:
- S/W软件立即启动
- EPWM SOCA、SOCB转换启动
- XINT2 ADC转换开始
采用EPWM SOCA启动方式
如何触发ADC?
1、使用EPWM的SOCA触发;
1
2
3AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1 AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
2、使能EPWMxSOCA信号的产生,以何种方式何时产生;
1
2
3
4
5EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount CTR = CMPA且为向上计数是产生触发事件 EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个事件时产生SOCA信号 EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
3、EPWM为up-down模式,触发频率为10K,时钟为150MHz;
1
2
3
4
5
6EPwm1Regs.TBPRD = 0x1D4C; // Set period for ePWM1 7500 10K EPwm1Regs.TBCTR = 0x0000U; // EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up-down模式 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x00; // 使用系统时钟 EPwm1Regs.TBCTL.bit.CLKDIV = 0x00;
ADC初始化配置程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h" // DSP2833x Examples Include File #include "DSP2833x_Adc.h" #define ADC_usDELAY 5000L Uint16 Sample_I = 0U; float Real_I = 0.0f; float Base_Current = 3.0f / 4096.0f; void init_28335ADC_CLK(void) { EALLOW; #define ADC_MODCLK 0x03 SysCtrlRegs.HISPCP.all = ADC_MODCLK; EDIS; } // ADC初始化 void init_adc_config(void) { extern void DSP28x_usDelay(Uint32 Count); EALLOW; SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; ADC_cal(); EDIS; AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits DELAY_US(ADC_usDELAY); // Delay before converting ADC channels // Configure ADC AdcRegs.ADCMAXCONV.all = 0x000F; // Setup 1 conv's on SEQ1 16个通道 AdcRegs.ADCTRL1.bit.ACQ_PS = 0x1; AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 顺序采样 AdcRegs.ADCTRL1.bit.CPS = 0; // 对外设时钟HSPCLK不分频 AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x0; // ADC内核时钟不分频 ADCCLK = HSPCLK / (CPS + 1) = 25MHz AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 级联排序模式 AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // 连续模式 AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1; // 排序覆盖 // 转换顺序 AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x00U; // Setup ADCINA0 as 1st SEQ1 conv. AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x01U; AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x02U; AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x03U; AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x04U; AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x05U; AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x06U; AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x07U; AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x08U; AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x09U; AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0x0AU; AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0BU; AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x0CU; AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0x0DU; AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0x0EU; AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x0FU; AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1 AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS) // Assumes ePWM1 clock is already enabled in InitSysCtrl(); EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount CTR = CMPA且为向上计数是产生触发事件 EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个事件时产生SOCA信号 EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value // 设置EPWM触发源 EPwm1Regs.TBPRD = 0x1D4C; // Set period for ePWM1 7500 10K EPwm1Regs.TBCTR = 0x0000U; // EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up-down模式 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x00; // 使用系统时钟 EPwm1Regs.TBCTL.bit.CLKDIV = 0x00; } // 转换计算 interrupt void adc_isr(void) { Sample_I = AdcRegs.ADCRESULT0 >>4; // 采样数据 Real_I = (float)Sample_I * Base_Current;// 实际电流 }
注意
1、ADC通道、结果寄存器对应关系:
1
2
3
4
5
6
7
8
9
10AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x02U; // Setup ADCINA0 as 1st SEQ1 conv. AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x03U; AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x00U; AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x01U; ADCINA2 -> AdcRegs.ADCRESULT0; ADCINA3 -> AdcRegs.ADCRESULT1; ADCINA0 -> AdcRegs.ADCRESULT2; ADCINA1 -> AdcRegs.ADCRESULT3;
由上面的代码可知,你的通道对应哪个CONVxx,则结果就存在哪个结果寄存器AdcRegs.ADCRESULTxx:
CONV00------------------AdcRegs.ADCRESULT0
CONV01------------------AdcRegs.ADCRESULT1
…
CONV15------------------AdcRegs.ADCRESULT15
这个对应关系是固定不变的,而A/D输入通道,可以根据自己选择排序控制寄存器的哪四位即CONVxx输入,然后进行转换。
2、为什么结果寄存器的值由进行右移4位
结果寄存器是16位的,而28335的ADC模块是12位的,一般使用的是映射在外设帧2,左对齐方式,,故前4位是保留的,所以需要右移4位才能得到实际值。
ADC结果寄存器是双映射。外设帧2(0x7108-0x7117)中的位置为2等待状态,且为左对齐。外设帧0空间(0x0B00-0x0B0F)的位置对CPU访问是1等待状态和对于DMA访问是0等待状态,右对齐。在ADC的高速/连续转换使用期间,使用0等待状态位置进行ADC结果到用户内存的快速转换。
DSP2833x_Headers_nonBIOS.cmd中
ADC_MIRROR : origin = 0x000B00, length = 0x000010 /* ADC Results register mirror /
ADC : origin = 0x007100, length = 0x000020 / ADC registers */
如何选择使用外设帧0?
最后
以上就是美丽石头最近收集整理的关于DSP C2000系列TMS320F28335学习之ADC的全部内容,更多相关DSP内容请搜索靠谱客的其他文章。
发表评论 取消回复