📄 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,Pass_Flag;
unsigned char canbaud;
extern VCI_CAN_OBJ rece_data[3];
const Uchar CanBaud[6][3]={{0x02,0x04,0x13},{0x06,0x04,0x13},{0x0E,0x04,0x13},{0x12,0x04,0x13},{0x1E,0x04,0x13},{0x26,0x04,0x13}};
//波特率数组
//15个MOB的ID和MID
unsigned long CANMOBID[15]={0x10000000,0x20000000,0x30000000,0x40000000,0x50000000,0x60000000,0x01000000,0x01000001,0x0200ff00,0x12000001,0x01000002,0x01000003,0x01000004,0x01000005,0x1300ff01};
unsigned long CANMOBMD[15]={0x0000ffff,0x0000ffff,0x0000ffff,0x00ff00ff,0x00ff00ff,0x00ff00ff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff};
unsigned char CANIDT[15][4]={0};
unsigned char CANIDM[15][4]={0};
Uchar counterTemp,send_count;
void can_init (void) //CAN初始化函数
{
canMob_init();
}
void canMob_init (void) //MOB初始化函数
{
unsigned char i,j;
unsigned long temp;
unsigned int temp1,temp2;
CLI(); //关中断
//DDRD=(1<<PD5)|(0<<PD6); //TXCAN, RXCNA
DDRD|=0x20; //CAN管脚初始化
DDRD&=0xBF;
CANGCON |= (1<<SWRES); //reset CAN interface
Pass_Flag = 0x00;
//CANMOBID[2]=(unsigned long)(SELFID<<8)|CANMOBID[2];
for(i=0;i<6;i++) //15个邮箱初始化
{
temp=CANMOBID[i]<<3; //ID初始化
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);
Pass_Flag = Pass_Flag + 1;
NOP();
}
if(Pass_Flag!=0x06)
RESET;
WDR();
Pass_Flag = 0x00;
for(i=0;i<6;i++)
{
temp=CANMOBMD[i]<<3;
temp1=(unsigned int)temp; //低16位
temp2=(unsigned int)(temp/0x00010000); //高16位
CANIDM[i][3]=(Uchar)temp1;
CANIDM[i][2]=(Uchar)(temp1>>8);
CANIDM[i][1]=(Uchar)temp2;
CANIDM[i][0]=(Uchar)(temp2>>8);
Pass_Flag = Pass_Flag + 1;
NOP();
}
if(Pass_Flag!=0x06)
RESET;
//reset all MObs
Pass_Flag = 0x00;
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
Pass_Flag = Pass_Flag + 1;
}
if(Pass_Flag!=0x0f)
RESET;
WDR();
CANBT1 = CanBaud[2][0];
CANBT2 = CanBaud[2][1];
CANBT3 = CanBaud[2][2];
//configure MObi
/******************************************************************/
Pass_Flag = 0x00;
for (i=0; i<3; i++)
{
CANPAGE = (i<<4); //MOb 0,1,2设置为发送模式
CANIDT1 = CANIDT[i][0]; //初始化 ID
CANIDT2 = CANIDT[i][1];
CANIDT3 = CANIDT[i][2];
CANIDT4 = CANIDT[i][3];
CANIDM1 = CANIDM[i][0]; //初始化 mask
CANIDM2 = CANIDM[i][1];
CANIDM3 = CANIDM[i][2];
CANIDM4 = CANIDM[i][3]; //0 = ignore bit
//CANIDM4 = (1<<IDEMSK); //identifier extention mask
CANCDMOB = (1<<IDE)|(8<<DLC0); //reception, ext. ID,rev2.0B
NOP();
Pass_Flag = Pass_Flag + 1;
}
if(Pass_Flag!=0x03)
RESET;
WDR();
Pass_Flag = 0x00;
for(i=3;i<6;i++)
{
CANPAGE = (i<<4); //MOb3,4,5设置为接受模式
CANIDT1 = CANIDT[i][0]; //初始化 ID
CANIDT2 = CANIDT[i][1];
CANIDT3 = CANIDT[i][2];
CANIDT4 = CANIDT[i][3];
CANIDM1 = CANIDM[i][0]; //初始化 mask
CANIDM2 = CANIDM[i][1];
CANIDM3 = CANIDM[i][2];
CANIDM4 = CANIDM[i][3]; //0 = ignore bit
CANCDMOB = (2<<CONMOB0)|(1<<IDE)|(8<<DLC0); //reception, ext. ID,rev2.0B
NOP();
Pass_Flag = Pass_Flag + 1;
}
if(Pass_Flag!=0x03)
RESET;
CANGCON = (1<<ENASTB); //start CAN interface, enable mod
CANGIE = (1<<ENIT)| (1<<ENRX)|(1<<ENTX); //enable receive interrupt and transmitte interrupt
CANIE1 = 0x00;
CANIE2 = 0x3f; //enable ALL MObs interrupt
WDR();
while (!(CANGSTA & (1<<ENFG))); //wait until module ready
CANGCON |= (1<<ENA); //enable CAN controller
SEI();
}
/*******************************************************************
CAN transmission via mailbox 1 (polling)
*******************************************************************/
void can_tx (VCI_CAN_OBJ msg)
{
unsigned char i,index,pass_Flag;
pass_Flag = 0x01;
CLI();
index =(unsigned char) (msg.ID%256);
pass_Flag <<= 1;
msg.ID <<= 3;
CANPAGE = (index<<4);
CANCDMOB = (1<<IDE) |(8<<DLC0);
pass_Flag <<= 1;
CANIDT4 = (unsigned char) (msg.ID&0xF8);
CANIDT3 = (unsigned char) (msg.ID>>8);
CANIDT2 = (unsigned char) (msg.ID>>16);
pass_Flag <<= 1;
CANIDT1 = (unsigned char) (msg.ID>>24);
if(pass_Flag!=0x08)
RESET;
for(i=0;i<8;i++)
{
CANMSG = msg.Data[i];
}
CANCDMOB |= (1<<CONMOB0); //enable transmission
SEI();
}
#pragma interrupt_handler can_ReceiveData:19
void can_ReceiveData (void) //receive interrupt
{
unsigned char nb_data;
unsigned char i,nn,err_temp,sta_temp;
unsigned int RC_CANSI,RCtemp2,tempp,RCF;
VCI_CAN_OBJ msg[3];
WDR();
CANGIE &= ~((1<<ENRX)|(1<<ENTX)); //关接收中断
RCtemp2=CANSIT2; //读取中断信息
err_temp = CANTEC; //读取发送错误计数器
if(err_temp>96)
RESET;
err_temp = CANREC; //读取接收错误计数器
if(err_temp>128)
RESET;
if(RCtemp2&(0x07))
{
for(i=0;i<3;i++) //查询前三个邮箱中断状态
{
tempp=(1<<i);
RCF=(RCtemp2&tempp);
if(RCF!=0)
{
CANPAGE = i<<4;
sta_temp = CANSTMOB;
CANSTMOB &= ~(1<<TXOK);
CANCDMOB = 0x18;
if(sta_temp&0x40) //是发送完成中断
{
send_count = 0; //清发送计数器
if(LED)
PORTB |= 0x40;
else
PORTB &= 0xbf;
WDR();
}
}
}
}
else if(RCtemp2&(0x38))
{
for(i=3;i<6;i++) //判断哪个邮箱产生接收中断
{
tempp=(1<<i);
RCF=(RCtemp2&tempp);
if(RCF!=0)
{
if(LED)
PORTB |= 0X80;
else
PORTB &= 0X7f;
CANPAGE = i<<4;
WDR();
for (nb_data = 0; nb_data <8; nb_data++)
{
rece_data[i-3].Data[nb_data]=CANMSG;
}
rece_data[i-3].ID = 0;
rece_data[i-3].ID |= ((unsigned long) CANIDT1<<24); //get identifier
rece_data[i-3].ID |= ((unsigned long) CANIDT2<<16);
rece_data[i-3].ID |= ((unsigned long) CANIDT3<<8);
rece_data[i-3].ID |= (CANIDT4&0xF8);
rece_data[i-3].ID >>= 3;
CANSTMOB &= ~((1<<RXOK)|(1<<TXOK));
CANCDMOB = 0x98; //接收使能
}
}
}
CANGIE |= (1<<ENRX); //开中断
CANGIE |= (1<<ENTX);
WDR();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -