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

📄 can.cpp

📁 Canbus驱动德一个源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {
        ev_receive(EV_CAN_TIMER|EV_CAN_EOPD, EV_WAIT|EV_ANY, 0, &events_r);

		//有接收中断发生
		if(events_r & EV_CAN_EOPD)
		{
			CanDaemonReceiver();
		}
		
		//CAN定时
		if(events_r & EV_CAN_TIMER )
		{
			CanTimer++;
			
			//若有接收的信息没有被处理,则处理,监视,不希望调用太频繁。
			if( ( CanTimer % (200/MIN_CAN_TIMER) ) == 0)
			{
				CanDaemonReceiver();
			}

			//发送操作,主要为发送链路结束请求,第一层控制发送频率
			for(i=0; i<CanStationCount; i++)
			{
				for(j=0; j<2; j++)
				{
					if( CanCB[i].fStart[j] == TRUE )
					{
						//由(MAX_END_LINK_TIME-MIN_END_LINK_TIME)/MIN_CAN_TIMER决定重发的次数
						if( CanCB[i].StopSendCount[j] != 0xffff )
						{
							if( CanCB[i].StopSendCount[j] > (MIN_END_LINK_TIME/MIN_CAN_TIMER) )
							{
								//开始发送链路结束请求
								if( CanCB[i].StopSendCount[j] < (MAX_END_LINK_TIME/MIN_CAN_TIMER) ) 
								{
									MyAddr = CanCB[i].Addr + COMMAND_PRI;
									CellBuf[0] = (MyAddr>>3)&0xff;
									CellBuf[1] = (MyAddr<<5)&0xff;
		
									CellBuf[2] = 3;
									CellBuf[3] = REQUEST_LINK_END;
	
									if( j==0 )
									{
										CellBuf[4] = NORMAL_CHANNEL;
									}
									else
									{
										CellBuf[4] = URGENCY_CHANNEL;
									}
								
									CellBuf[5] = CanCB[i].SendEnd[j];
									
									PutToCommand(CellBuf, i);
									
									CanCB[i].StopSendCount[j] ++;
									
									//等待,防止重复进入
									//?????????????????/多个模块问题
									//tm_wkafter(TICK2MS(20));
									
								}
								//超过了最大重发次数,复位链路
								else
								{
									RequstResetLink(j, i, 10);
								}
							}
							else
							{
								CanCB[i].StopSendCount[j] ++;
							}
						}
					}
				}
			}

			//led判断
			if( fSendLed == TRUE )
			{
				GlintCanLed(TRUE, FALSE );
				fSendLed = FALSE;
			}
			if( fReceLed == TRUE )
			{
				GlintCanLed(FALSE, FALSE );
			}

			//状态寄存器,监视发送,防止发送停止而缓冲有数据
			//for debug
			//BeginSendCell();

			#if( CAN_STATION ==TRUE ) 

				for(i=0; i<CanStationCount; i++)
				{
					//单板程序启动时,每隔1秒发送一次请求复位链路的命令(单板)
					if( (CanCB[i].fStart[0]==FALSE) || (CanCB[i].fStart[1]==FALSE) )
					{ 
						if( (CanTimer % (1200/MIN_CAN_TIMER)) == 0 )
						{
							if( CanCB[i].fStart[0] == FALSE )
							{
								RequstResetLink(0, i, 12);
							}
							
							if( CanCB[i].fStart[1] == FALSE )
							{
								RequstResetLink(1, i, 13);
							}
						}
					}
				}

			#endif
	

			//复位链路控制
			//查询所有的链路标志,看是否有复位标志
			if( CanTimer % (500/MIN_CAN_TIMER) == 0 )
			{
				for(i=0; i<CanStationCount; i++)
				{
					for(j=0; j<2; j++)
					{
						if( CanCB[i].fStart[j] == FALSE )
						{
							//在此链路发送,链路启动帧
							if( j==0 )
							{
								MyAddr = CanCB[i].Addr + NORMAL_PRI;
								
								CellBuf[0] = (MyAddr>>3)&0xff;
								CellBuf[1] = (MyAddr<<5)&0xff;
		
								CellBuf[2] = 1;
								CellBuf[3] = 0xc0;
								
								PutToNormal(CellBuf, i);
								
								BeginSendCell();
							}
							else
							{
								MyAddr = CanCB[i].Addr + URGENCY_PRI;
								
								CellBuf[0] = (MyAddr>>3)&0xff;
								CellBuf[1] = (MyAddr<<5)&0xff;
		
								CellBuf[2] = 1;
								CellBuf[3] = 0xc0;
								
								PutToUrgency(CellBuf, i);
								
								BeginSendCell();
							}
						}
					}
				}
			}

			//监视从应用层下发的接收缓冲,若由数据则拆包
			if( RUBufWPoint != RUBufRPoint )
			{
				MakeSendCell(ReceMode[RUBufRPoint]&0xffff, ReceUpBuffer[RUBufRPoint], ReceLength[RUBufRPoint], (ReceMode[RUBufRPoint]>>31) );

				RUBufRPoint ++;
				RUBufRPoint %= MAX_RUP_BUF;
				
				DF_PostMessage(CanUpTaskId,SM_COMMIDLE);
			}
			
			if( fReceFrameOk == TRUE )
			{
				if( CanDelay > MAX_CAN_DELAY )
				{
					DF_PostMessage(CanUpTaskId,SM_COMMIDLE);
					fReceFrameOk = FALSE;
					CanDelay = 0;
				}
				else
				{
					CanDelay ++;
				}
			}
		}
	}
}


