📄 canzj.c
字号:
Delay100TCYx(2);//等待200Fosc,确保离开复位状态
ClrWdt();
}
void CAN2510Init(void)
{
unsigned char temp;
CAN2510Reset();// 进入配置模式
ClrWdt();
TestTryTime=100;
while(TestTryTime--) //等待进入配置模式
{
CAN2510Enable();//CS=0;
//Delay10TCY();
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_CANSTAT);//CAN 状态寄存器 地址
temp=ReadSPI();
CAN2510Disable();//结束操作
//Delay10TCY();
if((temp&0x80)==0x80) break;
}
if(TestTryTime==0x00) DebugErrorCode=CAN2510_ENTCONFG_ERR;
//设置CAN的波特率为5K,在Fosc=4M时,Tbit=200us,假设BRP=39, 则
//TQ=[2*(1+BRP)]/Fosc=2*(1+39)/4=20us。
//NOMINAL BIT RATE=10TQ,SJW=1,Sync_Seg=1TQ,Prog _Seg=1TQ,Phase_Seg1=4TQ,Phase_Seg2=4TQ
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_CNF3);
WriteSPI(0x43);//设置Phase_Seg2=4TQ
WriteSPI(0x98);//设置Phase_Seg1=4TQ和Prog _Seg=1TQ
WriteSPI(0x27);//设置SJW和BRP,SJW=1TQ,BRP=39H
CAN2510Disable();
//Delay10TCY();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_BFPCTRL);
WriteSPI(0x05);//RXnBF 引脚控制和状态寄存器
WriteSPI(0x00);//TXnRTS引脚控制和状态寄存器
CAN2510Disable();
//Delay10TCY();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_TXB0CTRL);
WriteSPI(0x03);//设为最高优先级
CAN2510Disable();
//Delay10TCY();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_RXB0CTRL);
WriteSPI(0x60);//接收所有有效信息
CAN2510Disable();
//Delay10TCY();
//初始化接收滤波器
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_RXF0SIDH);
WriteSPI(0xff);
WriteSPI(0xeb);
WriteSPI(0xff);
WriteSPI(0xff);
CAN2510Disable();
//Delay10TCY();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_RXM0SIDH);
WriteSPI(0x00);
WriteSPI(0x00);
WriteSPI(0x00);
WriteSPI(0x00);
CAN2510Disable();
//Delay10TCY();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_CANINTE);//中断使能寄存器
WriteSPI(0x01);//使能接收0的中断
WriteSPI(0x00); //清除所有中断标志
CAN2510Disable();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_CANCTRL);
WriteSPI(0x00);//进入正常工作模式
TestTryTime=100;
ClrWdt();
while(TestTryTime--) //等待进入配置模式
{
CAN2510Enable();//CS=0;
//Delay10TCY();
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_CANSTAT);//CAN 状态寄存器 地址
temp=ReadSPI();
CAN2510Disable();//结束操作
//Delay10TCY();
if((temp&0xE0)==0x00) break;
}
if(TestTryTime==0x00) DebugErrorCode=CAN2510_QUITCONFG_ERR;
CAN2510Disable();
Delay10TCY();
}
void send2510_data(unsigned char FrameType, unsigned char IDbuff[4],unsigned char DataBuff[8])
{
unsigned char temp;
unsigned char temp1;
unsigned char Flag;
Flag=0x00;
ClrWdt();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_TXB0SIDH);
temp1=IDbuff[1]>>5;
temp=temp1+(IDbuff[0]<<3);
WriteSPI(temp);
temp1=(IDbuff[1]&0x1f)<<3;//取后5位
temp=IDbuff[1]&0x03;//取后2位
temp1=temp1+temp;
if(FrameType==1) temp1=temp1|0x08;
if(FrameType==0) temp1=temp1&0xf7;
WriteSPI(temp1);
WriteSPI(IDbuff[2]);
WriteSPI(IDbuff[3]);
WriteSPI(0x08);//设置发送数据长度为8
for(temp=0;temp<8;temp++) WriteSPI(DataBuff[temp]);
Nop();
Nop();
CAN2510Disable();
//CAN2510Enable();//CS=0;
//WriteSPI(MCP2510_WRITE);//写指令
//WriteSPI(MCP2510_TXB0CTRL);
//WriteSPI(0x0b);//请求发送
//CAN2510Disable();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_RTS0);//启动发送TXB0CTRL.TXREQ
WriteSPI(0x81);//请求发送
CAN2510Disable();
while(1)
{
ClrWdt();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_CANINTF);//CAN 中断标志寄存器 地址
temp=ReadSPI();
CAN2510Disable();//结束操作
//Delay10TCY();
if((temp&0x04)==0x04) {
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_CANINTF);
WriteSPI(0x04);//屏蔽字节
WriteSPI(0x00);//清除TX0IF标志
CAN2510Disable();//结束操作
break;
}
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_TXB0CTRL);//发送缓冲器0控制寄存器
temp=ReadSPI();
CAN2510Disable();//结束操作
//Delay10TCY();
if((temp&0x20)==0x20)//丢失仲裁,(断路)
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_TXB0CTRL);
WriteSPI(0x03);//中止发送
CAN2510Disable();
DebugErrorCode=CAN2510_SEND1_ERR;
Flag=0x01;
//Delay10TCY();
break;
}
if((temp&0x10)==0x10)//总线错误(短路)
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_TXB0CTRL);
WriteSPI(0x03);//中止发送
CAN2510Disable();
DebugErrorCode=CAN2510_SEND2_ERR;
Flag=0x02;
//Delay10TCY();
break;
}
}
if(Flag==0x00) DebugErrorCode=CAN_SENDOK;
}
void MCP2510Rec(void)
{
unsigned char temp,temp1,temp2;
unsigned char DataLeng;
ClrWdt();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_CANINTF);//中断标志寄存器
MCP2510IntStatus.word=ReadSPI();
CAN2510Disable();//结束操作
ClrWdt();
if(MCP2510IntStatus.Bits.RX0IF)//接收缓冲器0 满中断标志
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_RXB0SIDH);//收缓冲器0 标准标识符高位
temp=ReadSPI();
Can2510RevData.FrameID[0]=temp>>3;
temp1=ReadSPI();
temp2=temp1&0x03;//取后2位
temp2=temp2+((temp1&0xe0)>>3);
temp2=((temp&0x07)<<5)+temp2;
Can2510RevData.FrameID[1]=temp2;
Can2510RevData.FrameID[2]=ReadSPI();
Can2510RevData.FrameID[3]=ReadSPI();
DataLeng=ReadSPI();//数据长度
Can2510RevData.FrameData[0]=ReadSPI();
Can2510RevData.FrameData[1]=ReadSPI();
Can2510RevData.FrameData[2]=ReadSPI();
Can2510RevData.FrameData[3]=ReadSPI();
Can2510RevData.FrameData[4]=ReadSPI();
Can2510RevData.FrameData[5]=ReadSPI();
Can2510RevData.FrameData[6]=ReadSPI();
Can2510RevData.FrameData[7]=ReadSPI();
CAN2510Disable();//结束操作
ClrWdt();
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_CANINTF);
WriteSPI(0x01);//屏蔽字节
WriteSPI(0x00);//清除接收缓冲器0 满中断标志
CAN2510Disable();//结束操作
StateTemp.Bits.CAN2510RV_BIT=1; //置接收标志
}
if(MCP2510IntStatus.Bits.WAKIF)//总线唤醒中断,休眠模式下,退出休眠
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_CANINTF);
WriteSPI(0x40);//屏蔽字节
WriteSPI(0x00);//清除接收缓冲器0 满中断标志
CAN2510Disable();//结束操作
}
if(MCP2510IntStatus.Bits.ERRIF)//总线错误(溢出或发送/ 接收节点的状态发生改变)中断,
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_CANINTF);
WriteSPI(0x20);//屏蔽字节
WriteSPI(0x00);//清除出错中断标志
CAN2510Disable();//结束操作
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_READ);//读指令
WriteSPI(MCP2510_EFLG);//错误标志寄存器
temp=ReadSPI();
CAN2510Disable();//结束操作
if((temp&0x40)==0x40)//接收缓冲区0溢出
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_EFLG);
WriteSPI(0x40);//屏蔽字节
WriteSPI(0x00);//清除溢出
CAN2510Disable();//结束操作
DebugErrorCode=CAN2510_REVBUFF0_ERR;
}
if((temp&0x20)==0x20)//总线关闭
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_WRITE);//写指令
WriteSPI(MCP2510_CANCTRL);
WriteSPI(0x00);//正常工作模式
CAN2510Disable();
DebugErrorCode=CAN2510_SEND3_ERR;
}
}
if(MCP2510IntStatus.Bits.MERRF)//报文出错(报文发送和接收过程中出现错误)中断标志,与监听模式联合使用确定波特率
{
CAN2510Enable();//CS=0;
WriteSPI(MCP2510_MODIFY);//位修改
WriteSPI(MCP2510_CANINTF);
WriteSPI(0x80);//屏蔽字节
WriteSPI(0x00);//清除接收缓冲器0 满中断标志
CAN2510Disable();//结束操作
}
ClrWdt();
}
//--------------主程序--------------------------
void main (void)
{
unsigned char i;
init_cpu();
#ifdef Debug
CanTxData.FrameID[0]=0x11;
CanTxData.FrameID[1]=0x22;
CanTxData.FrameID[2]=0x33;
CanTxData.FrameID[3]=0x44;
for(i=0;i<8;i++) CanTxData.FrameData[i]=0x00;
CanTxData.FrameData[0]=DebugErrorCode;
#endif
CAN2510Init();
INTCON = 0x70; //开放外围模块、timer0、int0中断
WDTCON = 0x01;//开看门狗
INTCONbits.GIE=1;//开总中断
#ifdef Debug
CanTxData.FrameData[1]=DebugErrorCode;
send_data(1,CanTxData.FrameID,CanTxData.FrameData);
CanTxData.FrameData[2]=DebugErrorCode;
send2510_data(1,CanTxData.FrameID,CanTxData.FrameData);
#endif
ClrWdt();
while(1)
{
ClrWdt();
switch(Thread)
{
case NO_THREAD:
if(StateTemp.Bits.TSEC_BIT) //1s
{
StateTemp.Bits.TSEC_BIT=0;
PORTAbits.RA0=1;
PORTAbits.RA1=1;
Thread=THREAD_IDLE;
}
break;
case THREAD_IDLE:
if(StateTemp.Bits.TSEC_BIT) //1s
{
StateTemp.Bits.TSEC_BIT=0;
PORTAbits.RA0=!PORTAbits.RA0;
}
if(StateTemp.Bits.TMSEC_BIT) //100ms
{
StateTemp.Bits.TMSEC_BIT=0;
if(PORTAbits.RA1==0) PORTAbits.RA1=1;
//if(DebugErrorCode!=0x00)//CAN总线任何错误
}
if(StateTemp.Bits.CANRV_BIT) //pic18f258 can
{
StateTemp.Bits.CANRV_BIT=0;
for(i=0;i<4;i++) Can2510TxData.FrameID[i]=CanRevData.FrameID[i];
for(i=0;i<8;i++) Can2510TxData.FrameData[i]=CanRevData.FrameData[i];
send2510_data(1,Can2510TxData.FrameID,Can2510TxData.FrameData);
}
if(StateTemp.Bits.CAN2510RV_BIT)//mcp2510 can
{
for(i=0;i<4;i++) CanTxData.FrameID[i]=Can2510RevData.FrameID[i];
for(i=0;i<8;i++) CanTxData.FrameData[i]=Can2510RevData.FrameData[i];
send_data(1,CanTxData.FrameID,CanTxData.FrameData);
StateTemp.Bits.CAN2510RV_BIT=0;
}
if((PORTBbits.RB0==0)||StateTemp.Bits.INT0_BIT)//防止多个中断同时发生,INT0是下降沿中断,这样就会出现不能进入INT0中断
{
MCP2510Rec();
if(StateTemp.Bits.INT0_BIT) StateTemp.Bits.INT0_BIT=0;
}
break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -