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.

[参考译文] CCS/TMS320F28335:如何同时且尽可能快地读取 ADC 值?

Guru**** 2535750 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/612746/ccs-tms320f28335-how-to-read-adc-values-simultaneously-and-as-fast-as-possible

器件型号:TMS320F28335

工具/软件:Code Composer Studio

你好

我正在尝试执行一个项目、在该项目中、我需要使用 ADC 读取三个值、并对这些数据进行一些处理、然后选择合适的 GPIO。 此外、我需要测量每个环路中经历的时间、并在计算中使用该时间。 我使用了三个示例:ADCSOC、CpuTimer、GPIOSetup。 我的问题:

当我获取 ADC 值、并在变量中观察它们是否变为值、然后变为零、并继续执行此操作。 如何能够同时并尽可能快地读取 ADC 值。 (我不知道哪种触发速度最快)。 我应该更改代码的哪些部分?

构建项目后、我收到错误:"警告#10063-D:未指定"_c_int00"的入口点符号: "code_start"。 此错误是什么?

我在此处复制我的代码、如果您查看并查看我需要更改的代码部分、我将不胜感激:

#include "DSP28x_Project.h" //设备头文件和示例包括文件
#include 

//函数
void delay_loop (void);
void GPIO_select (void);
void GPIO_Setup1 (void);
void GPIO_Setup2 (void);
void GPIO_setup3 (void);
void StartTimer (void);
void StopTimer (void);
void ADC_ISR (void);

double phi1 (double cur, double vol, double t);

double phi2 (double cur, double vol, double t);

double phi3 (double cur, double vol、double t);

double phi4 (double cur、double vol、double t);

double phi5 (double cur, double vol, double t);

double phi6 (double cur, double vol, double t);


double phi16 (double cur, double vol, double t);


double phi17 (double cur, double vol, double t);

double phi18( double cur, double vol, double t);

double phi31 (double cur, double vol, double t);

double phi32 (double cur, double vol, double t);

double phi33 (double cur, double vol, double t);



double f1_1 (double cur, 双卷);

双 f1_2 (双卷、双卷);

双 f2_1 (双卷、双卷);

double f2_2 (双卷、双卷);

double f3_1 (双卷、双卷);

double f3_2 (双卷、 double vol);




//全局变量
int fr=50;//赫兹频率
int fr_unit_change=1;
long double t1=0;
long double delta_time;
double cpuTime1;
double cpuTime2;
double cpuTime;
double LoopCount;
double ConversionCount;
double Voltage1;
double Voltage2;
双电压3;
双电流= 0;
双电压= 0;
双电压= 0;
双电压1 = 0;双电流1 = 0;
double dt=0.00002;
double sum1=0;
double sum2=0;
double sum3=0;
double W[12]={115.9200、
0.4708、
1.0362、
14.8852、
228.9501、
84.3829、
-1.7023、
-0.9528、
-3.9271、
-1.6024、
-89.6407、
-470.1129};

int r1=10; //电感内部电阻
double l1=560e-6;//电感
器 double c1=100e-6;//电容
double vs=3.3; //输入直流电压
int RL=10; //加载

int f=1;//更改时间单位 t=f*tau
int a=1; //标准化电容器电压 Vc=a*vol
int b=1; //使电感器电流 iL=b*curdouble
w=2*3.14;



void main (void)
{
InitSysCtrl();




EALLOW;
#define ADC_MODCLK 0x3
EDIS;


EALLOW;
SysCtrlRegs.HISPCP。all = ADC_MODCLK;
EDIS;

Dint;
InitPieCtrl();

GPIO_SELECT();

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

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

InitCpuTimer();//对于本示例,仅初始化
(;){的 CPU 计时器
StartTimer();
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.ADCINT =&ADC_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

InitAdc ();//对于此示例,初始化 ADC
PieCtrlRegs.PIEIER1.bit.INTx6=1;
IER |= M_INT1; //启用 CPU 中断1
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM

//

LoopCount = 0;
ConversionCount = 0;

//
//配置 ADC
//
AdcRegs.ADCMAXCONV.ALL = 0x0002; //在 SEQ1上设置2 conv
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;//将 ADCINA2设置为第一个 SEQ1转换器
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;//将 ADCINA3设置为第2个 SEQ1转换器
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x4;
//
//从 ePWM 启用 SOCA 以启动 SEQ1
//
AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;

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

//
//假设 ePWM1时钟已在 InitSysCtrl()中启用;
//
EPwm1Regs.ETSEL.bit.SOCAEN = 1; //在组上启用 SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4;//从 CPMA 中选择 SOC、以进行递增计数
EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲
EPwm1Regs.CMPA.half.CMPA = 0x0080;//设置比较值
EPwm1Regs.TBPRD = 0xFFFF; //为 ePWM1设置周期
EPwm1Regs.TBCTL.bit.CTRMODE = 0;//向上计数并启动

//
//等待 ADC 中断
//

vol1 = voltage *3/4095;
cur1 = Current*3/4095;

sum1=W[0]*phi1 (f1_1 (cur1、vol1)、f1_2 (cur1、vol1)、fmod (t1)+dt)+W[1](f1_1 (vol1、vol1、vol1)、f1_2 (cur1、t1)、t1 (cur1)、t1、t1、t1 (cur1)、t1、t1、t1)、t1 (vol1)、t1、t1、t1 (vol1、t1、t1、t1)、t1、t1、t1 (cur1)、t1、t1、t1、t1、t1、t1、t1、t1)、t1 (vol1、t1)、t1 (vol1、t1)、t1、t1、t1 (vol1、t1、t1)、t1、t1、t1、t1、t1、t1 (vol1)、t1 (vol1、t1)、t1、t1 (cur1、t1)、t1

sum2=W[0]*phi1 (f2_1 (cur1、vol1)、f2_2 (cur1、vol1)、fmod (t1、1)+w[1]、voli2 (f2_1、vol1、vol1)、f2_2 (cur1、t1)、t1、t1、t1 (cur1)、t1、t1、t1、t1 (vol1)、t1、t1、t1、t1、t1、t1)、t1、t1、t1 (vol1、t1、t1、t1)、t1、t1、t1、t1、t1、t1 (vol1、t1)、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1 (vol1)、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1、t1

sum3=W[0]*phi1 (f3_1 (cur1、vol1)、f3_2 (cur1、vol1)、fmod (t1、1+dt)+W[1]+phi2 (f3_1、vol1、vol1)、f3_2 (cur1、t1)、t1、t1 (cur1)、t1、t1、t1、t1、t1 (vol1)、t1)、t1、t1 (curod (1)、t1、t1、t1)、t1、t1、t1 (1)、t1、t1、t1、t1、t1、t1、t1、t1 (vol1)、t1)、t1、t1 (vol1 (vol1)、t1、t1)、t1 (vol1、t1)、t1 (vol1)、t1 (vol1、t1、t1)、t1 (vol1)、t1 (vol1、t1)、t1、t1、t1、t1、t

如果((sum1<=sum2)&&(sum1<=sum3)){
GPIO_Setup1();
}
否则、如果((sum2<=sum1)&&(sum2<=sum3)){
GPIO_Setup2();
}
否则{
GPIO_setup3();
}

StopTimer();
Δ 时间=cpuTime*6.66e-9;
t1=t1+delta_time;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void GPIO_select (void)
{
EALLOW;
//GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;//启用 GPIO6上的上拉

GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;// GPIO6 = GPIO6
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;// GPIO6 =输出
GpioCtrlRegs.GPAMUX1.bit.GPIO7=0;
GpioCtrlRegs.GPADIR.bit.GPIO7=1;
GpioCtrlRegs.GPAMUX1.bit.GPIO8=0;
GpioCtrlRegs.GPADIR.bit.GPIO8=1;
GpioCtrlRegs.GPAMUX1.bit.GPIO9=0;
GpioCtrlRegs.GPADIR.bit.GPIO9=1;
EDIS;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void StartTimer (void)
{
// cpuTime1 = 0;

EALLOW;
CpuTimer2Regs.TCR.bit.TRB = 1; //将 CPU 定时器重置为周期值
CpuTimer2Regs.TCR.bit.TSS = 0; //启动或复位 CPU 定时器2.
cpuTime1 = CpuTimer2Regs.TIM.all; //在代码前获取 CPU 定时器2的值
EDIS;
}

void StopTimer (void)
{

EALLOW;
cpuTime2 = CpuTimer2Regs.TIM.all;//获取代码后 CPU 定时器2的值
cpuTime = cpuTime1 - cpuTime2; //使用 cpuTimer2计算时间
CpuTimer2Regs.TCR.bit.TSS = 1; //启动或复位 CPU 定时器2.
EDIS;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
_interrupt void
ADC_ISR (void)
{
Voltage1 = AdcRegs.ADCRESULT0 >>4;
Voltage2 = AdcRegs.ADCRESULT1 >>4;
Voltage3 = AdcRegs.ADCRESULT2 >>4;
电流= Voltage2- Voltage1;
电压=电压3-电压2;

//
//如果记录了40次转换,则重新开始
//

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

回返;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

    ATA、

    看起来您在 main()循环中有完整的模块初始化调用。  不建议这样做、因为初始化序列会在运行期间以插入方式中断模块。  我怀疑这就是您的 ADC 结果复位为0的原因。

    ADC ISR 通常是在结果准备就绪后立即访问结果的最简单方法。

    显示入口点警告、因为默认情况下、编译器将在初始化 C 环境的"_c_int00"处开始执行代码。  对于这些示例项目、代码执行入口点被覆盖到 xxx_CodeStartBranch.asm 中的"code_start"。  这主要是为了在跳转到"_c_int00"部分之前禁用看门狗。

    Tommy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Tommy。
    您能否指定您的初始化含义? 因为在模板示例中,所有初始化都在主()循环中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    除了实际数学之外、几乎所有的 for (;)循环。

    模块/实验6可能有助于参考: processors.wiki.ti.com/.../C2000_Archived_Workshops