void CanInitStatic(void)
{
	DWORD i;
	
	for(i=0; i<CanStationCount; i++)
	{
		//此块对应的分板的站址,0为无效
		CanCB[i].Addr = 0;
		
		//单元接收序号
		CanCB[i].ROrder[0] = 0;
		CanCB[i].ROrder[1] = 0;
		
		//单元发送序号
		CanCB[i].SOrder[0] = 1;
		CanCB[i].SOrder[1] = 1;
		
		//#if( CAN_STATION == TRUE ) 
			//链路启动状态
			CanCB[i].fStart[0] = FALSE;
			CanCB[i].fStart[1] = FALSE;
		//#else 
			//链路启动状态
			//CanCB[i].fStart[0] = TRUE;
			//CanCB[i].fStart[1] = TRUE;
		//#endif
		
		//当前桢起始单元序号
		CanCB[i].StartCellOrder[0] = 0;
		CanCB[i].StartCellOrder[1] = 0;
		
		//当前桢中的总共的单元数据,不包括控制单元
		CanCB[i].FrameLength[0] = 0;
		CanCB[i].FrameLength[1] = 0;
		
		//当前处理到的单元序号,在一桢中
		CanCB[i].FrameOrder[0] = 0;
		CanCB[i].FrameOrder[1] = 0;
		
		//发送链路结束请求时,最后一个单元的序号
		CanCB[i].SendEnd[0] = 0;
		CanCB[i].SendEnd[1] = 0;
		
		//当前丢失的单元(正在复要的)
		CanCB[i].RequestCell[0] = 0;
		CanCB[i].RequestCell[1] = 0;
	
		CanCB[i].RequestCount[0] = 0;
		CanCB[i].RequestCount[1] = 0;
		
		//
		CanCB[i].StopSendCount[0] = 0xffff;
		CanCB[i].StopSendCount[1] = 0xffff;
		
		//普通发送缓冲
		CanCB[i].NSBufRPoint = 0;
		CanCB[i].NSBufWPoint = 0;
		
		//紧急上传发送缓冲
		CanCB[i].USBufRPoint = 0;
		CanCB[i].USBufWPoint = 0;
	
		//命令发送缓冲
		CanCB[i].CSBufRPoint = 0;
		CanCB[i].CSBufWPoint = 0;
		
		//接收缓冲
		//一般接收缓冲
		CanCB[i].NRBufRPoint = 0;
		CanCB[i].NRBufWPoint = 0;
		
		//紧急接收缓冲
		CanCB[i].URBufRPoint = 0;
		CanCB[i].URBufWPoint = 0;
		
		//命令接收缓冲
		CanCB[i].CRBufRPoint = 0;
		CanCB[i].CRBufWPoint = 0;
		
		//for debug
		CanCB[i].NormalSendAll = 0;
		CanCB[i].NormalReceAll = 0;
		CanCB[i].CommandSendAll = 0;
		CanCB[i].CommandReceAll = 0;
		CanCB[i].UrgencySendAll = 0;
		CanCB[i].UrgencyReceAll = 0;
	}
	
	NSUBufRPoint = 0;
	NSUBufWPoint = 0;
	
	USUBufRPoint = 0;
	USUBufWPoint = 0;
	
	RUBufRPoint = 0;
	RUBufWPoint = 0;

	//保证第一次能够发送COMMIDLE消息
	fReceFrameOk = TRUE;

	IsrErrorCount = 0;
	
	CanDelay = 0;
}

