//###########################################################################
// FILE: can_external_transmit.c
// TITLE: Example to demonstrate CAN external transmission
//
//! \addtogroup cpu01_example_list
//! <h1>CAN-A External Transmit (can_external_transmit)</h1>
//!
//! This example initializes CAN module A for external communication.
//! CAN-A module is setup to trigger an interrupt service routine (ISR) when
//! data is received. Then transmit received data.
//!
//! \note CAN modules on the device need to be
//! connected to external CAN transceivers.
//!
//! \b External \b Connections \n
//! - CANA is on GPIO37 (CANTXA) and GPIO36 (CANRXA)
//!
//! \b Watch \b Variables \n
//! - txMsgCount - A counter for the number of messages sent
//! - rxMsgCount - A counter for the number of messages received
//! - txMsgData - An array with the data being sent
//! - rxMsgData - An array with the data that was received
//! - errorFlag - A flag that indicates an error has occurred
//!
//
//###########################################################################
// $TI Release: F2837xD Support Library v190 $
// $Release Date: Mon Feb 1 16:51:57 CST 2016 $
// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h" // Device Headerfile and Examples Include File
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_can.h"
#include "driverlib/can.h"
//
// Defines
//
#define MSG_DATA_LENGTH 8
#define TX_MSG_OBJ_ID 1
#define RX_MSG_OBJ_ID 2
//
// Globals
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
unsigned char txMsgData[MSG_DATA_LENGTH];
unsigned char rxMsgData[MSG_DATA_LENGTH];
tCANMsgObject sTXCANMessage;
tCANMsgObject sRXCANMessage;
//
// Function Prototypes
//
__interrupt void canaISR(void);
//
// Main
//
void main(void)
{
//
// Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
//
InitSysCtrl();
//
// Initialize GPIO and configure GPIO pins for CANTX/CANRX
// on module A
//
InitGpio();
//
// Setup GPIO pin mux for CAN-A TX/RX and CAN-B TX/RX
//
//GPIO36 - CANRXA
GPIO_SetupPinMux(36, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(36, GPIO_INPUT, GPIO_ASYNC);
//GPIO37 - CANTXA
GPIO_SetupPinMux(37, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(37, GPIO_OUTPUT, GPIO_PUSHPULL);
//
// Initialize the CAN controllers
//
CANInit(CANA_BASE);
//
// Setup CAN to be clocked off the PLL output clock
//
CANClkSourceSelect(CANA_BASE, 0); /* 500kHz CAN-Clock */
//
// Set up the CAN bus bit rate to 500kHz for each module
// This function sets up the CAN bus timing for a nominal configuration.
// You can achieve more control over the CAN bus timing by using the
// function CANBitTimingSet() instead of this one, if needed.
// Additionally, consult the device data sheet for more information about
// the CAN module clocking.
//
CANBitRateSet(CANA_BASE, 200000000, 500000);
//
// Enable interrupts on the CAN B peripheral.
//
CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
//
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
DINT;
//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
//
InitPieCtrl();
//
// Disable CPU interrupts and clear all CPU interrupt flags
//
IER = 0x0000;
IFR = 0x0000;
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
//
InitPieVectTable();
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// This registers the interrupt handler in PIE vector table.
//
EALLOW;
PieVectTable.CANA0_INT = canaISR;
EDIS;
//
// Enable the CAN-A interrupt on the processor (PIE).
//
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
IER |= M_INT9;
EINT;
//
// Enable the CAN-B interrupt signal
//
CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);
//
// Initialize the transmit message object used for sending CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: None
// Message Data Length: 4 Bytes
// Message Transmit data: txMsgData
//
sTXCANMessage.ui32MsgID = 0x5555;
sTXCANMessage.ui32MsgIDMask = 0;
sTXCANMessage.ui32Flags = 0;
sTXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sTXCANMessage.pucMsgData = txMsgData;
//
// Initialize the receive message object used for receiving CAN messages.
// Message Object Parameters:
// Message Identifier: 0x5555
// Message ID Mask: 0x0
// Message Object Flags: Receive Interrupt
// Message Data Length: 4 Bytes
// Message Receive data: rxMsgData
//
sRXCANMessage.ui32MsgID = 0x5555;
sRXCANMessage.ui32MsgIDMask = 0;
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;
sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
sRXCANMessage.pucMsgData = rxMsgData;
CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage,
MSG_OBJ_TYPE_RX);
//
// Start CAN module A and B operations
//
CANEnable(CANA_BASE);
//
// Transmit messages from CAN-A
//
for(;;)
{
//
// Check the error flag to see if errors occurred then stop application
//
if(errorFlag)
{
asm(" ESTOP0");
}
} // end of for(;;)
} // end of main
//
// CAN A ISR - The interrupt service routine called when a CAN interrupt is
// triggered on CAN module A.
//
__interrupt void
canaISR(void)
{
uint32_t status;
//
// Read the CAN-A interrupt status to find the cause of the interrupt
//
status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);
//
// If the cause is a controller status interrupt, then get the status
//
if(status == CAN_INT_INT0ID_STATUS)
{
//
// Read the controller status. This will return a field of status
// error bits that can indicate various errors. Error processing
// is not done in this example for simplicity. Refer to the
// API documentation for details about the error status bits.
// The act of reading this status will clear the interrupt.
//
status = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);
//
// Check to see if an error occurred.
//
if(((status & ~(CAN_ES_RXOK)) != 8) &&
((status & ~(CAN_ES_RXOK)) != 7) &&
((status & ~(CAN_ES_RXOK)) != 0))
{
//
// Set a flag to indicate some errors may have occurred.
//
errorFlag = 1;
}
}
//
// Check if the cause is the CAN-A receive message object 2
//
else if(status == RX_MSG_OBJ_ID)
{
//
// Get the received message
//
CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);
//
// Set the received message
//
for(i
评论4