主题中讨论的其他器件: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