//for debug
DWORD HouTaiTaskID;
void HouTaiTask(DWORD);

#if(TEST_SHARD==TRUE)
BYTE TestBuf[16];
DWORD CanCount; 
#endif

DWORD CanInitial(DWORD PortSort)
{

	DWORD i;

	DWORD PDevId[MAX_STATION];
	
	//根据系统得到CAN网的信息,如配置了多少分板
	CanStationCount = GetDeviceNum( (PORT_CANBUS + PortSort) );
	//CanStationCount = MAX_STATION;
	
	//大于系统最大允许数量
	if( CanStationCount > MAX_STATION ) 
	{
		return FALSE;
	}
	
	//动态申请内存
	CanCB = new TCanCBlock[CanStationCount];
	
	if( CanCB ==  NULL )
	{
		return FALSE;
	}
	 
	//初始化静态变量
	CanInitStatic();
	
	//根据系统得到CAN网的信息,每个分板的地址为什么
	GetDeviceIDSet(PDevId, PORT_CANBUS + PortSort );

	for(i=0; i<CanStationCount; i++) 
	{
		CanCB[i].Addr = GetDeviceAddress(PDevId[i]);
	}

	CanUpTaskId = GetAppID();
	
	//for(i=0; i<CanStationCount; i++)
	//{
	//	CanCB[i].Addr = i+1;
	//}
	//CanCB[0].Addr = 4;

	//***********************************************
	#if ( TEST_SHARD == TRUE )
	//for debug
	//初始化硬件
	InitCanHard();
	
	DWORD MyCount = 0;
	BYTE Status;
	
	//站号,优先级最低。
	WORD Temp = 99; 
	
	TestBuf[0] = (Temp>>3)&0xff;
	TestBuf[1] = (Temp<<5)&0xff;
	
	TestBuf[2] = 0;
	TestBuf[3] = 0;
	
	TestBuf[4] = 8;
	
	TestBuf[5] = 0;
	TestBuf[6] = 0;
	TestBuf[7] = 0;
	TestBuf[8] = 0;
	TestBuf[9] = 5;
	TestBuf[10] = 6;
	TestBuf[11] = 7;
	TestBuf[12] = 8;

    	//设置CAN网中断
    	DF_SetIntVector(SV_CANBUS, CanIsr,PortSort);
    
	CanCount = 0;

	//为发送准备
	Write2510Bytes(Txb0Sidh, TestBuf, MAX_CELL_SIZE);
	//开始发送
	MCP2510BitFunc(Txb0Ctrl, 0x08, 0x08);

	CanCount ++;
	TestBuf[5] = CanCount>>24;
	TestBuf[6] = CanCount>>16;
	TestBuf[7] = CanCount>>8;
	TestBuf[8] = CanCount;

	DWORD Temp1;

 	for(;;)
	{
		if( CanCount != Temp1 )
		{
			SetTpuIoStatus(7, IS_HIGH);
		}
		else
		{
			SetTpuIoStatus(7, IS_LOW);
		}
		
		Temp1 = CanCount;
		
		tm_wkafter(10);
	}

	#endif
	
	#if( TEST_RHARD == TRUE )
	InitCanHard();

    //设置CAN网中断
    DF_SetIntVector(SV_CANBUS, CanIsr,PortSort);
    
	for(;;);
	#endif
	//***********************************************

	//初始化硬件
	InitCanHard();
	
	//生成CAN管理任务
	if( t_create("CAND", 0xb1, 4096, 512, 0, &CanDaemonTaskId) != SUCCEED )
	{
		return FAIL;
	}
	
	if( t_start(CanDaemonTaskId, T_SUPV|T_PREEMPT|T_NOTSLICE, (TTASK_ENTRY)CanDaemon,0) != SUCCEED )
	{
		return FAIL;
	}
	
	//*******************************************for debug
	//创建后台任务
	//if( t_create("HOUT", 10, 4096, 512, 0, &HouTaiTaskID) != SUCCEED ) 
	//{
	//	return FAIL;
	//}
	
	//if( t_start(HouTaiTaskID, T_SUPV|T_PREEMPT|T_NOTSLICE, (TTASK_ENTRY)HouTaiTask,0) != SUCCEED )
	//{
	//	return FAIL;
	//}    
    //CanUpTaskId = DF_CreateTask("HOUT",(TTASK_ENTRY)HouTaiTask,0xf0,3096,0,0,0);
	//*******************************************
	
	//熄灭收发灯
	GlintCanLed(TRUE, FALSE);
	GlintCanLed(FALSE, FALSE);

        //设置CAN网中断
        DF_SetIntVector(CANBUS1_INT_VECTOR, CanIsr,PortSort);

	//允许CAN网中断,要求后台任务优先级要比CAN网任务高
        DF_EnableInt(CANBUS1_INT_VECTOR);
        return SUCCEED;
}

