主题中讨论的其他器件:C2000WARE
我将 PI 控制器用于直流/直流转换器控制。 当此行" UK_V = DCL_runPI (&pi1、rk、yk);"被执行时、编译器跳转到非法 ISR。 当 debuged 显示错误" cannot load from non-基 元位置"时。 尽管所有变量(UK、rk、yk)都具有相同的数据类型"float"。 编译器还发出警告"警告#10247-D:创建不带段的输出段"dclfuncs""
请帮帮我。
提前感谢您。
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.
我将 PI 控制器用于直流/直流转换器控制。 当此行" UK_V = DCL_runPI (&pi1、rk、yk);"被执行时、编译器跳转到非法 ISR。 当 debuged 显示错误" cannot load from non-基 元位置"时。 尽管所有变量(UK、rk、yk)都具有相同的数据类型"float"。 编译器还发出警告"警告#10247-D:创建不带段的输出段"dclfuncs""
请帮帮我。
提前感谢您。
我可以从函数名称中得知您使用的是库的 v1.0。 我建议您更新到最新的 v3.0、您可以在 C2000Ware 中找到该版本。 较新库中的等效函数是 DCL_runPI_C1。
该警告告诉您没有为控制器分配的内存。 您需要在链接器命令文件中添加一行、以告知链接器将该段放置在何处。 类似如下:
dclfuncs:>RAML4,page = 0
较新的库有几个工作示例、因此它可能有助于查看这些示例以了解如何完成此操作。
"非基元"错误可能与上述错误有关、但也请检查您是否已正确声明"pi1"控制器结构、以及该函数是否可见。
此致、
Richard
您好 Richard、
按照您的建议、我更新了最新版本 v3.0。 但这对我来说是行不通的。 以删除链接器文件中包含的命令警告。 但它为我提供了图像中所附的误差。 但是、我找不到任何其他链接器命令文件、那么为什么它会给我"多个链接器命令文件"的错误。 关于非基元位置、我已正确定义了它们。 但是、为了便于您了解、我要附加我的程序。
感谢您的支持。
此致、
Vidhi
//
//包含的文件
//
#include "F28x_Project.h"
#include "DCLF32.h"
//
定义
//
//////#define One (4095)// 2^12格式
//
//函数原型
//
void InitEPwm1 (void);
void InitEPwmISR (
isr);_ void _interrupt (void);void inepm2
(void) interrupt 1 (void);void Init_interrupt (void inoint (void);void Init_interrupt (void in2) //timestick associal 引脚42
//变量
//int i = 0;
int j = 0;
//int k = 0;
float pi_output;
//float error;
//float V_array[600];
float adc_volt[10];
float adc_cur[10];
float sum_v=0;
float sum_i=0;
float Vol_final;
float CURR_final;
float offset_V = 200;
float offset_I = 128;
float Duty_cycle = 0.5;
void ADC_CONFIG ();
void SetupADCSoftwareSync (void);
#define EPWM1_TIMER_TBPRD 1667 //周期寄存
器//#define EPWM1_CMPA 5000
#define EPWM1_DB 20;//对于500ns 的死区
#define pi_values_V{0.06f、0.1f、0.1f、1.0f、-1.0f、 0.1f}// Kp、Ki、I10、Sat_max、Sat_min、 sat_storage
float rk_V;//参考值
float YK_V;//测量的 ADC 信号
float UK_V;// PI 输出
DCL_PI pi1 = pi_values_V;
float V_ref=100;
int enable=0;
//电流控制
器#define pi_values_i{0.06f、0.1f、0.1f、0.01f、0.01f、0.0f、0.0f、0.0f、0.0f、0.0f、 0.1f}// Kp、Ki、I10、Sat_max、Sat_min、 sat_storage
float rk_i;//参考值
float YK_i;//测量的 ADC 信号
float UK_I;// PI 输出
//float lk_i = 0.0f;// saturation
DCL_PI Pi2 = pi_values_i;
uint32 EPwm2TimerIntCount =0;
uint32 EPwm1TimerIntCount
= 0;uint32
(void = 0);uint32 (void = 0)
InitSysCtrl();
// InitGpio();
//
启用 PWM1、PWM2
//
CpuSysRegs.PCLKCR2.bit.EPWM1=1;
CpuSysRegs.PCLKCR2.bit.EPWM2=1;
//在这种情况下、只需初始化 ePWM1、ePWM2、ePWM3的 GPIO 引脚
//这些函数位于 F2837xD_ePWM.c 文件
中//
InitEPwm1Gpio();
InitEPwm2Gpio();
//清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
//用户特定代码:
//interrupts 在此示例中不使用。
//
//映射 ISR 函数
//
EALLOW;
PieVectTable.EPWM1_INT =&epwm1_ISR;
PieVectTable.EPWM2_INT =&epwm2_ISR;
PieVectTable.XINT1_INT =∫μ_ext;
EDIS;
//初始化设备外设:
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
EDIS;
//
//配置 ePWM
//
InitEPwm1();
InitEPwm2();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;
//
//启用连接到 EPWM1-3 INT 的 CPU INT3:
//
IER |= M_INT3;
//
//在 PIE 中启用 ePWM INTn:组3中断1-3
//
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
//
启用全局中断和更高优先级的实时调试事件:
//
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM
//
在 PIE 中启用 XINT1和 XINT2:组1中断4和5
//启用连接到 WAKEINT 的 INT1:
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //启用 PIE 块
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; //启用 PIE 组1 int4
PieCtrlRegs.PIEIER1.bit.INTx5 = 1; //启用 PIE 组1 INT5
IER |= M_INT1; //启用 CPU INT1
EINT; //启用全局中断
//
// GPIO0为 XINT1
//
GPIO_SetupXINT1Gpio (42);//timetick 1
//
配置 XINT1
//
XintRegs.XINT1CR.bit.polarity = 1; //上升沿中断
//
//启用 XINT1
//
XintRegs.XINT1CR.bit.ENABLE = 1; //启用 XINT1
//
配置 ADC 并为其加电
adc_config();
SetupADCSoftwareSync();
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO42=0; // GPIO 42时钟节拍1
GpioCtrlRegs.GPBDIR.bit.GPIO42 = 0; //输入 qui DECIDI la DIR dell'interrupt
GpioCtrlRegs.GPBQSEL1.bit.GPIO42 = 0; // XINT1同步到 SYSCLKOUT 只
GpioCtrlRegs.GPCMUX1.bit.GPIO64=0;
GpioCtrlRegs.GPCDIR.bit.GPIO64=1; //引脚输出
GpioCtrlRegs.GPCQSEL1.bit.GPIO64=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO65=0;
GpioCtrlRegs.GPCDIR.bit.GPIO65=1; //引脚输出
GpioCtrlRegs.GPCQSEL1.bit.GPIO65=0;
GpioDataRegs.GPCCLEAR.bit.GPIO64=1;
GpioDataRegs.GPCCLEAR.bit.GPIO65=1;
DELAY_US (1000000);
GpioDataRegs.GPCSET.BIT.GPIO64=1;
GpioDataRegs.GPCSET.BIT.GPIO65=1;
DELAY_US (5000);
EDIS;
for (;;){
count++;
}
_interrupt
void epwm1_ISR (void)
{
J++;
// GpioDataRegs.GPCSET.BIO71 =1;
// GpioDataRegs.GPCSET.BIO70 =1;
// AdcaRegs.ADCSOCFRC1.ALL = 0x000F;
// AdcbRegs.ADCSOCFRC1.ALL = 0x000F;
AdccRegs.ADCSOCFRC1.ALL = 0x000F;
AdcdRegs.ADCSOCFRC1.ALL = 0x000F;
ADC_VOLT[j]=(AdccResultRegs.ADCRESULT0-OFFSET_V)*650/4095;//读取直流链路电压
adc_cur[j]=(2048-(AdcdResultRegs.ADCRESULT0+OFFSET_I))*35/2048;//读取电感器电流值
SUM_V = ADC_VOLT[j]+SUM_V;
sum_i = adc_cur[j]+sum_i;
if (j==10){
VOLT_FINAL = SUM_V/10;
CURR_FINAL = SUM_I/10;
SUM_V=0;
sum_i=0;
J=0;
}
if (enable=1){
YK_V = VOLT_final/400;//直流链路电压应在400V 以内
YK_I = CURR_FIND/20;//电感器电流应在20A 之内
RK_V = V_ref/400;
//================================================ 电压和电流 PI 控制器=================== //
UK_V = DCL_runPI_C1 (&pi1、rk_V、YK_V);
RK_I = UK_V;
UK_I = DCL_runPI_C1 (&Pi2、rk_I、YK_I);
//==================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== //
//
// ERROR =(rk_V-(float)(AdcaResultRegs.ADCRESULT0);
pi_output =(UK_i*EPwm2Regs.TBPRD);//针对 BDC 更改为 UK_I
Duty_cycle =((int) pi_output)/(EPwm2Regs.TBPRD);
EPwm2Regs.CMPA.bit.CMPA = pi_output;
}
EPwm1TimerIntCount++;
//清除此计时器的 INT 标志
//
EPwm1Regs.ETCLR.bit.INT = 1;
//
确认此中断以接收来自组3的更多中断
//
PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;
// GpioDataRegs.GPCCLEAR.bit.GPIO71 =1;
// GpioDataRegs.GPCCLEAR.bit.GPIO70 =1;
}
void adc_config(){
EALLOW;
//
////写入配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcbRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdccRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcdRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCB、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCC、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCD、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//
////延迟1ms 以允许 ADC 加电//
DELAY_US (1000);
EDIS;
}
中断 void int_ext (void)
{
ENABLE = 1;
// GpioDataRegs.GPBCLEAR.bit.GPIO42 =1;
//
//确认此中断以从组1获取更多内容
//
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;
}
void SetupADCSoftwareSync (void)
{
uint16 acqps;
//
//根据分辨率确定最小采集窗口(在 SYSCLKS 中)
//
if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution)
{
acqps = 14;//75ns
}
否则、//分辨率为16位
{
acqps = 63;//320ns
}
if (adc_resolution_12bit = AdcbRegs.ADCCTL2.bit.resolution)
{
acqps = 14;//75ns
}
否则、//分辨率为16位
{
acqps = 63;//320ns
}
if (adc_resolution_12bit = AdcRegs.ADCCTL2.bit.resolution)
{
acqps = 14;//75ns
}
否则、//分辨率为16位
{
acqps = 63;//320ns
}
if (adc_resolution_12bit = AdcdRegs.ADCCTL2.bit.resolution)
{
acqps = 14;//75ns
}
否则、//分辨率为16位
{
acqps = 63;//320ns
}
//
//选择要转换的通道和转换结束标志
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC1将转换引脚 B2 (Lac lato sx 2.632V= 35A)
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为 acqps +
AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC1将转换引脚 B2 (Lac lato sx 2.632V= 35A)
AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为 acqps +
AdccRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC1将转换引脚 B2 (Lac lato sx 2.632V= 35A)
AdccRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为 acqps +
AdcdRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC1将转换引脚 B2 (Lac lato sx 2.632V= 35A)
AdcdRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为 acqps +
//1个 SYSCLK 周期
EDIS;
}
空 InitEPwm1()
{
//用于 ISR
EPwm1Regs.TBPRD = 500; //设置 f=10KHz 的定时器周期
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; //相位为0
EPwm1Regs.TBCTR = 0x0000; //清除计数器
//
//设置 TBCLK
//
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上计数
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; //禁用相位加载
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1; //时钟与 SYSCLKOUT 的比率
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//每0加载一次寄存器
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
//设置比较
//
EPwm1Regs.CMPA.bit.CMPA = 250;
//
//设置操作
//
//在28379D 上运行时取消注释"ZRO"
// EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; //将 PWM1A 设置为零
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; //将 PWM1A 设置为零
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; //将 PWM1A 设置为零
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;
//高电平有效互补 PWM -设置死区
//
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm1Regs.DBRED.bit.DBRED = EPWM1_DB;
EPwm1Regs.DBFED.bit.DBFED = EPWM1_DB;
//
//中断,我们将在其中更改死区
//
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;//选择零事件时的 INT
EPwm1Regs.ETSEL.bit.INTEN = 1; //启用 INT
EPwm1Regs.ETPS.bit.INTPRD = et_1st; //生成第3个事件的 INT
}
void InitEPwm2()
{
//用于 PWM 操作
EPwm2Regs.TBPRD = 1667; 100kHz 时 ISR 的//频率
EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; //相位为0
EPwm2Regs.TBCTR = 0x0000; //清除计数器
//
//设置 TBCLK
//
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上计数
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; //禁用相位加载
EPwm2Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1; //时钟与 SYSCLKOUT 的比率
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
//
//设置比较
EPwm2Regs.CMPA.bit.CMPA = Duty_cycle* 1667;
//
//设置操作
//
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; //将 PWM1A 设置为零
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; //将 PWM1A 设置为零
// EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.CAU = AQ_CLEAR; //将 PWM1A 设置为零
EPwm2Regs.AQCTLB.bit.CAD = AQ_SET;
//高电平有效互补 PWM -设置死区
//
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm2Regs.DBRED.bit.DBRED = EPWM1_DB;
EPwm2Regs.DBFED.bit.DBFED = EPWM1_DB;
//
//中断,我们将在其中更改死区
//
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;//选择零事件时的 INT
EPwm2Regs.ETSEL.bit.INTEN = 1; //启用 INT
EPwm2Regs.ETPS.bit.INTPRD = et_1st; //在第三个事件上生成 INT
}
__interrupt void epwm2_ISR (void)
{
EPwm2TimerIntCount++;
//
//清除此计时器的 INT 标志
//
EPwm2Regs.ETCLR.bit.INT = 1;
//
//确认此中断以接收来自组3的更多中断
//
PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;
}
您好 Richard、
程序不会直接给出错误。 因为第一次程序运行"enable = 0"时,所以程序不会在 DCL_PI 函数内移动(代码中的第229行)。 现在、当我手动将 ENABLE = 1置于监视表达式中时、程序成功构建后、它将进入循环内部、并跳转到非法 ISR、并在代码中的第235行停止。 请仔细 查看图片。 之前、当我将光标放在 UK_V 上时、在值参数中、它说"无法从非基元位置加载"。 但现在它显示在值"0.00"中。
关于链接器命令文件、我签入了属性、但找不到任何其他链接器命令文件。
谢谢你。
此致、
Vidhi
您好、Vidhi、
对于符号重新定义错误、这些标签将定义要加载到 RAM 中的函数的地址。 它们必须位于工程中的多个位置、否则编译器不会生成警告。 您能否通过链接器、源文件和头文件进行搜索以检查它们在何处出现? 通常,它们将在链接器文件中定义,在头文件中定义 extern,并在 memcopy()函数中引用。 查看 C2000Ware 头文件中的闪存示例、了解如何完成此操作。
您是否查看了我上一篇帖子中的最后一项? 当我单步执行您的代码时、我注意到控制器不工作、除非您拥有正确数量的初始化程序。 请再次查看。 您应该在 pi_values_i 和 pi_values_V 中有十个初始化程序
此致、
Richard
尊敬的 Richard:
很抱歉、我为 pi_values_V 和 pi_values_i 定义了10个参数、但仍然是同一个问题。 如果我使用链接器命令文件、它仍然会给我重复分配存储器的错误。 但是、我会浏览源文件、头文件和链接器文件、我找不到多个链接器文件。 请问您使用的是哪个链接器命令文件? 我尝试使用"2837xS_Generic_RAM_lnk.cmd"和"28377S_RAM_lnk.cmd"、但也尝试了错误。
我认为它的问题与内存有关、而不是与代码有关。
我在尝试调试"停止位置及其原因"时注意到另一件事、我发现它在第28行的文件"DCL_PI_C1.asm"中停止、因为它找不到 R4H (如所附图像中所示)、R5H、R6H 的值、并跳转到非法 ISR。 请指导我如何找到这些值、以及我是否必须在定义" pi_values_v"和"pi_values_i "时提供一些地址而不是"NULL_ADDR"。
#define pi_values_V{1.0f、0.0f、0.0f、1.0f、-1.0f、 1.0f、1.0f、-1.0f、NULL_ADDR、NULL_ADDR} //#define PI_VALUES _V{0.06f、0.1f、0.1f、1.0f、-1.0f、 0.1f}// Kp、Ki、I10、Sat_max、Sat_min、 sat_storage float rk_V;//参考值 float YK_V;//测量的 ADC 信号 float UK_V;// PI 输出 //float lk_V; DCL_PI p1 = pi_values_V; float V_ref=100; int enable = 0; //电流控制 器#define pi_values_i 的 PI 控制器变量{1.0f、0.0f、0.0f、0.0f、0.0f、0.0f、0.0f、0.0f、0.0f 1.0f、1.0f、-1.0f、NULL_ADDR、NULL_ADDR}
谢谢您、
此致、
Vidhi