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

📄 接收.c

📁 51系列单片机CAN多点通信C语言源代码
💻 C
字号:
#include <c8051f040.h>                       // SFR declarations
#include "can.h"


////////////////////////////////////////////////////////////////////////////////
//Global Variables
////////////////////////////////////////////////////////////////////////////////
char MsgNum;
char status;
char receivedata;
char transmitdata;
int i;
int MOTwoIndex = 0;
int MOOneIndex = 0;
int StatusCopy;
int RXbuffer [4];
int TXbuffer [8];
int MsgIntNum;
int Temperature;
sbit BUTTON = P3^4;
sbit BUTTON1= P3^5;
sbit BUTTON2= P3^6;
sbit BUTTON3= P3^7;
sbit LED = P1^6;


data unsigned char temppage;

////////////////////////////////////////////////////////////////////////////////
// Function PROTOTYPES
////////////////////////////////////////////////////////////////////////////////

// Initialize Message Object

void transmit_data(char MsgNum);
void receive_data (char MsgNum);
void external_osc (void);
void config_IO (void);
 
void delay(int tim);
void uart_init();
void time_init();

void delay(int tim)
{ int i,j;
  for(i=0;i<tim;i++)
  {for(j=0;j<i;j++);}
}
////////////////////////////////////////////////////////////////////////////////
// MAIN Routine
////////////////////////////////////////////////////////////////////////////////
void main (void) {
 
  // disable watchdog timer
  WDTCN = 0xde;
  WDTCN = 0xad;
  	uart_init();
	time_init();

  //configure Port I/O
  config_IO();

  // switch to external oscillator
  external_osc();


////////////////////////////////////////////////////////////////////////////////
// Configure CAN communications
//
// IF1 used for procedures calles by main program
// IF2 used for interrupt service procedure receive_data
//
// Message Object assignments:
//  0x02: Used to transmit commands to toggle its LED, arbitration number 1
//
////////////////////////////////////////////////////////////////////////////////

  // Clear CAN RAM
  clear_msg_objects();

  // Initialize message object to transmit data
  init_msg_object_TX (0x02,2);

  // Initialize message object to receive data
  init_msg_object_RX (0x01,1);

  // Enable CAN interrupts in CIP-51
  EIE2 = 0x20;

  //Function call to start CAN
  start_CAN();

  //Global enable 8051 interrupts
   EA = 1;
   IE=0x90;
  IP=0x00;//uart0中断优先级为低
  EIP2=0x20;//can0中断优先级为高

  while(1);
}


////////////////////////////////////////////////////////////////////////////////
// Set up C8051F040
////////////////////////////////////////////////////////////////////////////////

// Switch to external oscillator
void external_osc (void)
{
  int n;                        // local variable used in delay FOR loop.
  SFRPAGE = CONFIG_PAGE;        // switch to config page to config oscillator
  OSCXCN  = 0x77;               // start external oscillator; 22.1 MHz Crystal
                                // system clock is 22.1 MHz / 2 = 11.05 MHz
  for (n=0;n<255;n++);          // delay about 1ms
  while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
  CLKSEL |= 0x01;               // switch to external oscillator
}

void config_IO (void)
{
  SFRPAGE  = CONFIG_PAGE;        //Port SFR's on Configuration page
  XBR3     = 0x80;     // Configure CAN TX pin (CTX) as push-pull digital output
  P1MDOUT |= 0x40;     // Configure P1.6 as push-pull to drive LED
  XBR2     = 0x40;     // Enable Crossbar/low ports
  XBR0      = 0x04;
  P0MDOUT   = 0X10;
}

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



//Transmit CAN frame to turn other node's LED ON
void transmit_data (char MsgNum)
{
  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
  CAN0DATL = transmitdata;       // Ones signals to turn LED's light ON in data A1 field
  CAN0ADR  = IF1CMDRQST; // Point to Command Request Reg.
  CAN0DATL = MsgNum;     // Move new data for TX to Msg Obj "MsgNum"
}

 


// Receive Data from the IF2 buffer
void receive_data (char MsgNum)
{ //int pass;
  unsigned char receive_data;
   
  SFRPAGE  = CAN0_PAGE; // IF1 already set up for RX

  CAN0ADR  = IF2CMDMSK;
  CAN0DATL = 0x0f; 

  CAN0ADR  = IF2CMDRQST;// Point to Command Request Reg.
  CAN0DATL = MsgNum;    // Move new data for RX from Msg Obj "MsgNum"
                        // Move new data to a
  
//  CAN0ADR=IF2MSGC; //消息接口寄存器2的
//   pass=CAN0DAT;
          
 //  if(pass&0x8000 !=0)						
// {
 CAN0ADR  = IF2DATA1;  // Point to 1st byte of Data Field

  receive_data = CAN0DATL;
     
   
 // if (receive_data == 0x35)   //Ones is signal from other node to turn LED ON
    //LED = 1;
 // else  LED = 0;                //Otherwise turn LED OFF (message was one's)
                                //指示灯亮灭!!
   
   SFRPAGE = UART0_PAGE;
   while(TI0==1); // 等待在串口中断程序那里将其清0
   SBUF0=receive_data;
  
 // }

}

////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routine
////////////////////////////////////////////////////////////////////////////////
void ISRname (void) interrupt 19
{
  unsigned int abcd;
  temppage=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=INTPEND1;
	   abcd=CAN0DAT;
	   if( (abcd&0x01)!=0 )
	     {
           receive_data (0x01);             // 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
    }
  if (((status&0x07) != 0)&&((status&0x07) != 7))
    {                           // Error interrupt, LEC changed
      /* error handling ? */
      CAN0STA = CAN0STA|0x07;              // Set LEC to NoChange
    }

	SFRPAGE=temppage;
}

void SERname (void) interrupt 4//从上位机接收到数据后
{                            //通过can总线发送给采集的开发板
  if(TI0==1)
  {TI0=0;}
  if(RI0==1)
  {   RI0=0;  
     receivedata=SBUF0;
	 LED = ~LED ;
    transmit_data(0x02);
  }
}
//*串口初始化,选择UART1
//**************************************************************************/
void uart_init()
{
    SFRPAGE   = UART0_PAGE;
    SCON0     = 0x50;								   //允许uart1

}
/*************************************************************************
*
*定时器初始化,作为UART0的波特率发生器
*************************************************************************/
void time_init()
{
    SFRPAGE   = TIMER01_PAGE;
    TCON      = 0X40;
	TMOD      = 0x20;
    CKCON     = 0X10;
	TH1       = 0xDC;
	TR1=1;


}

⌨️ 快捷键说明

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