This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28335:初始化 ADC

Guru**** 2022830 points
Other Parts Discussed in Thread: CONTROLSUITE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/565423/tms320f28335-initiallizating-adc

器件型号:TMS320F28335
Thread 中讨论的其他器件:controlSUITE

Hiii、

    我在 C28x F28335 Delphino 微控制器上工作、在这里、我想从 ADC 的所有16个通道读取 ADC 计数值(我不使用 PWM 触发寄存器)、并将这些值记录到 ADC ISR 中。

    这里我使用的是25MHz ADC 时钟(SysCtrlRegs.HISPCP。all = 0x3)和 sysclock 150Mhz。在这里,我将读取一些值473作为 ADC 计数(在每个通道上,如果我使  AdcRegs.ADCMAXCONV.all = 0x000; ) 将寄存   器更改为 AdcRegs.ADCMAXCONV.ALL = 0x0FFF 未正确设置中断、即问题出在 ADC 初始化、下面是我附加的代码。  

//######################################################################################################################
//
//文件:example_2833xAdc.c
//
//标题:DSP2833x ADC 示例程序。
//
//假设:
//
//此程序需要 DSP2833x 头文件。
//
//确保在中正确定义了 CPU 时钟速度
// DSP2833x_Examples.h 再编译此示例。
//
//连接要转换为 A2和 A3的信号。
//
//根据提供的信息,此项目配置为“引导至 SARAM”
//操作。 2833x 引导模式表如下所示。
//有关配置 eZdsp 引导模式的信息,
//请参阅 eZdsp 附带的文档,
//
//$Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// pu pu pu pu
//================================================================================
// 1 1 1 1跳转到闪存
// 1 1 0 SCI-A 引导
// 1 0 1 SPI-A 引导
// 1 0 0 I2C-A 引导
// 1 0 1 1 eCAN-A 引导
// 1 0 1 0 McBSP-A 引导
// 1 0 1跳转到 XINTF x16
// 1 0 0 0跳转到 XINTF x32
// 0 1 1 1跳转到 OTP
// 0 1 0并行 GPIO I/O 引导
// 0 1 0 1并行 XINTF 引导
// 0 1 0 0跳转至 SARAM <-"引导至 SARAM"
// 0 1 1分支检查引导模式
// 0 1 0引导至闪存,绕过 ADC 校准
// 0 0 0 1引导至 SARAM,旁路 ADC 校准
// 0 0 0 0 0引导至 SCI-A、旁路 ADC 校准
// Boot_Table_End$
//
//描述:
//
//此示例将 PLL 设置为 x10/2模式。
//
//对于150MHz 器件(默认)
//将 SYSCLKOUT 除以6以达到25.0Mhz HSPCLK
//(假设为30Mhz XCLKIN)。
//
//对于100MHz 器件:
//将 SYSCLKOUT 除以4以达到25.0Mhz HSPCLK
//(假设为20Mhz XCLKIN)。
//
//中断被启用并且 ePWM1被设置为生成一个周期
SEQ1上的// ADC SOC。 转换了 ADCINA3和 ADCINA2两个通道。
//
//监视变量:
//
// Voltage1[10]最后10个 ADCRESULT0值
// Voltage2[10]最后10个 ADCRESULT1值
//转换计数当前结果编号0-9
// LoopCount 空闲循环计数器
//
//
//######################################################################################################################
//
//原始作者:D.F.
//
//$TI 发行版:2833x/2823x 头文件和外设示例 V133 $
//$Release Date:2012年6月8日$
//######################################################################################################################

#include "DSP28x_Project.h"//器件头文件和示例 include 文件

//此文件中找到的函数的原型语句。
中断空 ADC_ISR (空);

//此示例中使用的全局变量:
uint16环计数;
UINT16转换计数;
uint16 Voltage1[10];
uint16 Voltage2[10];
uint16 Voltage3[10];
uint16 Voltage4[10];
uint16 Voltage5[10];
uint16 Voltage6[10];
uint16 Voltage7[10];
uint16 Voltage8[10];
uint16 Voltage9[10];

MAIN ()

//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 DSP2833x_SYSCTRL.c 文件中。
InitSysCtrl();


EALLOW;
#IF (CPU_FRQ_150MHz)//默认- 150MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0MHz
#endif
#IF (CPU_FRQ_100MHz)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)= 25.0MHz
#endif
EDIS;

//定义 ADCCLK 时钟频率(小于或等于25MHz)
//假设 InitSysCtrl()已将 SYSCLKOUT 设置为150MHz
EALLOW;
SysCtrlRegs.HISPCP。all = ADC_MODCLK;
EDIS;

//步骤2. 初始化 GPIO:
//此示例函数位于 DSP2833x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
// InitGpio();//针对此示例跳过

//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;

//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 DSP2833x_PIECTRL.c 文件中。
InitPieCtrl();

//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;

//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 DSP2833x_PieVect.c 中找到
InitPieVectTable();

//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.ADCINT =&ADC_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//步骤4. 初始化所有器件外设:
//此函数位于 DSP2833x_InitPeripherals.c 中
// InitPeripherals ();//此示例不需要
InitAdc ();//对于此示例,初始化 ADC

//步骤5. 特定于用户的代码、启用中断:

//在 PIE 中启用 ADCINT
PieCtrlRegs.PIEIER1.bit.INTx6=1;
IER |= M_INT1;//启用 CPU 中断1
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

LoopCount = 0;
ConversionCount = 0;

//配置 ADC
AdcRegs.ADCMAXCONV.ALL = 0x0FFF;//在 SEQ1上设置全部16个转换// 0x000F - 0x00FF

// AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7;
// AdcRegs.ADCMAXCONV.bit.MAX_CONV2= 0x7;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;//将 ADCINA0设置为第一个 SEQ1转换器
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;//将 ADCINA1设置为第2个 SEQ1转换器
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;//将 ADCINA2设置为第3个 SEQ1转换器
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;//将 ADCINA3设置为第4个 SEQ1转换器

AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;//将 ADCINA4设置为第5个 SEQ2转换器
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;//将 ADCINA5设置为第6个 SEQ2转换器
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;//将 ADCINA6设置为第7个 SEQ2转换器
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;//将 ADCINA7设置为第8个 SEQ2转换器

AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8;//将 ADCINB0设置为第9个 SEQ3转换器
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9;//将 ADCINB1设置为第10个 SEQ3转换
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA;//将 ADCINB2设置为第11个 SEQ3转换
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB;//将 ADCINB3设置为第12个 SEQ3转换

AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC;//将 ADCINB4设置为第13个 SEQ4转换
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD;//将 ADCINB5设置为第14个 SEQ4转换
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE;//将 ADCINB6设置为第15个 SEQ4转换
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF;//将 ADCINB7设置为第16个 SEQ4转换

// AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;//从 ePWM 启用 SOCA 以启动 SEQ1
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位 SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;//为 SEQ1启用软件触发器(在单独的指令中)

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//启用 SEQ1中断(每个 EOS)

// AdcRegs.ADCTRL2.bit.ePWM_SOCB_SEQ2 = 1;//从 ePWM 启用 SOCB 以启动 SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;//复位 SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 1;////启用 SEQ2的软件触发(在单独的指令中)

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = 1;//启用 SEQ2中断(每个 EOS)
AdcRegs.ADCTRL1.bit.CONT_RUN = 1;

/*
//假设 ePWM1时钟已在 InitSysCtrl()中启用;
EPwm2Regs.ETSEL.bit.SOCAEN = 1;//在组上启用 SOC
EPwm2Regs.ETSEL.bit.SOCASEL = 1;//4;//从 CPMA 中选择 SOC (向上计数)
EPwm2Regs.ETPS.bit.SOCAPRD = 1;//在发生第一个事件时生成脉冲

//SOCB
EPwm2Regs.ETSEL.bit.SOCBEN = 1;//在 B 组上启用 SOC
EPwm2Regs.ETSEL.bit.SOCBSEL = 1;//4;//在向上计数时从 CPMB 中选择 SOC
EPwm2Regs.ETPS.bit.SOCBPRD = 1;//在发生第一个事件时生成脉冲

EPwm2Regs.CMPA.half.CMPA = 0x0080;//设置比较值
EPwm2Regs.TBPRD = 0xFFFF;//为 ePWM1设置周期
EPwm2Regs.TBCTL.bit.CTRMODE = 0;//向上计数并启动

*


//等待 ADC 中断
for (;;)

LoopCount++;


中断空 ADC_ISR (空)

Voltage1[ConversionCount]= AdcRegs.ADCRESULT0 >> 4;
Voltage2[ConversionCount]= AdcRegs.ADCRESULT1 >>4;
Voltage3[ConversionCount]= AdcRegs.ADCRESULT2 >>4;
Voltage4[ConversionCount]= AdcRegs.ADCRESULT3 >>4;
Voltage5[ConversionCount]= AdcRegs.ADCRESULT4 >>4;
Voltage6[ConversionCount]= AdcRegs.ADCRESULT5 >> 4;
Voltage7[ConversionCount]= AdcRegs.ADCRESULT6 >> 4;
Voltage8[ConversionCount]= AdcRegs.ADCRESULT7>>4;
Voltage9[ConversionCount]= AdcRegs.ADCRESULT8 >> 4;


//如果记录了40次转换,则重新开始
if (ConversionCount = 9)

ConversionCount = 0;

else ConversionCount++;

//为下一个 ADC 序列重新初始化
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位 SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//清除 INT SEQ1位
AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;//复位 SEQ1
AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1;//清除 INT SEQ1位
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;//确认 PIE 中断

返回;

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

空 InitAdc (空)

extern void DSP28x_usDelay (uint32计数);

EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
adc_cal();
EDIS;

AdcRegs.ADCTRL3.ALL = 0x00E0;//加电带隙/参考/ADC 电路
DELAY_US (ADC_USDELAY);//转换 ADC 通道之前的延迟

----------------------------------------------------------------------

以上是我对 ADC 的初始化。 请帮我解决这个问题。

提前感谢。

  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Narasimha、

    实现此目标的最佳方法可能是从 controlSUITE 中的以下示例开始:

    \controlSUITE\device_support\F2833x\v142\DSP2833x_examples_ccsv5\ADC_seqmode_test

    首先让该示例工作、然后对其进行修改以满足您的需求、然后重新测试以确保它不会在可能的情况下损坏。

    它在连续运行模式下永久转换。 为了使它能够满足您的需求、我认为您需要修改它以:
    -使用16个通道而不是1个通道
    -使用中断读取结果、而不是自旋等待循环
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Devin、
    我查看了示例代码(adc_seqmode_test.c)、当 iam 运行该代码时、我连续获得473个计数值而不是零、初始化是否有任何问题? 即、我采用25MHz 的 ADC 时钟、并采用 AdcRegs.ADCTRL3.ALL = 0x00E0;

    此致、
    Narasimha
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Narasimha、

    通道输入的电压是多少? 如果您将通道接地、则预计会出现接近0的情况。 如果它是浮动的、那么473可能是一个合理的转换结果。

    如果您在使用内置示例时未能获得良好的结果、我建议对硬件进行故障排除、以确保所有电源和基准电压及引脚均符合预期。 您使用的是什么硬件? 是 TI 套件还是定制板?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Davin、

           我使用的是定制板、  

    这是我的 ADC 硬件配置、

          ADCLO 和 ADCREFIN 设置为接地、

          ADCRESEXT 下拉电阻为20k Ω、

         ADCREFP、ADCREFM 被短接、并将其设置为100nF 接地

         所有 ADC 通道均设置为接地

    这里是我  的 ADC 施密特设计

    此致、

    Narsimha。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Narsimha、

    我认为您不能将 REFP 和 REFM 连接在一起;它们应该具有不同的电压。

    它们还应分别具有2.2uF 的电容、而不是100nF 的接地电容。

    请参阅

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    实际上、如果所有 ADC 输入都接地、为什么要初始化 ADC 并对该通道进行采样?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、

       我在度假很抱歉耽误了时间、在我的项目中、我使用的是我们原理图中的内部基准电压、这里的所有输入引脚都被告知接地(我的新定制板尚未到达)。 因此、我将使用相应的原理图在该板上工作。

       如果我从 controlSUITE 运行示例代码(adc_seqmode_test)、我无法正确转换零电压(接地)、是否存在任何问题?

    此致、

    Narasimha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Narasimha、

    由于 ADC 硬件被配置为禁用 ADC、在这种情况下预计会出现不稳定的转换结果。