lin_main.c

来自「芯科原厂所有c8051fxx程序的例子。」· C语言 代码 · 共 317 行

C
317
字号
// Copyright (c) 2006 SILICON LABORATORIES, INC.
//
// FILE NAME   : LIN_Main.c
// TARGET MCU  : C8051F52xA-53xA
// DESCRIPTION : Main routine for static LIN API
// VERSION     : 1.00
//
// Initializes the device and calls routines to send and receive data across
//    the LIN interface.
//


//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
//
#include <c8051F520.h>
#include "LIN.h"

//-----------------------------------------------------------------------------
//  Global Variables
//-----------------------------------------------------------------------------
//
// These variables are used globally in LIN_Main.c:
//
//    1. LED - This is the LED on Port 1.3. 
//
//    2. SW - This is the switch on Port 1.4.
//
sbit  LED = P1^3;
sbit  SW = P1^4;

//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// main ()
//-----------------------------------------------------------------------------
//
// Initializes the device and intiates LIN operations.
//
void main (void) 
{

   l_u16 i;

#if (LIN_MODE == LIN_MASTER)

   l_u8  sw_state;

#endif

   // Initialize the LIN interface.
   l_sys_init ();

   // Initialize the interface std_ifc.
   l_ifc_init_std_ifc ();

#if (LIN_MODE == LIN_SLAVE)

   // Enable LIN interrupts if in LIN slave mode.
   l_sys_irq_restore (INT_ENABLE_LEVEL);

#endif

#if (LIN_MODE == LIN_MASTER)

   // Set the schedule called normal_schedule.
   l_sch_set_std_ifc (normal_schedule, 0);

#endif

   // Put the port pin connected to the LED (P1^3) in push-pull output mode.
   P1MDOUT |= 0x08;

#if (LIN_MODE == LIN_MASTER)

   // Initialize sw_state to TOGGLE_LED_SLAVE_ID_0.
   sw_state = TOGGLE_LED_SLAVE_ID_0;

   LED = OFF;

   while(1)
   {

      // Check if sw_slave_id_0 has been received.
      if (l_flg_tst_sw_slave_id_0_flag_rx ())
      {
         // Clear sw_slave_id_0_flag_rx.
         l_flg_clr_sw_slave_id_0_flag_rx ();

         // Toggle LED if sw_slave_id_0 is 1.
         if (l_bool_rd_sw_slave_id_0 ())
            LED = ~LED;
      }

      // Check if sw_slave_id_1 has been received.
      if (l_flg_tst_sw_slave_id_1_flag_rx ())
      {
         // Clear sw_slave_id_1_flag_rx.
         l_flg_clr_sw_slave_id_1_flag_rx ();

         // Toggle LED if sw_slave_id_1 is 1.
         if (l_bool_rd_sw_slave_id_1 ())
            LED = ~LED;
      }

      // Check if sw_slave_id_2 has been received.
      if (l_flg_tst_sw_slave_id_2_flag_rx ())
      {
         // Clear sw_slave_id_2_flag_rx.
         l_flg_clr_sw_slave_id_2_flag_rx ();

         // Toggle LED if sw_slave_id_2 is 1.
         if (l_bool_rd_sw_slave_id_2 ())
            LED = ~LED;
      }

      // If the switch goes low, debounce and change the value of the next
      // slave LED in the list.
      // The first time the switch is pressed, led_slave_id_0 will toggle.
      // The second time, led_slave_id_1 will toggle.
      // The third time, led_slave_id_2 will toggle.
      // The fourth time, the state machine will return to led_slave_id_0.
      if (!SW)
      {
         // Debounce
         for (i = 0; i < 0x1000; i++);
         while (!SW);
         for (i = 0; i < 0x1000; i++);

         if (sw_state == TOGGLE_LED_SLAVE_ID_0)
            l_bool_wr_led_slave_id_0 (!(l_bool_rd_led_slave_id_0 ()));
         else if (sw_state == TOGGLE_LED_SLAVE_ID_1)
            l_bool_wr_led_slave_id_1 (!(l_bool_rd_led_slave_id_1 ()));
         else if (sw_state == TOGGLE_LED_SLAVE_ID_2)
            l_bool_wr_led_slave_id_2 (!(l_bool_rd_led_slave_id_2 ()));

         if (sw_state < TOGGLE_LED_SLAVE_ID_2)
            sw_state++;
         else
            sw_state = TOGGLE_LED_SLAVE_ID_0;
      }

   }

#elif (LIN_MODE == LIN_SLAVE)

#if (LIN_SLAVE_ID == LIN_SLAVE_ID_0)

   LED = l_bool_rd_led_slave_id_0 ();

#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_1)

   LED = l_bool_rd_led_slave_id_1 ();

#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_2)

   LED = l_bool_rd_led_slave_id_2 ();

#endif

   while(1)
   {
      // Check if the Go to Sleep command is received.
      if (l_ifc_read_status_std_ifc () & GO_TO_SLEEP)
      {
         // Put the slave device in sleep mode.
         l_slave_go_to_sleep ();
      }

#if (LIN_SLAVE_ID == LIN_SLAVE_ID_0)

      // Check if led_slave_id_0 has changed.
      if (l_flg_tst_led_slave_id_0_flag_rx ())
      {
         // Clear led_slave_id_0_flag_rx.
         l_flg_clr_led_slave_id_0_flag_rx ();

         // Set LED to the value of led_slave_id_0.
         LED = l_bool_rd_led_slave_id_0 ();
      }

      // If the switch goes low, toggle the value of sw_slave_id_0.
      if (!SW)
      {
         // Debounce.
         for (i = 0; i < 0x1000; i++);
         while (!SW);
         for (i = 0; i < 0x1000; i++);

         l_bool_wr_sw_slave_id_0 (ON);

      }

      // If sw_slave_id_0 is 1 and has been transmitted, set it to zero.
      if (l_bool_rd_sw_slave_id_0 () && l_flg_tst_sw_slave_id_0_flag_tx ())
         l_bool_wr_sw_slave_id_0 (OFF);

#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_1)

      // Check if led_slave_id_1 has changed.
      if (l_flg_tst_led_slave_id_1_flag_rx ())
      {
         // Clear led_slave_id_1_flag_rx.
         l_flg_clr_led_slave_id_1_flag_rx ();

         // Set LED to the value of led_slave_id_1.
         LED = l_bool_rd_led_slave_id_1 ();
      }

      // If the switch goes low, toggle the value of sw_slave_id_1.
      if (!SW)
      {
         // Debounce.
         for (i = 0; i < 0x1000; i++);
         while (!SW);
         for (i = 0; i < 0x1000; i++);

         l_bool_wr_sw_slave_id_1 (ON);

      }

      // If sw_slave_id_1 is 1 and has been transmitted, set it to zero.
      if (l_bool_rd_sw_slave_id_1 () && l_flg_tst_sw_slave_id_1_flag_tx ())
         l_bool_wr_sw_slave_id_1 (OFF);

#elif (LIN_SLAVE_ID == LIN_SLAVE_ID_2)

      // Check if led_slave_id_2 has changed.
      if (l_flg_tst_led_slave_id_2_flag_rx ())
      {
         // Clear led_slave_id_2_flag_rx.
         l_flg_clr_led_slave_id_2_flag_rx ();

         // Set LED to the value of led_slave_id_2.
         LED = l_bool_rd_led_slave_id_2 ();
      }

      // If the switch goes low, toggle the value of sw_slave_id_2.
      if (!SW)
      {
         // Debounce.
         for (i = 0; i < 0x1000; i++);
         while (!SW);
         for (i = 0; i < 0x1000; i++);

         l_bool_wr_sw_slave_id_2 (ON);

      }

      // If sw_slave_id_2 is 1 and has been transmitted, set it to zero.
      if (l_bool_rd_sw_slave_id_2 () && l_flg_tst_sw_slave_id_2_flag_tx ())
         l_bool_wr_sw_slave_id_2 (OFF);

#endif

   }

#endif

}

