📄 f50x_lin_master.c
字号:
//-----------------------------------------------------------------------------
// F50x_LIN_Master.c
//-----------------------------------------------------------------------------
// Copyright 2008 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
// This program's purpose is to communicate between the A and B sides of the
// C8051F50x target board through the Local Interconnect Network (LIN).
//
// Pressing the P1.4_A switch will trigger the P1.3_B LED to light up.
// Releasing the P1.4_A switch will turn off the P1.3_B LED.
// Alternatively, pressing the P1.4_B switch will turn on the P1.3_A LED
// while releasing the P1.4_B switch will turn off the P1.3_A LED.
//
// This example is intended to be used with the LIN_Slave example.
//
// How To Test:
//
// 1) Verify the LED and switch pin jumpers are populated
// (J19 for device A and J11 for device B).
//
// 2) Make sure the LIN jumpers in J17 (for A side) and J26 (for B side)
// are connected.
//
// 3) If you wish to change the baud rate of the LIN, change the following
// global constant: LIN_BAUD_RATE
//
// 3) Download the code to a F50x-TB (either device A or device B) that is
// connected as above to another device running the LIN0_Slave code.
//
// 4) Run the code.
//
// 5) If the communication passes, when a switch on a side of the target board
// is pressed, the LED on the opposite side will light up. When said switch
// is released, the LED will turn off.
//
// Target: C8051F50x (C8051F500 TB)
// Tool chain: Keil C51 8 / Keil EVAL C51
// Command Line: None
//
// Revision History:
//
// Release 1.0 / 09 JUNE 2008 (ADT)
// -Initial Revision
//
// Obs1: When the master sends a request frame, the ID sent from the master
// is the same as the ID read by the master after a slave transmit frame,
// even if the slave tries to edit the ID before transmitting.
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F500_defs.h>
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
SBIT (SW1, P1, 4); // SW1 = '0' means switch pressed
SBIT (LED, P1, 3); // LED = '1' means LED on
#define SYSCLK 24000000 // Clock speed in Hz
#if (SYSCLK < 8000000) // For the slowest baud rate
#error Minimum system clock needed to operate LIN peripheral is 8Mhz.
#endif
#define TWENTY_MS (U16)((.02/(1.0/SYSCLK)) / 12.0) // Clock cycles for 20ms
#define LIN_BAUD_RATE 10000 // Baud Rate to run LIN peripheral
// 625 < LIN_BAUD_RATE < 20000
//-----------------------------------------------------------------------------
// LIN #defines
//-----------------------------------------------------------------------------
//------ Control register ------
#define STREQ 0x01 // LIN Master Start transmission request
#define WUPREQ 0x02 // Wake-Up request
#define RSTERR 0x04 // Error reset request
#define RSTINT 0x08 // Interrupt reset request
#define DTACK 0x10 // Slave Data ACK
#define TXRX 0x20 // Master selection of TX or RX mode
#define SLEEP 0x40 // Slave flag set by master to inform
// the peripheral that either a sleep
// mode frame or bus idle timeout
// was reached
#define STOP 0x80 // Slave flag, to be set by the
// application so no processing is to be
// done until next SYNCH BREAK
//------ Status Register ------
#define DONE 0x01 // Msg. processing completed
#define WAKEUP 0x02 // Wake-Up signal
#define ERROR 0x04 // Error detected
#define LININTREQ 0x08 // Interrupt request
#define DTREQ 0x10 // ID detected
#define ABORT 0x20 // Abort requested
#define IDLTOUT 0x40 // Time-out detected
#define ACTIVE 0x80 // Interface active (communicating)
#define LIN_MULTIPLIER (U8)((20000.0 / LIN_BAUD_RATE) - 1)
#if (SYSCLK >= 16000000)
#define LIN_PRESCALAR 1
#define LIN_DIVIDER (SYSCLK / (4 * (LIN_MULTIPLIER + 1) * LIN_BAUD_RATE))
#else
#define LIN_PRESCALAR 0
#define LIN_DIVIDER (SYSCLK / (2 * (LIN_MULTIPLIER + 1) * LIN_BAUD_RATE))
#endif
// Instruction Set
#define ID_SW1_SLAVE_QUERY 0x01
#define ID_LED_SLAVE 0x02 //LED on the slave side
#define ID_LED_SLAVE_OFF 0x02
#define ID_LED_SLAVE_ON 0x03
#define LED_MASTER_OFF 0x04
#define LED_MASTER_ON 0x05
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
UU16 Next_Interrupt_Time; // Contains the next interrupt time that
// PCA module 2 will try to match
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void Oscillator_Init (void); // Configure the system clock
void Port_Init (void); // Configure the Crossbar and GPIO
void PCA0_Init (void); // Configure the PCA
void LIN0_Master_Init (void); // Configure LIN for master
INTERRUPT_PROTO (PCA0_ISR, INTERRUPT_PCA0);
INTERRUPT_PROTO (LIN0_ISR, INTERRUPT_LIN0);
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
SFRPAGE = ACTIVE_PAGE;
PCA0MD &= ~0x40; // Disable Watchdog timer
Oscillator_Init (); // Initialize the system clock
Port_Init (); // Initialize crossbar and GPIO
PCA0_Init (); // Initialize PCA0
LIN0_Master_Init (); // Initialize LIN0
EA = 1; // Enable Interrupts
LED = 0; // Initialize LED to be off
while (1);
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value: None
// Parameters: None
//
// Module 2 is configured as a match interrupt to be used as a periodic
// interrupt every 20 ms.
//-----------------------------------------------------------------------------
void PCA0_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = ACTIVE_PAGE;
// Configure PCA time base; overflow interrupt disabled
PCA0CN = 0x00; // Stop counter; clear all flags
PCA0MD = 0x00; // Use SYSCLK / 12 as time base
PCA0CPM2 = 0x49; // Configure PCA0 module 2 to interrupt
// periodically
PCA0L = 0x00; // Set PCA0 counter to 0
PCA0H = 0x00;
// Initialize PCA0 module 2 to interrupt in 20 ms
Next_Interrupt_Time.U16 = TWENTY_MS;
PCA0CPL2 = Next_Interrupt_Time.U8[LSB];
PCA0CPH2 = Next_Interrupt_Time.U8[MSB];
EIE1 |= 0x08; // Enable PCA interrupts
CR = 1; // Start PCA counter
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value: None
// Parameters: None
//
// Configure the internal oscillator to maximum internal frequency of 24 Mhz
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
OSCICN = 0x87;
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// Port_Init *EDIT THIS SECTION*
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
// P0.0 - Skipped, Open-Drain, Digital
// P0.1 - Skipped, Open-Drain, Digital
// P0.2 - Skipped, Open-Drain, Digital
// P0.3 - Skipped, Open-Drain, Digital
// P0.4 - Skipped, Open-Drain, Digital
// P0.5 - Skipped, Open-Drain, Digital
// P0.6 - Skipped, Open-Drain, Digital
// P0.7 - Skipped, Open-Drain, Digital
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -