本文记录一下仿真模式下的printf()的使用,ADC,DMA,
目录
一、仿真模式下的printf()
这块推荐这个:CCS中printf()的使用
其实想找一下用仿真器的COM口做串口的方法,没有找到。这个在CCS仿真模式下直接用printf的方式,还挺方便的。
二、ADC
F28335 的 ADC 模块主要包括以下特点:
- --12 位模数转换
- --2 个采样保持器(S/H)
- --同时或顺序采样
- --模拟电压输入范围 0-3V
- --ADC 转换时钟频率最高可配置为 25MHz,采样带宽 12.5MHz
- --16 通道模拟输入
- --排序器支持 16 通道独立循环“自动转换”,每次转换通道可以软件编程 选择。
- --16 个结果寄存器存放 ADC 转换的结果,转换后的数字量表示为: 数字值=4095*(输入模拟值-ADCLO)/3,输入模拟值在 0-3V 之间
-
--多个触发源启动 ADC 转换(SOC):
①S/W--软件立即启动
②外部引脚
③ePWMx SOCA 启动
④ePWMx SOCB 启动
- --灵活的中断控制,允许每个或者每隔一个序列转换结束产生中断请求
- --排序器可工作在启动/停止模式
- --采样保持(S/H)采集时间窗口有独立的预定标控制
在使用 ADC 转换模块时,特别要注意的是 F28335 的 AD 的输入范围 0-3V,若 输入负电压或高于 3V 的电压就会烧坏 AD 模块,这一点要务必引起重视。超出输 入范围的电压可在前级电路,通过电阻进行分压,或经运放比例电路进行处理后 再输入。连接到 ADCINxx 引脚的模拟输入信号要尽可能的远离数字电路信号线, ADC 模块的电源供电要与数字电源电源隔离开,避免数字电源的高频干扰,ADC 的参考源是影响 AD 精度的一个重要因数,注意 ADC 参考源的电压纹波处理
ADC的内部框图:16个输入通道,分AB两组,两个采样保持器,一个转换模块,两个排序器。
由于有两个采样保持器,所以根据工作方式分:顺序采样,同步采样。后面讲。
双排序器根据工作方式分:级联模式,双排序器模式。
以上两个模块排列组合,ADC共有4中模式。
2.1 ADC模式
1,级联模式
在级联排序器操作方式下,2 个 8 状态排序器(SEQ1 和 SEQ2)构成一个 16状态的排序SEQ。只能设置一个触发源,按照顺序转换。
2,双排序器模式
两个排序器独立运行,分别独立设置一个触发源,只有一个AD转换模块,所以分时复用,转换顺序下图。
3,顺序采样
和级联排序模式下一样,就是按照顺序转换。级联排序其顺序采样也是最常用的模式。
4,同步采样
如果一个输入来自 ADCINA0-ADCINA7,另一个输入来自 ADCINB0-ADCINB7, ADC 能够实现 2 个 ADCINxx 输入的同时采样。此外,要求 2 个输入必须有同样的 采样和保持偏移量(比如 ADCINA4 和 ADCINB4,不能是 ADCINA7 和 ADCINA6)。 为了让 ADC 模块工作在同步采样模式,必须设置 ADCTRL3 寄存器中的 SMODE_SEL 位为 1。
在同步采样模式下,CONVxx 寄存器的最高位不起作用,每个采样和保持缓冲 器对 CONVxx 寄存器低 3 位确定的引脚进行采样。例如,如果 CONVxx 寄存器的值 是 0110b,ADCINA6 就由采样保持器 A 采样,ADCINB6 有采样保持器 B 采样,和 1110b 的效果是一样的,如果 CONVxx 寄存器的值是 1001b,ADCINA1 由采样和保 持器 A 采样,ADCINB1 由采样和保持器 B 采样。采样保持两路可以同步进行,因 为有两个采样保持器,但是转换不可能同时进行。转换器首先转换采样保持器 A 中锁存的电压量,然后转换采样保持器 B 中锁存的电压量。采样保持器 A 转换的 结果保存到当前的 ADCRESULTn 寄存器(如果排序器已经复位,SEQ1 的结果放到 ADCRESULT0),采样保持器 B 转换的结果保存到下一个(顺延)ADCRESULTn 寄 存器(如果排序器已经复位,SEQ1 的结果放到 ADCRESULT1),结果寄存器指针 每次增加 2。
2.2 触发源,中断,覆盖功能
1,触发源
2,中断
在不同工作模式下如何使用中断模式 1 和中断模式 2。
情形 1:在第 1 个和第 2 个序列中采样的数量不相等。
(1)中断模式 1(每个 EOS 到来时产生中断请求)
①排序器用 MAX_CONVn=1 初始化,转换 I1 和 I2。
②在中断服务子程序 a 中,通过软件将 MAX_CONVn 的值设为 2,转换 V1、V2 和 V3。
③在中断服务子程序 b 中,完成下列任务:
--将 MAX_CONVn 的值再次设置为 1,转换 I1 和 I2。
--从 ADC 结果寄存器中读出 I1、I2、V1、V2 和 V3 的值。
--复位排序器。
④重复操作第②、③步。每次 SEQ_CNTRn 等于 0 时产生中断,并且中断能够 被识别。
情形 2:在第 1 个和第 2 个序列中采样的数量相等。
(2)中断模式 2 操作(每隔一个 EOS 信号产生中断请求)
①排序器设置 MAX_CONVn=2 初始化,转换 I1、I2、I3 或 V1、V2 和 V3。
②在服务子程序 b 和 d 中,完成下列任务。
--从 ADC 结果寄存器中读出 I1、I2、I3 或者 V1、V2 和 V3 的值。
--复位排序器。
--重复第②步。
情形 3:两个序列的采样个数是相等的(带空读)
(3)中断模式 2(隔一个 EOS 信号产生中断请求)
①MAX_CONVn=2,初始化序列器,转换 I1、I2 和 x(空采样)。
②在中断服务子程序 b 和 d 中,完成下列任务:
--从 ADC 结果寄存器中读出 I1、I2、x、V1、V2 和 V3 的值。
--复位排序器。
--重复第②步。在①中,I1、I2 后的 X 采样为一个空的采样,其实并没有要求采样。然而利用模式 2 间隔产生中断请求的特性,可以减小中断服务子程序和 CPU 的开销。
3,排序器覆盖功能:(开DMA时,需要使能)
通常在运行模式下,排序器 SEQ1、SEQ2 或者级联 SEQ 用于选择 ADC 通道, 并将转换的结果存储在相应的 ADCRESULTn 寄存器中。在 MAX_CONVn 设置的转换 结束时,排序器自动返回 0。在使用排序器覆盖功能时,排序器的自动返回可通 过软件控制,这由 ADC 控制寄存器 1(ADCCTRL1)的第 5 位控制。例如假定 SEQOVRD 位为 0,ADC 工作在级联模式下的连续转换模式,MAX_CONV1 设置为 7,通常情况 下,排序器会递增并将 ADC 转换结果更新结果寄存器到 ADCRESULT7 寄存器,然 后返回到 0,。当 ADCRESULT7 寄存器更新完成后,相应的中断标志位被置位。当 SEQ_OVRD 位被重新置位,排序器在更新 7 个结果寄存器后不再回绕到 0,而将继 续增加,并更新 ADCRESULT8 寄存器,直到 ADCRESULT15 为止。ADCRESULT15 寄 存器更新完毕再返回到 0。这可以将结果寄存器看成 FIFO,用于 ADC 对连续数据 的捕捉。当 ADC 在最高数据速率下进行转换时,这个功能有助于捕捉 ADC 的数据
2.3 如何初始化配置
ADC有8个设置寄存器,不过使用起来很简单。
ADC配置步骤:
1,ADC外设时钟使能
2,高速外设时钟分频。从系统时钟进入ADC模块的,最高25M。
3,ADC初始化。
4,ADC内核时钟分频。用于ADC转换的。
5,采样持续时间。
6,排序器模式
7,采样方式。
8,设置输入通道,开几个口就设置几个。
9,设置最大通道数。
10,设置是否连续转换。
(11,排序器覆盖模式使能,开DMA时)
(12,使能SOC触发。用SOC信号触发模式时)
13,使能排序器。
例程,非DMA模式
#define ADC_MODCLK 3
#define ADC_CKPS 0x1 // ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
#define ADC_SHCLK 0xf // S/H width in ADC module periods = 16 ADC clocks
void ADC_Init(void)
{
// Specific clock setting for this example:
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
EDIS;
// Specific clock setting for this example:
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK) 25M
EDIS;
InitAdc(); // For this example, init the ADC
// Specific ADC setup for this example:
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; //时钟分频25/(ADC_CKPS+1)=12.5M
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; //采样持续时间,最大值
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 级联模式
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; //顺序采样
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; //ADC通道0配置AIN0
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 1; //ADC通道0配置AIN1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 2; //ADC通道0配置AIN2
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 2; //最大转换通道数
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // 非连续转换模式
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1; //
// Start SEQ1
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; //使能epwm_SOCA信号的触发SQE1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; //使能SEQ1
}
Uint16 Read_ADCValue(void)
{
while (AdcRegs.ADCST.bit.INT_SEQ1== 0);
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
return AdcRegs.ADCRESULT0>>4;
}
三、DMA
28335的DMA用起来很简单,只是几个功能函数参数可能有点不好理解。
DMA配置方式:
1,使能DMA外设时钟,
2,初始化DMA。
3,配置下面几个函数:
DMACH1AddrConfig
DMACH1BurstConfig
DMACH1TransferConfig
DMACH1WrapConfig
DMACH1ModeConfig4,启动DMA。
- DMACH1AddrConfig:两个参数:源指针,目的指针。
-
DMACH1BurstConfig:帧函数,一个触发信号执行一次
三个参数:
数据个数(类型Uint16),
每传一个数据,源指针增加量,
每传一个数据,目的指针增加量。
-
DMACH1TransferConfig:传输函数,主要设置几帧数据产生一个中断
三个参数:
帧个数,达到数会产生中断,
每传一帧,源指针增加量,
每传一帧,目的指针增加量。
-
DMACH1WrapConfig:打包函数,主要设置返回步长。
四个参数:
执行多少帧,源指针将返回,
源指针返回之后,加上一个偏移量。
执行多少帧,目的指针将返回,
目的指针返回之后,加上一个偏移量。
(其实不难理解,我们看一下寄存器的说明就清楚了。)
-
细心的可能发现 DMACH1TransferConfig 和 DMACH1WrapConfig 指针偏移量某些情况下好像有功能重合。数据手册中提到过,DMACH1WrapConfig设置偏移量时,会忽略DMACH1TransferConfig的偏移量。DMACH1WrapConfig的打包帧个数大于DMACH1TransferConfig时,DMACH1WrapConfig将失效。
-
DMACH1ModeConfig是DMA配置寄存器:
①persel--选择触发源,值为下列选项:
DMA_SEQ1INT--------ADC
DMA_SEQ2INT--------ADC
DMA_XINT1 --------外部中断
DMA_XINT2 --------外部中断
DMA_XINT3 --------外部中断
DMA_XINT4 --------外部中断
DMA_XINT5 --------外部中断
DMA_XINT6 --------外部中断
DMA_XINT7 --------外部中断
DMA_XINT13 --------外部中断
DMA_TINT0 --------CPU 时钟
DMA_TINT1 --------CPU 时钟
DMA_TINT2 --------CPU 时钟
DMA_MXEVTA --------McBSP-A
DMA_MREVTA --------McBSP-A
DMA_MXREVTB --------McBSP-B
DMA_MREVTB --------McBSP-B
②perinte--使能触发源,值为 PERINT_DISABLE 或 PERINT_ENABLE。
③oneshot--使能 oneshot 模式,值为 ONESHOT_DISABLE 或 ONESHOT_ENABLE。此模式下,一次触发完成全部 burst。
④cont--使能 Continuous 模式,值为 CONT_DISABLE 或 CONT_ENABLE。此模 式下,传送完毕后 DMA 重新被初始化,并等待触发源。
⑤synce--使能外围设备同步,值为 SYNC_DISABLE 或 SYNC_ENABLE。
⑥syncsel--同步选择。值为 SYNC_SRC 或 SYNC_DST。
⑦ovrinte--使能溢出中断。值为 OVRFLOW_DISABLE 或 OVEFLOW_ENABLE。
⑧datasize--每次传送位数。值为 SIXTEEN_BIT 或 THIRTYTWO_BIT。
⑨chintmode--通道中断产生模式。CHINT_BEGIN:传送开始发中断。 CHINT_END:传送结束发中断。
⑩chinte--使能通道中断。值为 CHINT_DISABLE 或 CHINT_ENABL
上例程,
void DMACH1_ADC_Init(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock
EDIS;
// Initialize DMA
DMAInitialize();
// Configure DMA Channel
DMACH1AddrConfig(DMA_Dest,DMA_Source);
DMACH1BurstConfig(3,1,1); //每帧传4个数,每传一个数指针加1
DMACH1TransferConfig(9,1,1); //传10帧数据触发中断,每帧之间指针加1
DMACH1WrapConfig(0ffff,0,0ffff,0); //关闭打包
DMACH1ModeConfig(DMA_SEQ1INT, //触发源SEQ1
PERINT_ENABLE, //使能触发源
ONESHOT_DISABLE, //关闭单次运行
CONT_ENABLE, //使能连续运行
SYNC_DISABLE, //关闭同步
SYNC_SRC, //和源设备同步
OVRFLOW_DISABLE, //关闭溢出中断
SIXTEEN_BIT, //16位传送
CHINT_END, //传送结束产生中断
CHINT_ENABLE); //使能中断通道
StartDMACH1(); //启动DMA
}
interrupt void local_DINTCH1_ISR(void) // DMA Channel 1
{
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.bit.ACK7 = 1;
// asm (" ESTOP0");//ok
// for(;;);
}
待续。。