//-----------------------------------------------------------------------------
// l_sys_irq_disable ()
//-----------------------------------------------------------------------------
//
// Disables LIN interrupts. Returns the status of LIN interrupts (IRQ_DISABLE).
//
l_irqmask l_sys_irq_disable (void)
{
   EIE1 &= ~0x20;

   return (INT_DISABLE_LEVEL);
}

//-----------------------------------------------------------------------------
// l_sys_irq_restore ()
//-----------------------------------------------------------------------------
//
// Restores LIN interrupts to a previous state.
//
// Parameters:
//    1. previous - This bit determines whether LIN interrupts are enabled or
//                  disabled (IRQ_ENABLE or IRQ_DISABLE).
//
void l_sys_irq_restore (l_irqmask previous)
{
   if (previous == INT_ENABLE_LEVEL)
      EIE1 |= 0x20;
   else if (previous == INT_DISABLE_LEVEL)
      EIE1 &= ~0x20;
}

#if (LIN_MODE == LIN_MASTER)
//-----------------------------------------------------------------------------
// Timer0_ISR ()
//-----------------------------------------------------------------------------
//
// In Master mode, the device attempts to transmit and receive at the start
//    of every time base tick. Timer0 overflows every SYSTEM_TICK seconds.
//    This defines the base tick length. The master should call
//    l_sch_tick_std_ifc () each time the system tick overflows to send,
//    receive, and schedule frames.
//
void Timer0_ISR (void) interrupt INTERRUPT_TIMER0
{
   // Reload Timer0 to overflow in 5 ms.
   T0 = TIMER0_RELOAD;

   // Perform the system tick task first to minimize jitter.
   l_sch_tick_std_ifc ();

}
#endif

⌨️ 快捷键说明

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