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

📄 main.c

📁 基于c8051f040一个多机通讯程序,开发环境keil
💻 C
📖 第 1 页 / 共 2 页
字号:
				     
			Uart1_SendByte(CAN_Data[pcan++]);	
		    //canlength--;
			if(pcan== 8) 
				{
					able1=0;//保护,防止溢出
					CAN_Data[0]=0;
					CAN_Data[1]=0;
					CAN_Data[2]=0;
					CAN_Data[3]=0;
					CAN_Data[4]=0;
					CAN_Data[5]=0;
					CAN_Data[6]=0;
					CAN_Data[7]=0;
				}
			if(pcan >= 8) pcan=0;//保护,防止溢出
							
        }
	   if(able2)//需要8通道一起传送时收到64字节数据
		{
            //if(pchanl%8 ==0 )
	        //Delay_s(5);	
            {
				for(i=1;i<=64;i++)
				{
					Uart1_SendByte(CAN_Datachannel[pchanl++]);
				}

			}
            //Uart1_SendByte(CAN_Datachannel[pchanl++]);
		    //canlength--;
			if(pchanl == 64) 
				{
					able2=0;//保护,防止溢出
				}
			if(pchanl >= 64) pchanl=0;//保护,防止溢出
							
        }

		if(puart==4)	
		{
			if((nexten==1) && (jjj==1))	
			{
				CAN_trans(0x0A);
			}	
			
		}

		
	}
}

/***********************************************************************************/
// 文件结束
/***********************************************************************************/


////////////////////////////////////////////////////////////////////////////////
//CAN Functions
////////////////////////////////////////////////////////////////////////////////

//Clear Message Objects
void clear_msg_objects (void)
{
  SFRPAGE  = CAN0_PAGE;
  CAN0ADR  = IF1CMDMSK;    // Point to Command Mask Register 1
  CAN0DATL = 0xFF;         // Set direction to WRITE all IF registers to Msg Obj
  for (ii=1;ii<33;ii++)
    {
      CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
      CAN0DATL = ii;
    }
}

//Initialize Message Object for RX
//***********   MsgNum代表消息对象号码,ID代表该消息对象的优先级   **********
void init_msg_object_RX (char MsgNum,ID)
{
  SFRPAGE  = CAN0_PAGE;
  CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
  CAN0DAT  = 0x00B8;     // Set to WRITE, and alter all Msg Obj except ID MASK
                         // and data bits
  CAN0ADR  = IF1ARB1;    // Point to arbitration1 register
  CAN0DAT  = 0x0000;     // Set arbitration1 ID to "0"    因为no extended ID 故仲裁位只有ID28~18有效
							// 即高字的XXX0 0000 0000 00xx中的'0'为11位有效仲裁位,
							// 我们将主机广播的仲裁的消息作为 0 (优先级最高),其余从1开始
  CAN0DAT  = 0x8000+ID*4;     // Arb2 high byte:Set MsgVal bit, no extended ID,
                         // Dir = RECEIVE
							// 因为我们是从机,故接受来自主机的消息处 仲裁应为 0
  CAN0DAT  = 0x0480;     // Msg Cntrl: set RXIE, remote frame function disabled
  CAN0ADR  = IF1CMDRQST; // Point to Command Request reg.
  CAN0DATL = MsgNum;     // Select Msg Obj passed into function parameter list
                         // --initiates write to Msg Obj
  // 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
}

//Initialize Message Object for TX
//***********   MsgNum代表消息对象号码,ID代表该消息对象的优先级   **********
void init_msg_object_TX (char MsgNum,ID)
{
  SFRPAGE = CAN0_PAGE;
  CAN0ADR = IF1CMDMSK;  // Point to Command Mask 1
  CAN0DAT = 0x00B2;     // Set to WRITE, & alter all Msg Obj except ID MASK bits
  CAN0ADR = IF1ARB1;    // Point to arbitration1 register
  CAN0DAT = 0x0000;     // Set arbitration1 ID to highest priority
  CAN0DAT = 0xA000+ID*4;     // Autoincrement to Arb2 high byte:
                        // Set MsgVal bit, no extended ID, Dir = WRITE
							// 因为我们是主机,故发送到从机的广播消息处 仲裁设为 0

  CAN0DAT = 0x0088;     // Msg Cntrl: DLC = 8, remote frame function not enabled****************每帧1字节数据

  CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
  CAN0DAT = MsgNum;     // Select Msg Obj passed into function parameter list
                        // --initiates write to Msg Obj
  // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}

//Start CAN
void start_CAN (void)
{
  /* Calculation of the CAN bit timing :
  System clock        f_sys = 11.0592 MHz/2 = 5.5296 MHz.
  System clock period t_sys = 1/f_sys =180.808449 ns.
  CAN time quantum       tq = t_sys (at BRP = 0)
  */

  SFRPAGE  = CAN0_PAGE;
  CAN0CN  |= 0x41;       // Configuration Change Enable CCE and INIT
  CAN0ADR  = BITREG   ;  // Point to Bit Timing register
  CAN0DAT  = 0x7FFF;     // see above

  CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
  CAN0DAT  = 0x0087;     // Config for TX : WRITE to CAN RAM, write data bytes,
                         // set TXrqst/NewDat, clr IntPnd

  // RX-IF2 operation may interrupt TX-IF1 operation
  CAN0ADR  = IF2CMDMSK;  // Point to Command Mask 2
  CAN0DATL = 0x1F;       // Config for RX : READ CAN RAM, read data bytes,
                         // clr NewDat and IntPnd
  CAN0CN  |= 0x06;       // Global Int. Enable IE and SIE
  CAN0CN  &= ~0x41;      // Clear CCE and INIT bits, starts CAN state machine
}

//指定每帧字节数的CAN传送
void CAN_trans (char MsgNum)
{
  unsigned char i=0;
  unsigned int charnum = 0;
  //unsigned char charh, charl;
 // if(puart<puart1)	charnum=puart+QUENEUART-puart1;
 // else if(puart>puart1) charnum=puart-puart1;
 // else return;
 // if(charnum>=8) charnum=8;				//charnum即待传送字节(<=8)的确认

//固定每帧8字节,不足填充0xFF的情况
  SFRPAGE  = CAN0_PAGE;  // IF1 already set up for TX
  CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
  CAN0DAT  = 0x0087;     // Config to WRITE to CAN RAM, write data bytes,
                         // set TXrqst/NewDat, Clr IntPnd
  CAN0ADR  = IF1DATA1;   // Point to 1st byte of Data Field
  for(i=1;i<=4;i++)
  {		if(i%2)	
  			CAN0DATH=UART_Data[puart1++];
		else	
			CAN0DATL=UART_Data[puart1++];	
		if(puart1>=4)	puart1=0;	
  }
   puart=0;

//  for(;i<=8;i++)
//  {  	if(i%2)	CAN0DATH=0xFF;
//  		CAN0DATL=0xFF;					}

  nexten=0;					//本消息要发送,后面的数据要等我的TxOK中断信号
  UART_Data[0]=0;
  UART_Data[1]=0;
  UART_Data[2]=0;
  UART_Data[3]=7;
  jjj=0;
  CAN0ADR	= IF1CMDRQST;
  CAN0DATL	= MsgNum;
}



// Receive Data from the IF2 buffer
void receive_data (char MsgNum)
{

  unsigned char i=1, recdata=0xFF;

  char SFRPAGE_SAVE = SFRPAGE;        // Save SFRPAGE
//每帧8字节,多余补充0xFF的情况
  SFRPAGE  = CAN0_PAGE; // IF1 already set up for RX
  CAN0ADR  = IF2CMDMSK;
  CAN0DAT  = 0x000F;
  CAN0ADR  = IF2CMDRQST;// Point to Command Request Reg.
  CAN0DATL = MsgNum;    // Move new data for RX from Msg Obj "MsgNum"
  CAN0ADR=IF2DATA1;
  
  for(i=1;i<=8;i++)
  {
  	if(i%2) recdata=CAN0DATH;
	else recdata=CAN0DATL;
	LED	= ~LED;
	if(channelable == 0)
	{
		if(pcan <= 7)
    		{
				CAN_Data[pcan++]=recdata;
	//	    	canlength++;
			}
     
  	    if(pcan == 8) 
	    {
		    pcan=0;
	   	    able1=1;//收到8字节时允许发送数据
	    }
	 }
	 if(channelable == 1) 
	 {
	 	if(pchanh<=63)
		{
			CAN_Datachannel[pchanh++]=recdata;

		}
		if(pchanh == 64)
	    {
			pchanh=0;
			able2=1;//收到64字节时允许发送数据
		}
	 }
     
  }

  
 SFRPAGE = SFRPAGE_SAVE;
}

////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routine
////////////////////////////////////////////////////////////////////////////////
void ISRcan (void) interrupt 19
{
  char data MsgNum;
  char SFRPAGE_SAVE = SFRPAGE;        // Save SFRPAGE
  SFRPAGE  = CAN0_PAGE;
  status = CAN0STA;
  if ((status&0x10) != 0)
    {                     // RxOk is set, interrupt caused by reception
      CAN0STA = (CAN0STA&0xEF)|0x07;         // Reset RxOk, set LEC to NoChange
      /* read message number from CAN INTREG */
	  CAN0ADR = INTREG;
	  MsgNum = CAN0DATL;
      receive_data (MsgNum);             // Up to now, we have only one RX message
    }
  if ((status&0x08) != 0)
    {                       // TxOk is set, interrupt caused by transmision
      CAN0STA = (CAN0STA&0xF7)|0x07;        // Reset TxOk, set LEC to NoChange
	  //CAN_trans (0x0A);
	  nexten=1;
    }
  if (((status&0x07) != 0)&&((status&0x07) != 7))
    {                           // Error interrupt, LEC changed
      /* error handling ? */
      CAN0STA = CAN0STA|0x07;              // Set LEC to NoChange
    }
  //if((status&0x07)==7)  		CAN0STA=0;
  SFRPAGE = SFRPAGE_SAVE;
}

⌨️ 快捷键说明

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