//*********************************************************for debug
DWORD FrameCount;
BYTE SendCount;
DWORD SendError;
void HouTaiTask(DWORD appid)
{
	WORD i;

	BYTE UpBuf[256];

	BYTE MyBuf[256];
	WORD SendCount2 = 0;
	WORD SendCount1 = 0;
	
	WORD CheckSum;
	
	for(i=0; i<256; i++)
	{
		MyBuf[i] = i+1;
	}
	
	MyBuf[0] = 240;
	
	CheckSum = 0; 
	
	for(i=1; i<240; i++)
	{
		CheckSum += MyBuf[i];
	}

	tm_wkafter(MS2TICK(4000));

	WORD WaitSendTime;
	
    TMessage msg;
    
    //启动遥控等待时间定时器
    DF_SetTimer(0, 0, 500); 
    
    DWORD Status = ERR_MESSAGE_OK;
	
	while(Status != ERR_MESSAGE_QUIT)
	{
        //调用取消息函数,从任务消息队列头,取需要处理的消息
        Status = DF_GetMessage(appid,&msg);
        
        //判断接收的消息是否为有效消息
        if(Status == ERR_MESSAGE_OK)
        {
			//根据消息执行功能
			switch( LOWORD(msg.lParam) ) 
			{
                //系统定时
                case SM_TIMEOUT:
                
					if( CanCB[0].fStart[1] == TRUE )
					{
						MyBuf[1] = SendCount2;
						
						CheckSum = 0;
						for(i=1; i<240; i++)
						{
							CheckSum += MyBuf[i];
						}
					
						MyBuf[240] = (CheckSum>>8)&0xff;
						MyBuf[241] = CheckSum&0xff;
			
						
						if( CanWrite(0, MyBuf, 242, ((WCF_URGENT<<31)|4) ) != 0 )
						{
							SendCount2 ++;   
						}
					}

                	break;
                	
                case SM_READCOMM:
                	CanRead(0, UpBuf);
                
					//for debug
					CheckSum = 0;
					for(i=1; i<UpBuf[0]; i++)
					{
						CheckSum += UpBuf[i];
					}
					
					if( ((CheckSum>>8)&0xff) == UpBuf[ UpBuf[0] ] )
					{
						if( (CheckSum&0xff) == UpBuf[ UpBuf[0]+1 ] )
						{
							FrameCount ++;
								
							//返回
							//CanWrite(0, UpBuf, 26, ((WCF_NORMAL<<31)|CanCB[0].Addr) );
							
							if( SendCount != UpBuf[1] )
							{
								SendError ++;
							}
							
							SendCount = UpBuf[1];
							SendCount ++;
						}
					}
			
                	break;
                	
                case SM_COMMIDLE:
                	SendCount1 ++;
                	break;
                	
                default:
					break;
			}
		}
	}
}
//*********************************************************for debug 




#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -