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

📄 can_232.c

📁 本程序是一个将CanOpen协议的通讯转换为TTL串口通讯(9600,e,7,1),CANOPEN的站号是9
💻 C
📖 第 1 页 / 共 2 页
字号:
		j=xx.yy.i&0x0F;
		if(j>8) j=8;

		cc=xx.yy.i&BIT7;

		//读取标识符
		if(cc==1)
		{//SFF=1:扩展帧
			xx.yy.i=RxBuffer[0];
			xx.yy.k=RxBuffer[1];
			xx.yy.m=RxBuffer[2];
			xx.yy.n=RxBuffer[3];
			xx.l>>=2;
		}
		else
		{//SFF=0:标准帧
			xx.yy.m=RxBuffer[0];
			xx.yy.n=RxBuffer[1];
			xx.mn[1]>>=4;
		}
        xx.yy.k=xx.yy.m&0x0F;
        xx.mn[1]>>=1;
		xx.yy.i=0;
		if((xx.yy.m==0)&&(xx.yy.n==0))
		{//NMT控制
			xx.yy.i=3;
		}
		else if((xx.yy.m==0)&&(xx.yy.n==0x80))
		{//SYNC
			xx.yy.i=3;
		}
		else if((xx.yy.m==1)&&(xx.yy.n==0))
		{//TIME SSTAMP
			xx.yy.i=3;
		}
		else
		{
			xx.yy.n&=0x7F;

			if(xx.yy.n==Can_ID)
			{//是本机的数据
				if(xx.yy.k>14)
				{//错误命令
					xx.yy.i=2;
				}
				else if(xx.yy.k==1)
				{//紧急
					xx.yy.i=3;
				}
				else if(xx.yy.k==4)
				{//PDO1(接收)
					xx.yy.k=0;//读取的数据存放的起始地址
				}
				else if(xx.yy.k==6)
				{//PDO2(接收)
					xx.yy.k=8;//读取的数据存放的起始地址
				}
				else if(xx.yy.k==8)
				{//PDO3(接收)
					xx.yy.k=16;//读取的数据存放的起始地址
				}
				else if(xx.yy.k==10)
				{//PDO4(接收)
					xx.yy.k=24;//读取的数据存放的起始地址
				}
//				else if(xx.yy.k==3)
//				{//PDO1(发送)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==5)
//				{//PDO2(发送)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==7)
//				{//PDO3(发送)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==9)
//				{//PDO4(发送)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==11)
//				{//SDO(发送/服务器)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==12)
//				{//SDO(接收/客户)
//					xx.yy.i=3;
//				}
//				else if(xx.yy.k==14)
//				{//NMT Error Control
//					xx.yy.i=3;
//				}
				else
				{//目前不支持的命令
					xx.yy.k=3;
				}
			}
			else
			{
				//不是本机的数据
				xx.yy.i=1;
			}
		}
		if(xx.yy.i==0)
		{
			if(cc==0)//SFF=0:标准帧
			{
				xx.yy.n=2;//读取数据在CAN控制器缓冲区的起始地址
			}
			else if(cc==1)//EFF=1:扩展帧
			{
				xx.yy.n=4;//读取数据在CAN控制器缓冲区的起始地址
			}

			//读取数据
			xx.yy.m=j+xx.yy.k;
			x=0;
			for(;xx.yy.k<xx.yy.m;xx.yy.k++,xx.yy.n++)
			{
				x++;
				CAN_RecBuf[xx.yy.k]=RxBuffer[xx.yy.n];
			}
			if(CAN_RecBuf[0]==1)
			{//设置CAN波特率
				//读取参数的命令
				if(btr!=CAN_RecBuf[1])
				{
					if(CAN_RecBuf[1]<=btr_10k)
					{
						btr=CAN_RecBuf[1];
						EEP_ERASE(1);//擦除第一扇区
						EEP_BYTE_WRITE(EEP_Start,btr);
						return 5;//修改CAN波特率
					}
				}
			}
			if(CAN_RecBuf[0]==5)
			{//读取命令
				//读取参数的命令
				if(x>1)
				{
					RunStatus=CAN_RecBuf[1];
				}
				SCI_SendBuf[2]=RunStatus;
				SCI_SendBuf[0]=0x7F;
				SCI_SendBuf[1]=0x02;
				SCI_SendBuf[3]=0x05;
				SCI_SendLen=4;	//要发送的数据为4个字节
				SCI_SendCount=0;//当前发送的数据是第0个字节
				TI=1;			//启动串口发送

				SCI_RecCount=0;	//当前从串口接收的数据
				//SCI_RecLen=22;//接收长度
				RI=0;			//清除接收标志
				REN=1;			//启动串口接收
			}
			else if(CAN_RecBuf[0]==2)
			{//写入命令
				if((j<8)||(xx.yy.k>=CAN_RecLen))
				{//收到一个完整的命令
					//设置参数
					SCI_SendBuf[15]=0;
					SCI_SendBuf[14]=3;


					//低速牵伸微调
					SCI_SendBuf[13]=SCI_SendBuf[7]&0x0F;
					SCI_SendBuf[12]=SCI_SendBuf[6]>>4;
					SCI_SendBuf[11]=SCI_SendBuf[6]&0x0F;

					SCI_SendBuf[10]=SCI_SendBuf[8];//低速牵伸系数
					//SCI_SendBuf[9]=SCI_SendBuf[9];//状态设定
					//保存设置
					if(RunStatus!=SCI_SendBuf[9])
					{
						unsigned char tmp;
						RunStatus=SCI_SendBuf[9];
						OffsetAddr++;
						tmp=OffsetAddr-EEP_Start-EEP_Offset-2;
						usTmp=BIT0;
						usTmp<<=tmp;
						OffsetFlag.i&=(~usTmp);
						EEP_BYTE_WRITE(OffsetAddr,RunStatus);
						EEP_BYTE_WRITE(EEP_Start+EEP_Offset,OffsetFlag.c[0]);
						EEP_BYTE_WRITE(EEP_Start+EEP_Offset+1,OffsetFlag.c[1]);
					}
					SCI_SendBuf[8]=SCI_SendBuf[1];//牵伸设定
					SCI_SendBuf[7]=SCI_SendBuf[5];//原料特性参数
					SCI_SendBuf[6]=SCI_SendBuf[4];//棉条异物检测系数

					//定量微调
					SCI_SendBuf[5]=SCI_SendBuf[3]&0x0F;
					SCI_SendBuf[4]=SCI_SendBuf[2]>>4;
					SCI_SendBuf[3]=SCI_SendBuf[2]&0x0F;

					SCI_SendBuf[2]=2;
					SCI_SendBuf[1]=4;
					SCI_SendBuf[0]=0x7F;

					//求校验和
					for(j=3;j<15;j++)
					{
						SCI_SendBuf[15]^=SCI_SendBuf[j];
					}
					SCI_SendLen=16;	//要发送的数据为16个字节
					SCI_SendCount=0;//当前要发送的数据是第0个字节
					TI=1;			//启动串口发送
					REN=0;			//禁止串口接收
				}
			}
			else
			{//错误的命令
			}
		}
		//释放接收缓冲区,清除数据超载位
		CommandReg=RRB_Bit|CDO_Bit;
	}
	else if(bb)
	{//一次数据发送完成
		if(CanBlkInd<2)
		{
			SendData_Can(&CanBlkInd);//启动CAN发送数据
		}
	}
	else
	{//出错
		CommandReg=AT_Bit;//中止发送
		CommandReg=RRB_Bit|CDO_Bit;//释放接收缓冲区,清除数据超载位
		InterruptReg=0;//清除中断标志

		xx.yy.i=4;
	}
	return xx.yy.i;
}
//---------------------------------------------------------------------
//函数名称:	main
//功    能:	主函数
//参    数:	无
//返 回 值:	无
//作    者:	边国利
//日    期:	2006年3月20日
//---------------------------------------------------------------------

