学习日常日志1 第一篇水文,会不会被潜规则
本水文只适合新手观赏娱乐,也是为了学习过程中的总结,大佬们请手下留情(请使劲打脸)
这次使用了TMS320F28335开发板和TLV5618双路DA输出模块,使用F28335进行双通道的AD采样,再将采样数据发送给TLV5618模块
F28335上使用到的功能模块:1.ADC 模块 2.SPI模块 下面主要记录分享F28335的ADC配置。
而TLV5618模块,是一个16位的双路DA输出模块,只要把采样的12位+4位模式控制 这16位数据发送给它,就可以将数字信号输出位模拟信号,具体细节,下篇水文会详细介绍
言归正传(开始瞎编) 这里主要
讨论使用到的ADC相关的详细配置,直接肛代码
- // HSPCLK = 25.0 MHz<br />
- #if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT<br />
- #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK2) = 150/(2*3) = 25.0 MHz<br />
- #endif<br />
- #if (CPU_FRQ_100MHZ)<br />
- #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK2) = 100/(2*2) = 25.0 MHz<br />
- #endif<br />
- <br />
- /* ADC CLK = 12.5MHz*/<br />
- #define ADC_CKPS 0x0001 /* 设置ADC核时钟ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz*/<br />
- #define ADC_SHCLK 0x0002 /* 一个采样保持的周期 S/H width in ADC module periods = 8 ADC clocks*/<br />
- <br />
- EALLOW;<br />
- <br />
- /*高速外设时钟预定标寄存器(3位) 当HISPCP = 0; HSPCLK = SYSCLKOUT;<br />
- //当0<=HISPCP <=7时,HSPCLK = SYSCLKOUT/(2*HISPCP) //在系统复位是,HISPCP = 1 , HSPCLK = 75MHz SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/(ADC_MODCLK*2) = 25MHz */ EDIS; InitAdc(); /* 使能ADC模块,并上电*/ SetAdcParm(); /* 设置ADC模块有关参数*/ /* 设置ADC模块有关参数*/ void SetAdcParm(void) { /*清除不确定的SOC触发*/ AdcRegs.ADCTRL2.bit.SOC_SEQ1=0; /* AdcRegs.ADCTRL2.bit.SOC_SEQ2=0;*/ /*CPS 在ADCTRL1的第7位。(1位寄存器 =1(对HSPCLK = 25MHz进行2分频)或 = 0(对HSPCLK不分频))*/ AdcRegs.ADCTRL1.bit.CPS = 0; /*ADCCLK(ADC核(即AD转换的部分)时钟),由ADCCLKPS(4位)对HSPCLK进行分频得到。 //在ADCCLKPS = 0时:ADCCLK = HSPCLK/(CPS+1) ; //在1<=ADCCLKPS<=15 时: ADCCLK = HSPCLK/(2*ADCCLKPS*(CPS+1))*/ AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; //ADCCLK = 12.5MHz /* Specific ADC setup for this example: //ADC_PS(4位)表示采样窗口大小,控制采样中一个SOC(start of sequence启动序列转换)的脉冲宽度(时间) //一个SOC = (ACQ_PS + 1) 个ADCCLK周期 //顺序采样模式下: 一个AD转换周期(即完整的S/H采样保持周期) = SOC +ADCCLK; //同步采样模式下:一个AD转换周期 (即完整的S/H采样保持周期) = SOC + 2*ADCCLK*/ AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; // S/H 采样保持周期,8个ADCCLK(同步模式),采样数率=1.5MHz /*(SOC+ADCCLK)而(SOC = (ACQ_PS+1)个ADCCLK)*/ AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; /* 0:顺序采样模式。1:同步采样模式*/ AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; /* 1:级联模式。0 : 双序列模式(必须使用同步采样模式,这种模式可能会出现问题,要是用同步采样模式,一般采用同步级联的方式) //在双序列模式下,数据的存放是这样的:通道1结果放在结果寄存器1中,通道2结果放在结果寄存器8中,依此交叉存放 //同步采样模式中,CONVnn (4位)最高位将被舍弃(意思是说,只区别偏移地址,A.B通道将采样同一编号的通道,若A选择采样2,则B也是采样2通道)*/ /*0: 启动/停止转换方式,到达EOC时,停止采样,需要手动将SEQ_CNTR置1。 //1:自动重新开始,即在SEQ_CNTR = 0 时,自动重新将MAXCONVn的值装入。*/ AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run /*ADC输入通道配置(共16个通道) //进入转换的通道数应与ADCMAXCONV寄存器设置的数对应。 //ADC有4个通道选择序列控制器 ADCCHSELSEQ1~ADCCHSELSEQ4(每个寄存器都是16位, //ADCCHSELSEQ1的每4位可选择任意一个通道),并非CONV00只能选择 A0通道,可重复。 // AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // 采样A0通道*/ AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;// 采样A1通道 /*AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; //还是对通道A2采样 // AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8; //选择B0通道*/ AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9; /* AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA; // AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB; // AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC; // AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD; // AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE; // AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF; // 采样B7通道*/ /*在同步,级联模式下,A B通道的结果是按顺序存取的。之前一直在使用覆盖模式,一直没成功,在完全掌握之前要慎用覆盖模式。 //序列发生器的覆盖功能 //在级联模式下,0:禁止覆盖功能,若采样最大通道设为7,则在第8的通道采样完成,ADC转换值也更新到了ADCRESULT0~7中时 //指针将重0开始,也就是转换结果重新从ADCRESULT0开始存入 //1: 与上面一样,只是当第一次转换结果都存入ADCRESULT0~7时,指针将继续往下存,即接下来的转换结果从ADCRESULT8开始 //直到更新到ADCRESULT15,再从ADCRESULT0 存入。这在高速转换时,有利于ADC数据的捕获。*/ AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; /* 设置最大转换通道数,最多可设置16个输入通道 // AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0xf; //级联模式下,最大转换数为16 //同步模式下最大通道的配置 // AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; // AdcRegs.ADCMAXCONV.all = 0x77; // //或者用下面的 // AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x07; SEQ1 // AdcRegs.ADCMAXCONV.bit.MAX_CONV2 = 0x70;SEQ2*/ AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x1; //实际值比设置值大1 /*AdcRegs.ADCMAXCONV.bit.MAX_CONV2 = 0x0; //实际值比设置值大1 // Start SEQ1 //启动SEQ转换(SOC)触发位 //0:清除不确定的SOC触发 //软件触发SOC // AdcRegs.ADCTRL2.bit.SOC_SEQ1=1; 放在了后面语句中启动*/ }
(配合我下面的解说和代码注解食用最佳) 对ADC的配置使用时,总共分为8步:1. ADC的初始化(上电)。2. ADC时钟的配置。3. ADC采样周期配置。4.采样方式即序列发生器模式配置。5.通道配置。6.运行方式配置。7.启动ADC的方式。8.序列发生器覆盖功能。下面,将结合代码详细的解释配置的8大步骤。 (码字好累,我需要续续)
1.ADC初始化(上电)
这个工作已经在InitAdc();中完成。这个函数是来自于系统自带的DSP2833x_Adc.c 文件里面,需要注意的是需要延迟5ms以便ADC完全上电
2.ADC时钟配置
时钟是ADC的心脏,它为ADC提供了信号的基准。ADC核时钟是由HSPCLK(高速外设时钟)分频得来的。具体配置如下
- EALLOW;<br />
- <br />
- //高速外设时钟预定标寄存器(3位) 当HISPCP = 0; HSPCLK = SYSCLKOUT;<br />
- //当0<=HISPCP <=7时,HSPCLK = SYSCLKOUT/(2*HISPCP) //在系统复位是,HISPCP = 1 , HSPCLK = 75MHz SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/(ADC_MODCLK*2) = 25MHz EDIS;
系统初始化中,HISPCP是系统时钟(150MHz)的1分频。这里对它进行更改,使用ADC_MODCLK = 3(6分频),即HISPCP由系统时钟6分频得到(25MHz)。 3. ADC采样周期 这里是配置完成一个完整采样的时间,一个完整的采样时间包括一个点序列开始(SOC),数据结果更新(C)。
采样保持周期的配置在控制寄存器1 ADCTRL1[11:8] 的ACQ_PS配置(配合代码上面的注释食用)
4.采样方式即序列发生器模式配置
采样方式分为 顺序采样和同步采样,使用
- AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; /* 0:顺序采样模式。1:同步采样模式*/
进行配置;序列发生器模式分为,双排序器模式(16位)级联模式(两个8位)。使用
- AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; /* 1:级联模式。0 : 双序列模式 */
5.通道配置
ADC输入通道配置(共16个通道)进入转换的通道数应与ADCMAXCONV寄存器设置的数对应。ADC有4个通道选择序列控制器ADCCHSELSEQ1~ADCCHSELSEQ4(每个寄存器都是16位,ADCCHSELSEQ1的每4位可选择任意一个通道),并非CONV00只能选择 A0通道,可重复。
- // AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // 采样A0通道*/<br />
- AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;// 采样A1通道<br />
- /*AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; //还是对通道A2采样<br />
- // AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;<br />
- // AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;<br />
- // AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;<br />
- // AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;<br />
- // AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;<br />
- // AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8; //选择B0通道*/<br />
- AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9;<br />
- /* AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA;<br />
- // AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB;<br />
- // AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC;<br />
- // AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD;<br />
- // AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE;<br />
- // AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF; // 采样B7通道*/
6.运行方式配置
运行方式包括:1. 启动/停止模式,完成采样后,序列发生器停止工作,除非复位序列发生器,否则,在下一个SOC,序列发生器将从它结束的状态开始。(换句话说就是到达EOC时,停止采样,需要手动将SEQ_CNTR置1) 2. 连续转换模式,自动重新开始,即在SEQ_CNTR = 0 时,自动重新将MAXCONVn的值装入。在AdcRegs.ADCTRL1.bit.CONT_RUN = 1; 进行配置
7. 启动ADC的方式
启动方式:1、软件触发。 2、ePWMx SOC。3、XINT2_ADCSOC 三种触发方式
8. 序列发生器覆盖功能
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0;
在级联模式下,禁止覆盖功能时,若采样最大通道设为7,则在第8的通道采样完成,ADC转换值也更新到了ADCRESULT0~7中时,指针将重0开始,也就是转换结果重新从ADCRESULT0开始存入。 启动覆盖模式:与上面一样,只是当第一次转换结果都存入ADCRESULT0~7时,指针将继续往下存,即接下来的转换结果从ADCRESULT8开始,直到更新到ADCRESULT15,再从ADCRESULT0 存入。这在高速转换时,有利于ADC数据的捕获。
最后,需要注意的是,AD采样结果存储的顺序,同步级联模式结果储存顺序是在结果寄存器里面顺序存储。在双序列模式下,转换结果从结果寄存器0开始交叉存放,例如采样数据1 存在结果寄存器1(RESULT0),数据8存在结果寄存器2(RESULT1),一次类推。在读结果寄存器数据时,可以使用0等待状态的地址(结果寄存器的映射地址),防止高速转换时数据丢失,并且这里的数据是右对齐的 从0x0B00开始。
需要整个配置文件请猛戳下面链接
https://m.eeworld.com.cn/bbs/forum.php?mod=attachment&aid=MzEzNjMwfDAyYWYyOWU3ZDM4NDJjMGQ3ODgwY2Q1Mjc2NDAzN2E4fDE3MzIwNDgxNjM%3D&request=yes&_f=.c
搞完收工,最后
此内容由EEWORLD论坛网友乘鲤而去原创,如需转载或用于商业用途需征得作者同意并注明出处