我的CLA task 是epwm触发,读取AdcResult.ADCRESULT6数值后,进行运算,得到的结果赋值给EPwm1Regs.CMPA.half.CMPA。
编译没有错误,可以烧写,可以运行,在expressions窗口可以观察到task中其他变量都如期变化,只有CMPA的数值始终是初始化时的给定值。
可能是哪里的配置出了问题呢?
一、CLA配置
/*
* Cpu_Cla.c
*
* Created on: 2020年11月24日
* Author: 29458
*/
#include "DSP28x_Project.h"
#include "Cpu_Cla.h"//所有 CLA中断都定义在Cpu_Cla.h当中
#include "DSP2803x_Examples.h"
#include "string.h"
//Linker defined vars
extern Uint16 Cla1Prog_Start;
extern Uint16 Cla1funcsLoadStart;
extern Uint16 Cla1funcsLoadEnd;
extern Uint16 Cla1funcsRunStart;
extern Uint16 Cla1funcsLoadSize;
extern Uint16 Cla1mathTablesLoadStart;
extern Uint16 Cla1mathTablesRunStart;
extern Uint16 Cla1mathTablesLoadSize;
void Cla_AppInit(void)
{
/* Assign user defined ISR to the PIE vector table */
EALLOW;
PieVectTable.CLA1_INT1 = &cla1_task1_isr;//取中断向量的地址.放入CPU中断向量表中。
PieVectTable.CLA1_INT2 = &cla1_task2_isr;
PieVectTable.CLA1_INT3 = &cla1_task3_isr;
PieVectTable.CLA1_INT4 = &cla1_task4_isr;
PieVectTable.CLA1_INT5 = &cla1_task5_isr;
PieVectTable.CLA1_INT6 = &cla1_task6_isr;
PieVectTable.CLA1_INT7 = &cla1_task7_isr;
PieVectTable.CLA1_INT8 = &cla1_task8_isr;
EDIS;
//Copy over the CLA code and Tables
memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);//将CLA代码拷贝入CLA的代码段,因为CLA的代码需要单独放在一个固定的位置,所以需要执行这一段代码
memcpy(&Cla1mathTablesRunStart, &Cla1mathTablesLoadStart, (Uint32)&Cla1mathTablesLoadSize);
/* Compute all CLA task vectors */
EALLOW;
Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 – (Uint32)&Cla1Prog_Start);//取task初始地址的偏移量
Cla1Regs.MVECT2 = (Uint16)((Uint32)&Cla1Task2 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT3 = (Uint16)((Uint32)&Cla1Task3 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT4 = (Uint16)((Uint32)&Cla1Task4 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT5 = (Uint16)((Uint32)&Cla1Task5 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT6 = (Uint16)((Uint32)&Cla1Task6 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT7 = (Uint16)((Uint32)&Cla1Task7 – (Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT8 = (Uint16)((Uint32)&Cla1Task8 – (Uint32)&Cla1Prog_Start);
EDIS;
// Step 3 : Mapping CLA tasks
/* All tasks are enabled and will be started by an ePWM trigger
* Map CLA program memory to the CLA and enable software breakpoints
*/
EALLOW;
Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_EPWM1INT;//PWM触发CLA的task
Cla1Regs.MPISRCSEL1.bit.PERINT2SEL = CLA_INT2_NONE; //软件触发进入
// Cla1Regs.MPISRCSEL1.bit.PERINT3SEL = CLA_INT3_EPWM3INT;
// Cla1Regs.MPISRCSEL1.bit.PERINT4SEL = CLA_INT4_EPWM4INT;
// Cla1Regs.MPISRCSEL1.bit.PERINT5SEL = CLA_INT5_EPWM5INT;
// Cla1Regs.MPISRCSEL1.bit.PERINT6SEL = CLA_INT6_EPWM6INT;
// Cla1Regs.MPISRCSEL1.bit.PERINT7SEL = CLA_INT7_EPWM7INT;
// Cla1Regs.MPISRCSEL1.bit.PERINT8SEL = CLA_INT8_NONE;
Cla1Regs.MIER.all = 0x00FF;//1111 1111 。配置完成,使能task
EDIS;
/* Enable CLA interrupts at the group and subgroup levels */
PieCtrlRegs.PIEIER11.all = 0x0;//中断向量表第11组全部使能
IER |= M_INT11 ; //IER与0100 0000 0000按位或
/* Switch the CLA program space to the CLA and enable software forcing
* Also switch over CLA data ram 0 and 1
*/
EALLOW;
Cla1Regs.MMEMCFG.bit.PROGE = 1;// CLA program RAM to CLA space将CLA的数据段和程序段都映射到CLA空间
Cla1Regs.MMEMCFG.bit.RAM1E = 1;// CLA data RAM to CLA space
Cla1Regs.MMEMCFG.bit.RAM0E = 1;
Cla1Regs.MCTL.bit.IACKE = 1;//软件触发
// Cla1Regs.MIER.all = 0x00FF;//中断配置好以后,使能所有task
EDIS;
}
//###########################################################################
// CLA ISRs
//###########################################################################
__interrupt void cla1_task1_isr(void)
{//This interrupt will be taken by the main CPU when CLA task 7 completes.
// Run_Time_End();
// GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;
PieCtrlRegs.PIEACK.bit.ACK11 = 1;//清ACK中断,通常用在ISR的最后;使得同组的其他中断能响应。
}
__interrupt void cla1_task2_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task3_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task4_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task5_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task6_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task7_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
__interrupt void cla1_task8_isr( void)
{
PieCtrlRegs.PIEACK.bit.ACK11 = 1;
}
二、CLA task
/*
* Cla_Task1.cla
*
* Created on: 2020年11月25日
* Author: 29458
*/
#include "DSP28x_Project.h"
#include "ClaShare.h"
#include "CLAmath.h"
#include "Cpu_Cla.h"
#include "DSP2803x_Device.h"
#include "DSP2803x_Cla_typedefs.h"
//———————-变量定义———————————————//
//float fCorrectDone;
//float fguzhangwei; //校零完成标志位和故障标志位
//float favg;
//float favg2;
//float fsum;
//float fsum2;
//float fk;//采样128个点
//float fADerr;
//float fADerr2; //电压采样差值和电流采样差值
//====================SOGI相关变量====================================================================//
float Uac;
float u_sogi_k ,u_sogi_k_1 ,u_sogi_k_2 ;//输入变量
float y_sogi_k ,y_sogi_k_1 ,y_sogi_k_2 ;//同相输出正弦波变量
float y_sogi_qk,y_sogi_qk_1,y_sogi_qk_2;//正交输出正弦波变量
#define k_sogi (float)(0.1)
#define wn (int)(314)
#define Ts (float)(75e-6)
#define IQ12Coe (float)(0.0002441406)//2^12
#define Coe (float)(0.0078125)//1/128
#define x (float)(0.007853981633974)
#define y (float)(0.0000616850275068085)
#define b0 (float)(0.001959617488787) //同相正弦波公式系数,
#define qb0 (float)(0.00000769539988327536) //正交正弦波中,当前拍输入量的系数
#define qb1 (float)(0.00001539079976655072) //正交正弦波中,上一拍输入量的系数
#define qb2 (float)(0.00000769539988327536) //正交正弦波中,上上一拍输入量的系数
#define a1 (float)(1.996019201823359) //上一拍输出量的系数
#define a2 (float)(-0.996080765022425) //上上一拍输出量的系数
float Yout;
float sum;
float sum2;
float aaaa;
//把要拷贝到RAM里的函数定义到段Cla1Prog
#pragma CODE_SECTION(Cla1Task2, "Cla1Prog");
__interrupt void Cla1Task2(void)
{
//Part1:数据赋初值
CorrectDone = 0;
guzhangwei = 0;
avg = 0;
avg2 = 0;
sum = 0;
sum2 = 0;
k = 0;//采样128个点
ADerr = 0;
ADerr2 = 0;
}
#pragma CODE_SECTION(Cla1Task1, "Cla1Prog");
__interrupt void Cla1Task1(void)
{
if(CorrectDone==0) //校零没有完成
{
// delay_2(2);
sum += sum_cla;//输出电压采样值
sum2 += sum2_cla;//输出电流采样值
if(k<128)
{
k++;
}
if(k==128)
{
avg = sum*Coe; //右移7位即除以128,取平均值
avg2 = sum2*Coe;
ADerr = avg -2048;//和理论值做差
ADerr2= avg2-2048;//得到0.2I
CorrectDone=1; //校零完成标志位置1
}
}
if(CorrectDone==1) //校零已经完成
{
// Uac=(AdcResult.ADCRESULT6-ADerr)*0.0016-3.279; //数据处理 3.279/4095*2=0.0016 369
Uac=(sum_cla-ADerr)*0.0016-3.279; //数据处理 3.279/4095*2=0.0016 369
// Uac=sum_cla*0.0016-3.279; //数据处理 3.279/4095*2=0.0016 369
// I_L=(AdcResult.ADCRESULT5-ADerr2)*0.0016-3.279; //得到实际电感电流的0.2倍值。0.2I_L
//—————————SOGI—————————————————–//
u_sogi_k = Uac;//输入电网电压
y_sogi_k = a1*y_sogi_k_1 + a2*y_sogi_k_2 + b0*(u_sogi_k – u_sogi_k_2);//求与电网电压同相的正弦波
y_sogi_k_2 = y_sogi_k_1;
y_sogi_k_1 = y_sogi_k;
y_sogi_qk = a1*y_sogi_qk_1 + a2*y_sogi_qk_2 + qb0*u_sogi_k + qb1*u_sogi_k_1 + qb2*u_sogi_k_2;//与电网电压正交的正弦波
y_sogi_qk_2 = y_sogi_qk_1;
y_sogi_qk_1 = y_sogi_qk;
u_sogi_k_2 = u_sogi_k_1;
u_sogi_k_1 = u_sogi_k;
Yout = y_sogi_k;
if(Yout>0.95)
Yout=0.95;
if(Yout<-0.95)
Yout=-0.95;
aaaa = Yout*750+750;
EPwm1Regs.CMPA.half.CMPA = 800;//!!!!!!!!即使直接写一个具体的值,也无法赋值!!!!!!
EPwm1Regs.CMPB = -Yout*750+750;
}
// EALLOW;
// EPwm1Regs.ETCLR.bit.INT = 1; //事件触发清除寄存器,清除中断标志位,因为已经响应过这个中断
//PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //写1,使该位清零。应答下次定时器中断
// PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //中断应答,必须有这个信号,才能中断 EPWM1
// EDIS;
}
__interrupt void Cla1Task3 ( void )
{
}
__interrupt void Cla1Task4 ( void )
{
}
__interrupt void Cla1Task5 ( void )
{
}
__interrupt void Cla1Task6 ( void )
{
}
__interrupt void Cla1Task7 ( void )
{
}
__interrupt void Cla1Task8 ( void )
{
}
//===========================================================================
// End of file.
//===========================================================================//
三、变量定义
/*
* ClaEntry.c
*
* Created on: 2020年11月26日
* Author: 29458
*/
#include "DSP28x_Project.h"
#include "ClaShare.h"
#pragma DATA_SECTION(CorrectDone,"Cla1ToCpuMsgRAM");//CLA中变量,CPU只能读,不能写
float CorrectDone;
#pragma DATA_SECTION(guzhangwei,"Cla1ToCpuMsgRAM");
float guzhangwei;
#pragma DATA_SECTION(avg,"Cla1ToCpuMsgRAM");
float avg;
#pragma DATA_SECTION(avg2,"Cla1ToCpuMsgRAM");
float avg2;
//#pragma DATA_SECTION(sum2,"Cla1ToCpuMsgRAM");
//float sum2;
#pragma DATA_SECTION(k,"Cla1ToCpuMsgRAM");
float k;
#pragma DATA_SECTION(ADerr,"Cla1ToCpuMsgRAM");
float ADerr;
#pragma DATA_SECTION(ADerr2,"Cla1ToCpuMsgRAM");
float ADerr2;
四、变零头文件
/*
* ClaShare.h
*
* Created on: 2020年11月26日
* Author: 29458
*/
#ifndef INCLUDE1_CLASHARE_H_
#define INCLUDE1_CLASHARE_H_
extern float CorrectDone;
extern float guzhangwei ;
extern float avg ;
extern float avg2 ;
extern float sum_cla ;
extern float sum2_cla ;
extern float k ;
extern float ADerr ;
extern float ADerr2 ;
#endif /* INCLUDE1_CLASHARE_H_ */
Green Deng:
你好,我看到你参考过这个帖子:e2echina.ti.com/…/188510
请问帖子中提到的解决方案是否有测试过?
,
user6119125:
才解决。是在*.cla文件首端添加#include "DSP2803x_Cla_typedefs.h"。要放在第一行才有效。具体原理不明。谢谢您的回复。
另,之前在CPU中的程序现在移到CLA task中执行,结果偏差很大。尤其是ADC采样环节(在初始化时,对ADC结果校零:采集128次求平均值,将该平均值和理论值做差。之前误差只有十几,现在居然有三四百。)不知道是什么原因导致的,是PWM模块配置问题吗?您能给些建议吗?还是另开一个帖子?
,
Green Deng:
你好,据我所知,F28035的CLA只能访问ADC模块的结果寄存器。也就是说,采样的值应该跟CLA没关系,CLA只能对采样的数据进行处理。这么看的话,出现问题可能跟采样部分有关,如果ADC是由PWM触发,那确实有可能跟PWM配置会有关。
你看一下,如果确实有这方面的问题,建议新开一个帖子进行咨询。