📄 can.c
字号:
#include "main.h"
//#pragma interrupt_handler can_ReceiveData:19
/*******************************************************************
CAN initialization:
Mailbox 0: Receive --> interrupt
Mailbox 1: Transmit --> polling
*******************************************************************/
#define TYP_RESET 5
#define TYP_BAUD 10
#define SELFID 2
extern unsigned char sysrst;
unsigned char canbaud;
const Uchar CanBaud[6][3]={{0x02,0x04,0x13},{0x06,0x04,0x13},{0x0E,0x04,0x13},{0x12,0x04,0x13},{0x1E,0x04,0x13},{0x26,0x04,0x13}};
unsigned long CANMOBID[15]={0x1300ff01,0x1300ff01,0x02000000|(SELFID<<8),0x02000000|(SELFID<<8),0x0100ff00,0x0100ff00,0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x0200ff00,0x12000001,0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x1300ff01};
unsigned long CANMOBMD[15]={0x1f00ffff,0x1f00ffff,0x0f00ff00, 0x0f00ff00, 0x0f00ff00,0x0f00ff00,0x0f00ff00, 0x0f00ff00, 0x0f00ff00,0x1f0000ff,0x0f00ff00,0x0f00ff00,0x0f00ff00,0x0f00ff00,0x1f00ffff};
unsigned char CANIDT[15][4]={0};
unsigned char CANIDM[15][4]={0};
Uchar counterTemp;
void can_init (void)
{
canMob_init();
//IDRcbufInit();
//RstIDused();
}
void canMob_init (void)
{
unsigned char i,j;
unsigned long temp;
unsigned int temp1,temp2;
//DDRD=(1<<PD5)|(0<<PD6); //TXCAN, RXCNA
DDRD|=0x20;
DDRD&=0xBF;
CANGCON |= (1<<SWRES); //reset CAN interface
//CANMOBID[2]=(unsigned long)(SELFID<<8)|CANMOBID[2];
for(i=0;i<15;i++)
{
temp=CANMOBID[i]<<3;
temp1=(unsigned int)temp;
temp2=(unsigned int)(temp/0x00010000);
CANIDT[i][3]=(Uchar)temp1;
CANIDT[i][2]=(Uchar)(temp1>>8);
CANIDT[i][1]=(Uchar)temp2;
CANIDT[i][0]=(Uchar)(temp2>>8);
NOP();
}
for(i=0;i<15;i++)
{
temp=CANMOBMD[i]<<3;
temp1=(unsigned int)temp;
temp2=(unsigned int)(temp/0x00010000);
CANIDM[i][3]=(Uchar)temp1;
CANIDM[i][2]=(Uchar)(temp1>>8);
CANIDM[i][1]=(Uchar)temp2;
CANIDM[i][0]=(Uchar)(temp2>>8);
NOP();
}
//reset all MObs
for (i=0; i<15; i++)
{
CANPAGE = (i<<4); //select MOb
CANCDMOB = 0; //disable MOb
CANSTMOB = 0; //clear status
CANIDT1 = 0; //clear ID
CANIDT2 = 0;
CANIDT3 = 0;
CANIDT4 = 0;
CANIDM1 = 0; //clear mask
CANIDM2 = 0;
CANIDM3 = 0;
CANIDM4 = 0;
for (j=0; j<8; j++)
CANMSG = 0; //clear data
}
//bit timing -> datasheet page 260 (check table) 250Kbps
//CANBT1 = 0x02; //16Mhz,1Mbps
//CANBT2 = 0x04;
//CANBT3 = 0x13;
//canbaud= EEPROM_read(0x0020);
CANBT1 = CanBaud[2][0];
CANBT2 = CanBaud[2][1];
CANBT3 = CanBaud[2][2];
//configure MObi
/******************************************************************/
for (i=0; i<15; i++)
{
CANPAGE = (i<<4); //MOb number 0
CANIDT1 = CANIDT[i][0]; //clear ID
CANIDT2 = CANIDT[i][1];
CANIDT3 = CANIDT[i][2];
CANIDT4 = CANIDT[i][3];
CANIDM1 = CANIDM[i][0]; //clear mask
CANIDM2 = CANIDM[i][1];
CANIDM3 = CANIDM[i][2];
CANIDM4 = CANIDM[i][3]; //0 = ignore bit
//CANIDM4 = (1<<IDEMSK); //identifier extention mask
CANCDMOB = (2<<CONMOB) | (1<<IDE); //reception, ext. ID,rev2.0B
NOP();
}
//CANHPMOB = (2<<HPMOB);
CANGCON = (1<<ENASTB); //start CAN interface, enable mode
/***********************************************************************/
//interrupts
//CANGIE = (1<<ENIT) | (1<<ENRX); //enable receive interrupt
CANGIE = (1<<ENIT) | (1<<ENTX)| (1<<ENRX); //enable receive interrupt and transmitte interrupt
///////////////////////////////////////////////////////////////////////
CANIE1 = 0xff;
CANIE2 = 0x7f; //enable ALL MObs interrupt
CANSIT1 = 0; //clear MOb status interrupt
CANSIT2 = 0;
/////////////////////////// Enable Mob0 transmit/////////////////////
CLI();
CANPAGE = (1<<4);
CANCDMOB |= (1<<CONMOB0);
/////////////////////////////////////////////////////////////////////
while (!(CANGSTA & (1<<ENFG))); //wait until module ready
CANGCON |= (1<<ENA); //enable CAN controller
}
/*******************************************************************
CAN transmission via mailbox 1 (polling)
*******************************************************************/
void can_tx (VCI_CAN_OBJ msg)
{
unsigned char i;
//enable MOb1, auto increment index, start with index = 0
CANPAGE = (1<<4);
CANCDMOB = (1<<IDE) | (8<<DLC0); //set IDE bit rev2.0B, data length = 8
msg.ID <<= 3; //write 29 Bit identifier
CANIDT4 = (unsigned char) (msg.ID&0xF8);
CANIDT3 = (unsigned char) (msg.ID>>8);
CANIDT2 = (unsigned char) (msg.ID>>16);
CANIDT1 = (unsigned char) (msg.ID>>24);
for(i=0;i<8;i++)
{
CANMSG = msg.Data[i];
}
// for (i=0; i<8; i++) //put data in mailbox 6
CANCDMOB |= (1<<CONMOB0); //enable transmission
//while (!(CANSTMOB & (1<<TXOK))); //wait until complete
//CANSTMOB &= ~(1<<TXOK); //reset flag
}
#define can_TX_BUFFER_SIZE 8
VCI_CAN_OBJ tx_msg_buff[can_TX_BUFFER_SIZE];
Uchar can_sendingP;
Uchar can_willsendP;
Uchar can_tx_count;
Uint CAN_tx_OverFlow= 60000;
void can_tx_buff(VCI_CAN_OBJ tx_msg)
{
CAN_tx_OverFlow = 60000;
while (can_tx_count == can_TX_BUFFER_SIZE)
{
CAN_tx_OverFlow--;
if(CAN_tx_OverFlow<=50)
{
can_tx_count = 0;
can_sendingP = can_willsendP;
CANSTMOB &= ~(1<<TXOK);
CAN_tx_OverFlow = 60000;
}
}
if(can_tx_count || (CANGSTA & (1<<TXBSY)))
{
tx_msg_buff[can_willsendP] = tx_msg;
if(++can_willsendP == can_TX_BUFFER_SIZE)
can_willsendP = 0;
++can_tx_count;
}
else
{
if(can_willsendP != can_sendingP)
{
NOP();
can_willsendP=0;
can_sendingP=0;
}
can_tx(tx_msg);
}
}
/*******************************************************************
CAN receive interrupt service routine (mailbox i)
*******************************************************************/
#pragma interrupt_handler can_ReceiveData:19
void can_ReceiveData (void) //receive interrupt
{Uchar RCFlag;
unsigned char nb_data;
unsigned char temp = CANPAGE; //save CANPAGE
unsigned char i,tt=0,CAN_REMOb[15],nn;
unsigned int RC_CANSI,RCtemp1,RCtemp2,tempp,RCF;
VCI_CAN_OBJ msg[15];
//VCI_CAN_OBJ CanTkfrm;
if(CANSTMOB & (1<<TXOK))
{
CANSTMOB &= ~(1<<TXOK);
if(can_tx_count)
{
--can_tx_count;
can_tx(tx_msg_buff[can_sendingP]);
if(++can_sendingP==can_TX_BUFFER_SIZE) can_sendingP=0;
}
}
else
{
RCtemp2=CANSIT2;
RCtemp1=CANSIT1;
CANSTMOB &= ~(1<<RXOK);
RC_CANSI=(RCtemp1<<8)|RCtemp2;
for(i=0;i<15;i++)
{
tempp=(1<<i);
RCF=(RC_CANSI&tempp);
if(RCF!=0)
{
if(i==10)
NOP();
CAN_REMOb[tt]=i;
tt++;
}
}
/* for(i=0;i<tt;i++)
{
CANPAGE = (CAN_REMOb[i]<<4);
CANSTMOB &= ~(1<<RXOK);
for (nb_data = 0; nb_data <(CANCDMOB&DLC_MSK); nb_data++)
{
msg[i].Data[nb_data]=CANMSG;
}
msg[i].ID = 0;
msg[i].ID |= ((unsigned long) CANIDT1<<24); //get identifier
msg[i].ID |= ((unsigned long) CANIDT2<<16);
msg[i].ID |= ((unsigned long) CANIDT3<<8);
msg[i].ID |= (CANIDT4&0xF8);
msg[i].ID >>= 3;
CANCDMOB = (2<<CONMOB) | (1<<IDE);
}*/
for(i=0;i<tt;i++)
{
CANPAGE = (CAN_REMOb[i]<<4);
CANSTMOB &= ~(1<<RXOK);
for (nb_data = 0; nb_data <(CANCDMOB&DLC_MSK); nb_data++)
{
msg[i].Data[nb_data]=CANMSG;
}
msg[i].ID = 0;
msg[i].ID |= ((unsigned long) CANIDT1<<24); //get identifier
msg[i].ID |= ((unsigned long) CANIDT2<<16);
msg[i].ID |= ((unsigned long) CANIDT3<<8);
msg[i].ID |= (CANIDT4&0xF8);
msg[i].ID >>= 3;
CANCDMOB = (2<<CONMOB) | (1<<IDE);
}
for(nn=0;nn<tt;nn++)
{
/*****************************************************
* 用户程序
* 举例: msg[nn].ID 是ID 号
msg[nn].date[0]~msg[nn].date[8] 是数据
********************************************************/
}
}
CANPAGE = temp; //restore CANPAGE
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -