can总线多机通讯发送报文资料.docx
《can总线多机通讯发送报文资料.docx》由会员分享,可在线阅读,更多相关《can总线多机通讯发送报文资料.docx(13页珍藏版)》请在冰豆网上搜索。
can总线多机通讯发送报文资料
#include"SJA1000REG_1.h"
#include
#include
#include
#include
#defineSTD_FRAMEID_LENTH2//标准帧ID长度
#defineEXT_FRAMEID_LENTH4//扩展帧ID长度
#defineLOW_BYTE(x)(unsignedchar)(x)
#defineHIGH_BYTE(x)(unsignedchar)((unsignedint)(x)>>8)
#defineOSCCLK11059200UL
#defineCPUCLK(OSCCLK/12)
#defineSJA_BASE_ADDR0X7E00
#defineT0_MASK0x0f
sbitLED=P2^5;
sbitSJA1000_RST=P2^6;
unsignedcharxdata*SJA_CS_Point=(unsignedcharxdata*)SJA_BASE_ADDR;
voidSJA1000_Init(unsignedcharbtr0,unsignedcharbtr1,unsignedchar*filter);
voidWriteSJAReg(unsignedcharRegAdr,unsignedcharValue);//写寄存器
unsignedcharReadSJAReg(unsignedcharRegAdr);//读寄存器
charSetBitMask(unsignedcharRegAdr,unsignedcharBitValue);//设置寄存器特定位
charClearBitMask(unsignedcharRegAdr,unsignedcharBitValue);//清除寄存器特定位
charWriteSJARegBlock(unsignedcharRegAdr,unsignedchar*ValueBuf,unsignedcharlen);//连续写寄存器
charReadSJARegBlock(unsignedcharRegAdr,unsignedchar*ValueBuf,unsignedcharlen);//连续读寄存器
charSetSJASendCmd(unsignedcharcmd);//发送模式cmd0为正常发送1为单次发送2为自发自收
charSJASendData(unsignedchar*databuf,unsignedcharcmd);//sja1000发送函数,将数据写入sja1000发送缓冲区,再将其发到总线上
charSJARcvData(unsignedchar*databuf);//SJA1000接收函数读取接收缓冲区的CAN报文
//voidSJA1000_Config_Filter(charmode,char*Filter);//配置滤波器模式和滤波参数mode大于0为双滤波器,其他为单滤波
unsignedcharSJA_CAN_Filter[8]={0xea,0x40,0x00,0x00,0x00,0x0f,0xff,0xff};
unsignedcharUserData[8];
typedefstruct//结构定义
{
unsignedlongID;
unsignedcharFF;
unsignedcharRTR;
unsignedcharDLC;
unsignedcharCanData[8];
}
CanFrame_t;
CanFrame_tUserSendData;
voidUserDataDeal()
{
UserData[0]=0x55;
}
voidNumDataDeal()
{
UserSendData.ID=0x251;
UserSendData.FF=0;
UserSendData.RTR=0;
UserSendData.DLC=8;
UserSendData.CanData[0]=UserData[0];
UserSendData.CanData[1]=UserData[1];
UserSendData.CanData[2]=UserData[2];
UserSendData.CanData[3]=UserData[3];
UserSendData.CanData[4]=UserData[4];
UserSendData.CanData[5]=UserData[5];
UserSendData.CanData[6]=UserData[6];
UserSendData.CanData[7]=UserData[7];
}
voidtimerInit(void)//串口初始化
{
TMOD&=~T0_MASK;//清除旧的设置(#defineT0_MASK0x0f)
TMOD|=0x01;
}
voidtimerDelay(unsignedintn)//延时0.01×n
{
do{
TL0=LOW_BYTE(65536UL-CPUCLK/100);
TH0=HIGH_BYTE(65536UL-CPUCLK/100);
TR0=1;
while(!
TF0);
TR0=0;
TF0=0;
}
while(--n!
=0);
}
voidSJA1000_Init(unsignedcharbtr0,unsignedcharbtr1,unsignedchar*filter)
{
SetBitMask(REG_CAN_MOD,RM_RR_BIT);//进入复位模式
WriteSJAReg(REG_CAN_CDR,0x48);//配置时钟分频,选择peliCAN模式
WriteSJAReg(REG_CAN_MOD,0x09);//配置模式寄存器,选择单滤波、正常模式
WriteSJARegBlock(REG_CAN_ACR0,filter,8);//配置验收代码/屏蔽寄存器
WriteSJAReg(REG_CAN_BTR0,btr0);//配置总线定时器0
WriteSJAReg(REG_CAN_BTR1,btr1);//配置总线定时器1
WriteSJAReg(REG_CAN_OCR,0x1A);//配置输出引脚TX0与RX0,推挽输出
ClearBitMask(REG_CAN_MOD,RM_RR_BIT);//推出复位模式
}
voidWriteSJAReg(unsignedcharRegAdr,unsignedcharValue)//写SJA1000寄存器
{
*(SJA_CS_Point+RegAdr)=Value;
return;
}
unsignedcharReadSJAReg(unsignedcharRegAdr)//读SJA1000寄存器
{
return(*(SJA_CS_Point+RegAdr));
}
charSetBitMask(unsignedcharRegAdr,unsignedcharBitValue)//设置指定寄存器指定位为1
{
charstatus=0;
unsignedchartemp;
temp=ReadSJAReg(RegAdr);
temp=temp|BitValue;
WriteSJAReg(RegAdr,temp);
if(ReadSJAReg(RegAdr)==temp)
{
status=1;
}
else
{
status=0;
}
return(status);
}
charClearBitMask(unsignedcharRegAdr,unsignedcharBitValue)//将指定寄存器的指定位清零
{
charstatus=0;
unsignedchartemp;
temp=ReadSJAReg(RegAdr);
temp=temp&(~BitValue);
WriteSJAReg(RegAdr,temp);
if(ReadSJAReg(RegAdr)==temp)
{
status=1;
}
else
{
status=0;
}
return(status);
}
charWriteSJARegBlock(unsignedcharRegAdr,unsignedchar*ValueBuf,unsignedcharlen)//连续写多个寄存器RegAdr寄存器起始地址len要连续写入的寄存器数
{
unsignedchari;
if(len!
=0)
{
for(i=0;i{
WriteSJAReg(RegAdr+i,ValueBuf[i]);
}
}
returnlen;
}
charReadSJARegBlock(unsignedcharRegAdr,unsignedchar*ValueBuf,unsignedcharlen)//连续读多个寄存器RegAdr寄存器起始地址len要读取的寄存器数
{
unsignedchari;
if(len!
=0)
{
for(i=0;i{
ValueBuf[i]=ReadSJAReg(RegAdr+i);
}
}
returnlen;
}
charSetSJASendCmd(unsignedcharcmd)//发送模式cmd0为正常发送1为单次发送2为自发自收
{
unsignedcharret;
switch(cmd)
{
default:
case0:
ret=SetBitMask(REG_CAN_CMR,TR_BIT);
break;
case1:
ret=SetBitMask(REG_CAN_CMR,TR_BIT|AT_BIT);
break;
case2:
ret=SetBitMask(REG_CAN_CMR,TR_BIT|SRR_BIT);
break;
case0xff:
ret=SetBitMask(REG_CAN_CMR,AT_BIT);
break;
}
returnret;
}
charSJASendData(unsignedchar*databuf,unsignedcharcmd)//sja1000发送函数,将数据写入sja1000发送缓冲区,再将其发到总线上
{
charstatus=1;
unsignedcharlen;
unsignedchardlc;
if((ReadSJAReg(REG_CAN_SR)&(TBS_BIT|TCS_BIT))!
=(TBS_BIT|TCS_BIT))
{
status=0;
}
else
{
dlc=(*databuf&0x0f);
if(dlc>8)
{
dlc=8;
}
switch(*databuf&0xc0)
{
case0x00:
len=STD_FRAMEID_LENTH+dlc+1;
break;
case0x40:
len=STD_FRAMEID_LENTH+1;
break;
case0x80:
len=EXT_FRAMEID_LENTH+dlc+1;
break;
case0xc0:
len=EXT_FRAMEID_LENTH+1;
break;
default:
len=0;
status=0;
break;
}
if(len>0)
{
WriteSJARegBlock(REG_CAN_TXFMINFO,databuf,len);
SetSJASendCmd(cmd);
status=1;
}
}
return(status);
}
charSJARcvData(unsignedchar*databuf)//SJA1000接收函数读取接收缓冲区的CAN报文
{
charstatus=1;
unsignedcharlen;
unsignedchardlc;
if((ReadSJAReg(REG_CAN_SR)&RBS_BIT)==0)
{
status=0;
}
else
{
*databuf=ReadSJAReg(REG_CAN_RXFMINFO);
dlc=(*databuf&0x0f);
if(dlc>8)
{
dlc=8;
}
switch(*databuf&0xC0)
{
case0x00:
len=STD_FRAMEID_LENTH+dlc;
break;
case0x40:
len=STD_FRAMEID_LENTH;
break;
case0x80:
len=EXT_FRAMEID_LENTH+dlc;
break;
case0xC0:
len=EXT_FRAMEID_LENTH;
break;
default:
len=0;
status=0;
break;
}
if(len>0)
{
ReadSJARegBlock(REG_CAN_RXBUF1,databuf+1,len);
status=SetBitMask(REG_CAN_CMR,RRB_BIT);
}
}
return(status);
}
/*voidSJA1000_Config_Filter(charmode,char*Filter)//配置滤波器模式和滤波参数mode大于0为双滤波器,其他为单滤波
{
SetBitMask(REG_CAN_MOD,RM_RR_BIT);
if(mode>0)
{
SetBitMask(REG_CAN_MOD,AFM_BIT);
}
else
{
ClearBitMask(REG_CAN_MOD,AFM_BIT);
}
WriteSJARegBlock(REG_CAN_ACR0,Filter,8);
ClearBitMask(REG_CAN_MOD,RM_RR_BIT);
}*/
intHal_CanMsgSend(CanFrame_t*pCanFrame)//CAN控制器报文发送接口
{
unsignedcharsnd_buf[13];
unsignedlongid;
snd_buf[0]=(pCanFrame->DLC&0xf);
if(pCanFrame->FF)
{
snd_buf[0]=(1<<7);
}
if(pCanFrame->RTR)
{
snd_buf[0]|=(1<<6);
}
if(pCanFrame->FF)
{
id=(pCanFrame->ID<<3);
snd_buf[1]=(id>>24)&0xff;
snd_buf[2]=(id>>16)&0xff;
snd_buf[3]=(id>>8)&0xff;
snd_buf[4]=(id>>0)&0xff;
memcpy(&snd_buf[5],pCanFrame->CanData,pCanFrame->DLC);
}
else
{
id=(pCanFrame->ID<<5);
snd_buf[1]=(id>>8)&0xff;
snd_buf[2]=id&0xff;
memcpy(&snd_buf[3],pCanFrame->CanData,pCanFrame->DLC);
}
returnSJASendData(snd_buf,0);
}
intHal_CanMsgRecive(CanFrame_t*pCanFrame)//CAN控制器报文接收接口
{
unsignedcharrcv_buf[13];
if(SJARcvData(rcv_buf))
{
pCanFrame->DLC=(rcv_buf[0]&0xf);
if(rcv_buf[0]&(1<<7))
{
pCanFrame->FF=1;
}
else
{
pCanFrame->FF=0;
}
if(rcv_buf[0]&(1<<6))
{
pCanFrame->RTR=1;
}
else
{
pCanFrame->RTR=0;
}
if(rcv_buf[0]&(1<<7))
{
pCanFrame->ID=rcv_buf[1];
pCanFrame->ID<<=8;
pCanFrame->ID+=rcv_buf[2];
pCanFrame->ID<<=8;
pCanFrame->ID+=rcv_buf[3];
pCanFrame->ID<<=8;
pCanFrame->ID+=rcv_buf[4];
pCanFrame->ID>>=3;
memcpy(pCanFrame->CanData,&rcv_buf[5],8);
}
else
{
pCanFrame->ID=rcv_buf[1]<<8;
pCanFrame->ID|=rcv_buf[2]<<0;
pCanFrame->ID>>=5;
memcpy(pCanFrame->CanData,&rcv_buf[3],8);
}
return1;
}
else
{
return0;
}
}
intHal_CanInit(void)
{
SJA1000_RST=1;
timerDelay(50);
SJA1000_RST=0;
SJA1000_Init(0x00,0x14,SJA_CAN_Filter);
return1;
}
voidmain()
{
timerInit();
Hal_CanInit();
while
(1)
{
//unsignedcharstatus,JiShu;
//JiShu=0;
UserDataDeal();
NumDataDeal();
if(Hal_CanMsgSend(&UserSendData))
{
LED=!
LED;
timerDelay(100);
}
}
}