TI C2000官方的V1.31程序库也有年头了,也没太关注,不知道更新了没有。
C2000 V1.31程序库的寄存器定义和别的MCU不太一样,寄存器地址定义不是太直观,使用不是很方便。
以ECAN模块为例,它的寄存器组是这样定义的:
struct MOTO_REGS {
UNUM32 MOTO0;
UNUM32 MOTO1;
UNUM32 MOTO2;
UNUM32 MOTO3;
UNUM32 MOTO4;
UNUM32 MOTO5;
UNUM32 MOTO6;
UNUM32 MOTO7;
UNUM32 MOTO8;
UNUM32 MOTO9;
UNUM32 MOTO10;
UNUM32 MOTO11;
UNUM32 MOTO12;
UNUM32 MOTO13;
UNUM32 MOTO14;
UNUM32 MOTO15;
UNUM32 MOTO16;
UNUM32 MOTO17;
UNUM32 MOTO18;
UNUM32 MOTO19;
UNUM32 MOTO20;
UNUM32 MOTO21;
UNUM32 MOTO22;
UNUM32 MOTO23;
UNUM32 MOTO24;
UNUM32 MOTO25;
UNUM32 MOTO26;
UNUM32 MOTO27;
UNUM32 MOTO28;
UNUM32 MOTO29;
UNUM32 MOTO30;
UNUM32 MOTO31;
};
如果32个寄存器都要用的话,相似的语句你得拷贝32遍。
而且如果同时用到ECAN的两个模块A和B的话,按V1.31库,你还得同样功能的函数写两遍(有的书上还就是怎么写的)。
或许有取巧的方法,在模块A寄存器的地址值上加个偏移,就成了模块B寄存器的地址值。
我的做法是尽量保证库的完整(不在库上做大修改,小动作还是要的)。
方法如下:
1、模块的改进用法:
V1.31库ecan.h中声明了寄存器
extern volatile struct ECAN_REGS ECanaRegs;
extern volatile struct ECAN_MBOXES ECanaMboxes;
extern volatile struct LAM_REGS ECanaLAMRegs;
extern volatile struct MOTO_REGS ECanaMOTORegs;
extern volatile struct MOTS_REGS ECanaMOTSRegs;
extern volatile struct ECAN_REGS ECanbRegs;
extern volatile struct ECAN_MBOXES ECanbMboxes;
extern volatile struct LAM_REGS ECanbLAMRegs;
extern volatile struct MOTO_REGS ECanbMOTORegs;
extern volatile struct MOTS_REGS ECanbMOTSRegs;
注意: ECanaRegs这类名字在其他文件用于地址定义了,不能改或改也只是换个名字(我觉得是这样)。
在用户的.c文件中,在定义指针数组以对应两个模块的寄存器
volatile struct ECAN_REGS *ECan_mp_Regs[2];
volatile struct ECAN_MBOXES *ECan_mp_MBoxes[2];
volatile struct LAM_REGS *ECan_mp_LAM_Regs[2];
模块初始化函数
void ECAN_InitModule(UNUM16 eCanModuleSN)
中把指针数组和模块寄存器的地址对应上
ECan_mp_Regs[eCanModuleSN] = &ECanaRegs;
ECan_mp_MBoxes[eCanModuleSN] = &ECanaMboxes;
ECan_mp_LAM_Regs[eCanModuleSN] = &ECanaLAMRegs;
然后在进行初始化的其他工作
ECan_Regs_Shadow[eCanModuleSN].CANTIOC.all = ECan_Regs[eCanModuleSN]->CANTIOC.all;
ECan_Regs_Shadow[eCanModuleSN].CANTIOC.bit.TXFUNC = BIT_SET;
ECan_Regs[eCanModuleSN]->CANTIOC.all = ECan_Regs_Shadow[eCanModuleSN].CANTIOC.all;
ECan_Regs_Shadow[eCanModuleSN].CANRIOC.all = ECan_Regs[eCanModuleSN]->CANRIOC.all;
ECan_Regs_Shadow[eCanModuleSN].CANRIOC.bit.RXFUNC = BIT_SET;
ECan_mp_Regs[eCanModuleSN]->CANRIOC.all = ECan_ms_Regs_Shadow[eCanModuleSN].CANRIOC.all;
其他类似,这样将两个模块的操作,用模块的序号作形参,一套函数就可以了。
当然如果两个模块配置有差别,比如波特率不同,那还要在改进些。
对于V1.31库里ECAN模块的寄存器定义,也可以调整下以方便使用。如邮箱寄存器组:
struct ECAN_MBOXES {
struct MBoxT MBOX[32];
};
用法:
for ( i = 0; i < ECAN_MBOX_NUM; i++ )
{
ECan_MBoxes[eCanModuleSN]->MBOX
.MSGCTRL.all = 0x00000000;
ECan_MBoxes[eCanModuleSN]->MBOX.MSGID.all = 0x00000000;
}
又如
struct LAM_REGS {
union CANLAM_REG LAM[32];
};
for ( eCanMBoxesSN = 16; eCanMBoxesSN < ECAN_MBOX_NUM; eCanMBoxesSN++ )
{
ECan_MBoxes[eCanModuleSN]->MBOX[eCanMBoxesSN].MSGID.all = ECAN_MBOX_DEF_ID - ( eCanMBoxesSN-16);
ECan_MBoxes[eCanModuleSN]->MBOX[eCanMBoxesSN].MSGCTRL.bit.DLC = 8;
ECan_LAM_Regs[eCanModuleSN]->LAM[eCanMBoxesSN].all = 0;
ECan_LAM_Regs[eCanModuleSN]->LAM[eCanMBoxesSN].bit.LAMI = BIT_SET;
}本文来自论坛,点击查看完整帖子内容。