void main(void)
{
	unsigned char cResult;
    unsigned int aaa;
	//初始化堆栈
	SP=0x80;
	//初始化Can控制器
	//读取Can的波特率
	btr=EEP_BYTE_READ(EEP_Start);
	if(btr==0xFF)
	{
		btr=btr_125k;//默认125k;
		EEP_BYTE_WRITE(EEP_Start,btr);
	}
	else
	{
		if(btr>btr_10k)
		{
			btr=btr_125k;//默认125k
			EEP_ERASE(1);//擦除第一扇区
			EEP_BYTE_WRITE(EEP_Start,btr);
		}
	}
	
	//读取最后一次设置标志量
	OffsetFlag.c[0]=EEP_BYTE_READ(EEP_Start+EEP_Offset);
	OffsetFlag.c[1]=EEP_BYTE_READ(EEP_Start+EEP_Offset+1);
	//读取最后一次设置
	OffsetAddr=EEP_Start+EEP_Offset+2;
	if(OffsetFlag.i!=0xFFFF)
	{
		usTmp=BIT0;
		for(cResult=0;cResult<16;cResult++)
		{
			if((OffsetFlag.i&usTmp)!=0)
			{
				break;
			}
			usTmp<<=1;
		}
		OffsetAddr+=cResult;
	}
	//读取运行状态
	RunStatus=EEP_BYTE_READ(EEP_Start+EEP_Offset+1);
	if(RunStatus==0xFF)
	{
		RunStatus=0;
	}

	if(OffsetFlag.i!=0xFFFF)
	{//擦除扇区(第二扇区)
		EEP_ERASE(2);
		OffsetAddr=EEP_Start+EEP_Offset+2;//设置存储地址
		EEP_BYTE_WRITE(OffsetAddr,RunStatus);
	}
	//初始化T0定时器
	TMOD=0x55;		//定时器0,1用于计数器,工作于方式1
	TH0=FenPinH;
	TL0=FenPinL;
	TH1=FenPinH;
	TL1=FenPinL;
	//初始化串口(晶振11.0592M)
	PCON=0x00;		//波特率不倍频
	T2CON=0x34;		//T2设为波特率发生器,启动T2
#ifdef JINGZHEN_11M
	RCAP2H=0xFF;
	RCAP2L=0xDC;	//设置波特率为9600
#else
	RCAP2H=0xFF;
	RCAP2L=0xCC;	//设置波特率为9600
#endif
	SCON=0x40;		//串行口工作在方式1,在接收时只有收到有效停止位时才激活RI,禁止接收

	TCON=0x55;		//清除所有中断标志,启动T1,T0,设置外部中断为沿触发

	TR0=1;					//启动定时器T0
	TR1=1;					//启动定时器T1
	ET0=1;                  //允许定时器T0中断
    ET1=1;                  //允许定时器T1中断
    EA=1;//开总中断
	InitCan();
	//IE=0;			//关总中断

	//初始化并启动WatchDog
	//WDT_RST();
	 /*
    for(cResult=0;cResult<6;cResult++)
	{
		SCI_SendBuf[cResult]=0x55+cResult;
	}
	SCI_SendCount=0;
	SCI_SendLen=6;
	TI=1;// */
	//死循环
	for(;;)
	{
        //喂狗
		WDT_RST();
		if((P3&4)==0)
        {
            aaa++;
            cResult=InterruptReg;
            if(aaa>60000)
            {
                CommandReg=AT_Bit;//中止发送
                _nop_();
		        CommandReg=RRB_Bit|CDO_Bit;//释放接收缓冲区,清除数据超载位
                _nop_();
                InterruptReg=0;//清除中断标志
                _nop_();
                //IE0=0;
            }
        }
        else
        {
            aaa=0;
        }

		//判断是否有CAN事件
		if(IE0==1)
		{//有外部中断0(接收CAN控制器的事件)到来
            //ReadCanID();
            //读取CAN控制器的相关寄存器,并进行处理
            IE0=0;//清除外部中断0的中断标志
            aaa=0;
			cResult=ReadCan();
			if(cResult==5)
			{//修改CAN波特率后,要求系统复位
				InitCan();
			}

		}
		//判断是否有串口事件
		if(RI==1)
		{
			if(SCI_RecCount<SCI_RecLen)
			{//接收未完成
				SCI_RecBuf[SCI_RecCount]=SBUF&0x7F;
                SCI_RecCount++;

			}
			if(SCI_RecCount==SCI_RecLen)
			{//接收完成
				SCI_RecCount=0;
                //bb=0;
				REN=0;//禁止接收
				//ReadCanID();
				//将数据处理成上位机的格式
				//运行状态
				CAN_SendBuf[0]=CAN_SendBuf[1]&0x0F;
				CAN_SendBuf[0]|=CAN_SendBuf[2]<<4;
				//棉层厚度变化
				CAN_SendBuf[1]=CAN_SendBuf[3];
				//CV值
				CAN_SendBuf[2]=CAN_SendBuf[4]&0x0F;
				CAN_SendBuf[2]|=CAN_SendBuf[5]<<4;
				CAN_SendBuf[3]=CAN_SendBuf[6]&0x0F;
				CAN_SendBuf[3]|=CAN_SendBuf[7]<<4;
				//TP1
				CAN_SendBuf[4]=CAN_SendBuf[8]&0x0F;
				CAN_SendBuf[4]|=CAN_SendBuf[9]<<4;
				CAN_SendBuf[5]=CAN_SendBuf[10]&0x0F;
				CAN_SendBuf[5]|=CAN_SendBuf[11]<<4;
				//TP2
				CAN_SendBuf[6]=CAN_SendBuf[12]&0x0F;
				CAN_SendBuf[6]|=CAN_SendBuf[13]<<4;
				CAN_SendBuf[7]=CAN_SendBuf[14]&0x0F;
				CAN_SendBuf[7]|=CAN_SendBuf[15]<<4;
				//TP3
				CAN_SendBuf[8]=CAN_SendBuf[16]&0x0F;
				CAN_SendBuf[8]|=CAN_SendBuf[17]<<4;
				CAN_SendBuf[9]=CAN_SendBuf[18]&0x0F;
				CAN_SendBuf[9]|=CAN_SendBuf[19]<<4;

				CanBlkInd=0;
				SendData_Can(&CanBlkInd);//启动CAN发送数据
			}
			RI=0;//清除串口接收中断标志
		}
		if(TI==1)
		{
			if(SCI_SendCount<SCI_SendLen)
			{//发送未完成
				SBUF=GetEven(SCI_SendBuf[SCI_SendCount]);
			}
			TI=0;//清除串口发送中断标志
			SCI_SendCount++;
		}         //*/
	}
}
void timer0(void) interrupt 1
{
    TH0=FenPinH;
	TL0=FenPinL;
	DoofPulseOut^=1;
    //TH0=0xFD;
	//TL0=0xFD;		//计数个数为256个
	TF0=0;//清除中断标志;
}
void timer1(void) interrupt 3
{
    TH1=FenPinH;
	TL1=FenPinL;	//计数个数为256个
    FeedPulseOut^=1;
	TF1=0;//清除中断标志;
}
//*/

⌨️ 快捷键说明

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