注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
Laspide的个人空间 https://home.eeworld.com.cn/space-uid-65032.html [收藏] [复制] [分享] [RSS]
日志

【TI C2000的使用经验】V1.31库文件使用的改进方法(ECAN为例)

已有 1722 次阅读2015-4-1 13:02 |个人分类:C2000

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;
}

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章