⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canzj.c

📁 是一个CAN转接的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -