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.

[参考译文] TMS320F28379D:由 CPU 定时器触发的 ADC

Guru**** 2610425 points
Other Parts Discussed in Thread: C2000WARE, TMS320F28379D

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/689612/tms320f28379d-adc-triggered-by-cpu-timer

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

您好!  

我的主管要求我使用时间中断而不是 ePWM 来触发 ADC、因此我修正了 ADC_SoC_ePWM 示例、使其由 CPU timer0触发、如下所示程序代码所示。

算法工作、但我注意到、当我将采样周期从83.33微秒更改为41.665微秒时、采样周期不正确、 下图所示的两 种情况下的 ADC 结果显示、采样周期仍然相同、为83.33微秒、结果是输入信号变为1kHz、但实际上是2kHz 方波。  

//######################################################################################################################
//
//文件:adc_soc_ePWM_cpu01.c
//
//标题:针对 F2837xD 通过 ePWM 触发 ADC。
//
//! addtogroup cpu01_example_list
//!

ADC ePWM 触发(ADC_SoC_ePWM)


//!
//! 此示例设置 EPWM 以定期触发 ADC。
//!
//! 程序运行后,内存将包含:\n
//! -\b 结果:一系列的模数转换样本
//! 引脚 A0。 采样之间的时间根据周期确定
//! PWM 计时器的功能。
//
//######################################################################################################################
//$TI 版本:F2837xD 支持库 V210 $
//$Release Date:Tue Nov1 14:46:15 CDT 2016 $
//版权所有:版权所有(C) 2013-2016 Texas Instruments Incorporated -
// http://www.ti.com/ 保留所有权利$
//######################################################################################################################

//
//包含的文件
//
#include "F28x_Project.h"
#include "stdio.h"
#include "math.h"
#include
#include
#include

//
//函数原型
//
void ConfigureADC (void);
void ConfigureEPWM (void);
void SetupADCTimer0 (uint16通道);
//void SetupADCepwm (uint16通道);
_interrupt void CPU_timer0_ISR (void);

void scia_echoback_init (void);
void scia_fifo_init (void);
void scia_xmit (int a);
void scia_msg (char * msg);
void send_result (uint16 res);

//
//定义
//
#define results_buffer_size 64 //缓冲区大小为256
文件*myfil;
//#define ADC_SAMPLE_PERIOD 0x1000 // 1999 =具有100MHz ePWM 时钟的50kHz 采样

//
//全局
//
uint16 AdcaResults[results_buffer_size];
uint16 AdcaResults1[results_buffer_size];    

uint16结果索引;
uint16结果索引 x1;
//uint16 LoopCount;//来自 sci 示例
易失性 uint16 bufferFull;
易失性 uint16 bufferFull1;
uint16 Vin;



int z;
char *msg;

void main (void)

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

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

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

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

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

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

//
//映射 ISR 函数
//
EALLOW;
PieVectTable.TIMER0_INT =&CPU_timer0_ISR;
EDIS;

//启动 CPU 定时器并对其进行配置

InitCpuTimer();//对于此示例,只初始化 CPU 计时器
ConfigCpuTimer (&CpuTimer0、200、83.33);                       //将 CPU 时钟配置为200MHz 并将中断配置为12kHz

//
//配置 ADC 并为其加电

//

ConfigureADC();

//
//配置 ePWM
//
// ConfigureEPWM();

//
//在通道0上设置用于 ePWM 触发转换的 ADC
//


SetupADCTimer0 (0);

//
//启用全局中断和更高优先级的实时调试事件:
//
IER |= M_INT1;//启用组1中断
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

//
//初始化结果缓冲区
//
for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)

AdcaResults[resultsIndex]=0;


resultsIndex = 0;
bufferFull = 0;

for (results 索引 x1 = 0;results 索引 x1 < results_buffer_size;results 索引 x1++)

AdcaResults1[结果 x1]= 0;


结果索引 x1 = 0;
bufferFull1 = 0;
//
//启用 PIE 中断
//

PieCtrlRegs.PIEIER1.bit.INTx7=1;


//
//对于这个示例、只初始化针对 SCI-A 端口的引脚。
// GPIO_SetupPinMux ()-设置 GPxMUX1/2和 GPyMUX1/2寄存器位
// GPIO_SetupPinOptions ()-设置 GPIO 的方向和配置
//这些函数可在 F2837xD_GPIO.c 文件中找到。
//
GPIO_SetupPinMux (28、GPIO_MUX_CPU1、1);
GPIO_SetupPinOptions (28、GPIO_INPUT、GPIO_PushPull);
GPIO_SetupPinMux (29、GPIO_MUX_CPU1、1);
GPIO_SetupPinOptions (29、GPIO_OUTPUT、GPIO_异 步);


scia_fifo_init();//初始化 SCI FIFO
scia_echoback_init ();//初始化用于 echoback 的 SCI


MSG ="\r\n\n 转换开始:\n\n";
scia_msg (msg);

//
//同步 ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;

CpuTimer0Regs.TCR.ALL = 0x4000;

//
//步骤5. 特定于用户的代码、启用_interrupts:
//将 GPIO34配置为 GPIO 输出引脚
//
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
EDIS;


CpuTimer0.RegsAddr->TCR.bit.tie = 1;

//
//将此循环与 cpu.timer 触发一起使用
//
操作

while (!bufferFull);
bufferFull = 0;

asm (" ESTOP0");
} while (1);


//
// ConfigureADC -写入 ADC 配置并为两者加电
// ADC A 和 ADC B
//
空配置 ADC (空)

EALLOW;

//
//写入配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4是6
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);

//
//将脉冲位置设置为晚期
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;

//
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//
//延迟1ms 以允许 ADC 加电时间
//
DELAY_US (1000);

EDIS;

//
// SetupADCepwm -设置 ADC ePWM 采集窗口
//
//void SetupADCepwm (uint16通道)
空设置 ADCTimer0 (UINT16通道)

uint16 acqps;

//
//根据分辨率确定最小采集窗口(在 SYSCLKS 中)
//
if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution)

acqps = 14;//75ns

否则、//分辨率为16位

acqps = 63;//320ns

//
//选择要转换的通道和转换结束标志
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道;//SOC0将转换引脚 A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1;对于 CPU.timer0触发器、ePWM1 SOCA/C = 5或= 1时触发//
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除

AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;//SOC1将转换引脚 A1
AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1;对于 CPU.timer0触发器、ePWM1 SOCA/C = 5或= 1时的//触发
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除

EDIS;

//中断 void timer0_ISR (void)
_interrupt void CPU_timer0_ISR (void)

CpuTimer0.InterruptCount++;
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
//
//确认此中断以从组1接收更多中断

AdcaResults[resultsIndex++]=AdcaResultRegs.ADCRESULT0;

if (results_buffer_size = resultsIndex)

myfile = fopen ("C:\\ti\\C2000Ware_1_00_03_00_Software\\device_support\\f2837xd\\examples\\cpu1\\adc_soc_ePWM\\AdcaResults1.txt"、"w");

if (myfile == NULL)

printf ("打开文件时出错。\n");

对于(z=0;z <RESULTS_BUFFER_SIZE;z++)

Vin =结果[z];
SEND_RESULT (Vin);
fprintf (myfile、"%d "、Vin);


否则 if (results_buffer_size > resultsIndex)

fclose (myfile);


if (results_buffer_size <= resultsIndex)

resultsIndex = 0;
bufferFull = 1;


// AdcaResults1[resultsIndexx1++]=(float32) AdcaResultRegs.ADCRESULT1 *(float32)(3/3096);
AdcaResults1[Indexsx1++]= AdcaResultRegs.ADCRESULT1;
if (results_buffer_size <= resultsIndex1)

结果索引 x1 = 0;
bufferFull1 = 1;

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志

PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;

//
// scia_echoback_init -测试1、SCIA DLB、8位字、波特率0x000F、
//默认,1个停止位,无奇偶校验
//

void scia_echoback_init ()

//
//注意:SCIA 外设的时钟被打开
//在 InitSysCtrl()函数中
//

SciaRegs.SCICCR.all = 0x0007;// 1停止位,无回路
//无奇偶校验,8个字符位,
//异步模式,空闲线协议
SciaRegs.SCICTL1.all = 0x0003;//启用 TX、RX、内部 SCICLK、
//禁用 RX ERR、睡眠、TXWAKE
SciaRegs.SCICTL2.all = 0x0003;
SciaRegs.SCICTL2.bit.TXINTENA=1;
SciaRegs.SCICTL2.bit.RXBKINTENA=1;

//
// SCIA 为9600波特
//@LSPCLK = 50MHz (200MHz SYSCLK) HBAUD = 0x02且 LBAUD = 0x8B。
//@LSPCLK = 30MHz (120MHz SYSCLK) HBAUD = 0x01且 LBAUD = 0x86。
//
SciaRegs.SCIHBAUD.ALL = 0x0002;//为0x0002
SciaRegs.SCILBAUD.ALL = 0x008A;//为0x008B

SciaRegs.SCICTL1.all = 0x0023;//从复位中撤回 SCI

//
// scia_xmit -从 SCI 发送一个字符
//
void scia_xmit (int a)

while (SciaRegs.SCIFFTX.bit.TXFFST!= 0){}
SciaRegs.SCITXBUF.ALL =A;


//
// scia_msg -通过 SCIA 发送消息
//
void scia_msg (char * msg)

int i;
I = 0;
while (msg[i]!='\0')



scia_xmit (msg[i]);
i++;


// scia_fifo_init -初始化 SCI FIFO
//
void scia_fifo_init()

SciaRegs.SCIFFTX.ALL = 0xE040;
SciaRegs.SCIFFRX.ALL = 0x2044;
SciaRegs.SCIFFCT.all = 0x0;


void send_result (uint16分辨率)

int b3、b2、b1、b0;
B3 =(res/1000)+48;
B2 =((res%1000)/100)+48;
B1 =((res%100)/10)+48;
B0 =(res%10)+48;
scia_xmit (B3);
scia_xmit (B2);
scia_xmit (b1);
scia_xmit (b0);
MSG ="、";
scia_msg (msg);

返回;

//
//文件结束
//

//

第一幅采样周期为83.33微秒的图片、当我运行项目并对2kHz 方波输入进行采样时、我得到了这幅图片。  

这个图片、当采样周期设置为41.665微秒、但当我运行程序时、它显示采样周期为83.33微秒。 如果您看 一下绘制的 adcresult、我的2KHz 输入将变为1kHz。 老实说、我试图解决这个问题、但我没有解决。 我尝试的一件事是将 CPU 配置寄存器中的 CPU 时钟从200MHz 更改为100MHz,但它不起作用。   

供您参考:我没有更改系统时钟设置。 因此、我想 pllsysclk 是200MHz 或100MHz。 我得到 IMULL=20、FULL=0.0、SYSDIVSEL = 1、如下图所示:  

非常感谢您的支持和帮助  

Hayder

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您使用的是定制板还是 TI 板、如 LaunchPad 或 controlCARD? 如果您使用的是 LaunchPad、则需要将_LAUNCHXL_F28379D 放入预定义符号中、以将 SYSCLK 配置为200MHz。

    您只是通过查看结果来测量周期、还是通过示波器在 ISR 中切换的 GPIO34?

    您可能应该使用 ADC ISR 读取 ADC 结果、而不是 CPUTimer ISR、以确保在读取结果之前完成转换。

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

    尊敬的惠特尼:  

    我使用的是 TMS320F28379D 实验板套件、我想它就是您所说的控制卡。

    我使用 ADC ISR 来读取 ADC 结果、但它没有解决问题。  

    查看测量的 GPIO34、它的作用域 我设置为在计时器中断中切换、这看起来不正确。  它应该会给我一个41.665微秒的中断周期、我为我正在使用的 CPU timer0设置了这个中断周期。

    是否有其他建议可以解决此问题?

    此致  

    Hayder  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的图形属性是什么? 您是否对两种采样率使用相同的设置?

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

    尊敬的惠特尼:  

    在随附的图片中查找图形属性。 我想我在更改中断周期时并没有改变特性中的采样率。

    当我将采样率更改为表示中断周期的值时、我在图上得到了正确的周期。  



    此致

    Hayder

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

    好的、很高兴您现在看到了预期的结果。 这是否能解决您的问题、或者是否比图形更能解决问题?

    惠特尼