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

📄 f50x_lin_master.c

📁 C8051F500开发编程:MCU全部资源应用实例
💻 C
📖 第 1 页 / 共 2 页
字号:
// P1.0  -  TX    (LIN), Push-Pull,  Digital
// P1.1  -  RX    (LIN), Open-Drain, Digital
// P1.2  -  Unassigned,  Open-Drain, Digital
// P1.3  -  LED,         Push-Pull,  Digital
// P1.4  -  SW1,         Open-Drain, Digital
// P1.5  -  Unassigned,  Open-Drain, Digital
// P1.6  -  Unassigned,  Open-Drain, Digital
// P1.7  -  Unassigned,  Open-Drain, Digital
//
//-----------------------------------------------------------------------------
void Port_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;

   P1MDOUT   = 0x09;                   // Set P1.0 to push-pull
                                       // Set P1.1 to open-drain
                                       // Set P1.3 to push-pull
                                       // Set P1.4 to open-drain

   P0SKIP    = 0xFF;                   // Skip to place LIN on 1.0 and 1.1             

   XBR2      = 0x41;                   // Enable LIN, crossbar and weak pullups

   SFRPAGE = SFRPAGE_save;
}


//-----------------------------------------------------------------------------
// LIN0_Master_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Intializes the LIN peripheral to master mode.
//
// LIN is an asynchronous, serial communications interface. All LIN registers
// besides the control mode register (LIN0CF) are indirectly accessed; 
// the address is specified in the LINADDR register which points to a specific
// data register which can be accessed through the LINDATA register. 
// Waveforms and additional specifications can be found in the LIN consortium
// (http:\\www.lin-subbus.com). 
//-----------------------------------------------------------------------------

void LIN0_Master_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;
   
   // Enable interface, configure the device for LIN Master, manual baud rate
   LIN0CF = 0x80;
   LIN0CF |= 0x40;
   
   SFRPAGE = ACTIVE_PAGE;
   // Load the least significant byte of the divider.
   LIN0ADR = LIN0DIV;
   LIN0DAT = (U8) LIN_DIVIDER;

   // Load the multiplier, prescalar, and most significant bit of the divider.
   LIN0ADR = LIN0MUL;
   LIN0DAT = (U8) ((LIN_PRESCALAR << 6) | (LIN_MULTIPLIER << 1) 
               | (LIN_DIVIDER >> 8));

   LIN0ADR = LIN0SIZE;
   LIN0DAT = 0x80;                     // Enhanced checksum

   LIN0ADR = LIN0CTRL;
   LIN0DAT = 0x0C;                     // Reset LININT and LIN0ERR

   EIE1 |= 0x80;                       // Enable  LIN interrupts

   SFRPAGE = SFRPAGE_save;

}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PCA0_ISR
//-----------------------------------------------------------------------------
//
// This is the ISR for the PCA0. Module 2 will send a LIN transmit or request 
// frame every 20ms to the slave. If there is a falling edge on the master 
// switch, meaning that the switch was just pressed, send a LED on transfer.
// If there is a rising edige on the master switch, meaning that the switch
// was just released, send a LED off transfer. If the switch was in the same 
// state as it was previously, meaning that the switch is either not pressed
// or is being held down, send a request frame to retreive the status of the
// slave switch.
//
//-----------------------------------------------------------------------------

INTERRUPT (PCA0_ISR, INTERRUPT_PCA0)
{
   static U8 sw1prev = 0;              // Status of the switch during the last 
                                       // interrupt
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = ACTIVE_PAGE;
   
   if (CCF2)
   {
      CCF2 = 0;                        // Clear other interrupt flags for PCA

      // Interrupt every 20 ms
      Next_Interrupt_Time.U16 = Next_Interrupt_Time.U16 + TWENTY_MS;

      PCA0CPL2 = Next_Interrupt_Time.U8[LSB];   
      PCA0CPH2 = Next_Interrupt_Time.U8[MSB];

      if ((sw1prev == 0) && (SW1 == 1))
      {
         // Button was down and switch is now off = rising edge
         // Turn off LED
         LIN0ADR = LIN0CTRL;           
         LIN0DAT |= TXRX;              // Select to transmit data

         LIN0ADR = LIN0ID;
         LIN0DAT = ID_LED_SLAVE_OFF;   // Tell slave to turn off LED

         LIN0ADR = LIN0SIZE;
         LIN0DAT = (LIN0DAT & 0xF0) | 0x00;   // Transmitting 0 byte

         LIN0ADR = LIN0CTRL;
         LIN0DAT |= STREQ;             // Start Request
      }
      else if ((sw1prev == 1) && (SW1 == 0))
      {
         // Button was up and switch is now pressed = falling edge
         // Turn on LED
         LIN0ADR = LIN0CTRL;           
         LIN0DAT |= TXRX;              // Select to transmit data

         LIN0ADR = LIN0ID;
         LIN0DAT = ID_LED_SLAVE_ON;    // Tell slave to turn on LED

         LIN0ADR = LIN0SIZE;
         LIN0DAT = (LIN0DAT & 0xF0) | 0x00;   // Transmitting 0 byte

         LIN0ADR = LIN0CTRL;
         LIN0DAT |= STREQ;             // Start Request
      }
      else if ((sw1prev == SW1))
      {
         // Same state as last state, covers 00 and 11
         // Poll slave switch
         LIN0ADR = LIN0CTRL;
         LIN0DAT &= ~TXRX;             // Create a master receive operation

         LIN0ADR = LIN0ID;
         LIN0DAT = ID_SW1_SLAVE_QUERY; // Want to know status of slave switch
      
         LIN0ADR = LIN0SIZE;
         LIN0DAT = (LIN0DAT & 0xF0) | 0x01;   // Transmitting 1 byte

         LIN0ADR = LIN0CTRL;
         LIN0DAT |= STREQ;             // Start Request
      }

   }
   else
   {
      PCA0CN &= ~0xBB;                 // Clear other PCA interrupt flags
   }
   
   sw1prev = SW1;                      // Save value of switch
   SFRPAGE = SFRPAGE_save;
}

//-----------------------------------------------------------------------------
// LIN0_ISR
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This ISR triggers when completing/receiving a transmission from the slave. 
// Depending on what message is sent, LED (P1.3) on the slave will turn on/off.
// When receiving a transmission from the slave, the information in data byte
// 1 will tell the master the state of the switch on the slave side. The master
// will then toggle the LED (P1.3) on the master side accordingly.
//
//-----------------------------------------------------------------------------

INTERRUPT (LIN0_ISR, INTERRUPT_LIN0)
{
   U8 ctrl, ID, command, status, error;
   static U8 num_error = 0;
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = ACTIVE_PAGE;
   
   LIN0ADR = LIN0ST;                   // Retrieve status
   status = LIN0DAT;

   LIN0ADR = LIN0CTRL;
   ctrl = LIN0DAT;

   LIN0ADR = LIN0ID;
   ID = LIN0DAT;

   if (status & LININTREQ)
   {
      if (status & ERROR)              // If an error was detected
      {
         LIN0ADR = LIN0ERR;
         error = LIN0DAT;              // Check the error register
         // Keep track of the number of errors received
         num_error++;
         // Handle your errors here, application dependent
      }
      else if(status & DONE)           // If transmission/reception completed
      {
         // If in recieve mode and ID is correct
         if (((ctrl & TXRX) == 0) && (ID == ID_SW1_SLAVE_QUERY))
         {
            LIN0ADR = LIN0DT1;
            command = LIN0DAT;         // Get info from transmission

            if (command == LED_MASTER_ON)
             {
                LED = 1;
             }
            if (command == LED_MASTER_OFF)
            {
                LED = 0;
            }
         }
      }
   }

   LIN0ADR = LIN0CTRL;
   LIN0DAT |= 0x0C;                    // Reset LININT and LIN0ERR

   SFRPAGE = SFRPAGE_save;
      
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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