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

📄 can1.c

📁 this application program demonstrate programming and simulation of the on-chip CAN (controller area
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************
// Module        On-Chip CAN Interface 1 (CAN1)
// Controller    Infineon C167CS/CR or ST10F168
//****************************************************************************

#ifdef C167CS
#include <c167cs.h>  // register definitions for C167CS device
#endif
#ifdef C167CR
#include <REG167.h>  // register definitions for C167CR device
#endif
#ifdef ST10F168      
#include <REG168.h>  // register definitions for ST10 device
#endif
#include <can.h>     // register definitions for on-chip CAN
#include <string.h>
#include <intrins.h>


// Definitions for Interrupt Enable Control Registers
#define  IC_IE(x)    (((x) == 0) ? 0x0000 : 0x0040)
#define  IC_ILVL(x)  (((x) << 2) & 0x003C)
#define  IC_GLVL(x)  ((x) & 0x0003)


/****** C A N   I D   D E F I N I T I O N S  *****************************************/

// Macros for CAN Message Configuration and DLC register
#define  CanTX       0x08      // Transmit
#define  CanRX       0x00      // Receive
#define  CanIDE      0x04      // ID extended (29-bit)

#define  SetDLC(v)   ((unsigned char)((v)<<4))  

// Define Message Object 1 Identifiers (handled in polling mode)
#define  ID1     (CanID29(0x00000100))
#define  ID1MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID1TYP  (CanTX | CanIDE | SetDLC(1))        // Transmit, ID extended (29-bit),
                                                     // 1 Byte message length

// Define Message Object 2 Identifiers (handled in polling mode)
#define  ID2     (CanID29(0x00000101))
#define  ID2MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID2TYP  (CanRX | CanIDE | SetDLC(1))        // Receive, ID extended (29-bit),
                                                     // 1 Byte message length

// Define Message Object 3 Identifiers (handled in interrupt mode)
#define  ID3     (CanID29(0x00000102))
#define  ID3MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID3TYP  (CanTX | CanIDE | SetDLC(8))        // Transmit, ID extended (29-bit),
                                                     // 8 Byte message length
#define  ID3IntChk (C1MOBJ[3].msg_ctl & RXIE_MASK)   // Interrupt Status for Message Object 2

// Define Message Object 4 Identifiers (handled in interrupt mode)
#define  ID4     (CanID29(0x00000103))
#define  ID4MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID4TYP  (CanRX | CanIDE | SetDLC(8))        // Receive, ID extended (29-bit),
                                                     // 8 Byte message length
#define  ID4IntChk (C1MOBJ[4].msg_ctl & TXIE_MASK)   // Interrupt Status for Message Object 3

// Define Message Object 5 Identifiers (remote request sender)
#define  ID5     (CanID29(0x00000104))
#define  ID5MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID5TYP  (CanRX | CanIDE | SetDLC(8))        // Transmit, ID extended (29-bit),
                                                     // 8 Byte message length

// Define Message Object 6 Identifiers (remote frame replier)
#define  ID6     (CanID29(0x00000105))
#define  ID6MSK  (CanID29(0x1FFFFFFF) | CanIDEMSK)
#define  ID6TYP  (CanTX | CanIDE | SetDLC(8))        // Receive, ID extended (29-bit),
                                                     // 8 Byte message length

// IDxTYP table for all used message objects 
unsigned char const id_typ[] =  {
  0,            // dummy element
  ID1TYP,
  ID2TYP,
  ID3TYP,
  ID4TYP,
  ID5TYP,
  ID6TYP,
};

// Set value in Arbitration registers
#define  CanID29(id)((((unsigned long)(id) >> 21) & 0x000000ff) | \
                     (((unsigned long)(id) >>  5) & 0x0000ff00) | \
                     (((unsigned long)(id) << 11) & 0x00ff0000) | \
                     (((unsigned long)(id) << 27)))

#define  CanID11(id) (CanID29((unsigned long)(id) << 18))

#define  CanSetID(val,ch)  C1MOBJ[(ch)].arbitr = (val);
  
// ===== CAN Baudrate Calculation ======================
// Tscl =   (1+BRP)/(2*f_CPU)
// Tbit = 1 + (TSEG1+1) + (TSEG2+1) * Tscl

// Examples:
// 125kHz CAN Baudrate,  f_CPU=10MHz
// TSEG1 = 4, TSEG2 = 3, BRP = 15
// Tscl = 16/10.0 MHz = 0.800 礢ec
// Tbit = (1 + (4+1)+(3+1)) * Tscl = 10 * 0.800uSec = 8 礢ec -> 125kHz Baudrate

// Examples:
// 1MHz CAN Baudrate,  f_CPU=10MHz
// TSEG1 = 6, TSEG2 = 1, BRP = 0
// Tscl = 1/10.0 MHz = 0.100 礢ec
// Tbit = (1 + (1+6)+(1+1)) * Tscl = 10 * 0.100uSec = 1 礢ec -> 1MHz Baudrate

#define BRP    0
#define SJW    0
#define TSEG1  4
#define TSEG2  3

// Clear all bits in Message Control register (MCR)
#define  MCR_CLRALL    (INTPND_CLR & RXIE_CLR   & TXIE_CLR & MSGVAL_CLR & \
                        NEWDAT_CLR & CPUUPD_CLR & TXRQ_CLR & RMTPND_CLR)

// Enable Message Object; clear all other bits in MCR
#define  MCR_ENA       (INTPND_CLR & RXIE_CLR   & TXIE_CLR & MSGVAL_SET & \
                        NEWDAT_CLR & CPUUPD_CLR & TXRQ_CLR & RMTPND_CLR)


// Enable Message Object & Transmit Interrupt; clear all other bits in MCR
#define  MCR_ENA_TXIE  (INTPND_CLR & RXIE_CLR   & TXIE_SET & MSGVAL_SET & \
                        NEWDAT_CLR & CPUUPD_CLR & TXRQ_CLR & RMTPND_CLR)


// Enable Message Object & Receive Interrupt; clear all other bits in MCR
#define  MCR_ENA_RXIE  (INTPND_CLR & RXIE_SET   & TXIE_CLR & MSGVAL_SET & \
                        NEWDAT_CLR & CPUUPD_CLR & TXRQ_CLR & RMTPND_CLR)

/*
 * CAN Initialization:
 *    - reset CAN controller
 *    - initialize CAN message object (ID, MSK, control)
 *    - clear message object status register
 *    - clear unused message object (ID, MSK, control, status)
 *    - enable CAN controller
 */

void CAN1Init (void)  {
  int i;

  _bfld_(DP4,0x0020,0x0000);     // set P4.5 (CAN_RxD) to alternate input
                                 // P4.6 (CAN_TxD) is set to output by hardware

  C1CSR          =  0x0041;                    // set INIT and CCE
                                               // set CAN Baudrate
  C1BTR = (BRP) | (SJW << 6) | (TSEG1 << 8) | (TSEG2 << 12);

  C1GMS          =  0xE0FF;                    // set global mask short register
  C1UGML         =  0xFFFF;                    // set upper global mask long register
  C1LGML         =  0xF8FF;                    // set lower global mask long register 
 
  //  Initialize Message Object 1
  C1MOBJ[1].msg_ctl  =  MCR_ENA;               // set message control register
  C1MOBJ[1].msg_cfg  =  ID1TYP;                // set message configuration register
  CanSetID (ID1, 1);                           // set arbitration register
  
  //  Initialize Message Object 2
  C1MOBJ[2].msg_ctl  =  MCR_ENA;               // set message control register
  C1MOBJ[2].msg_cfg  =  ID2TYP;                // set message configuration register
  CanSetID (ID2, 2);                           // set arbitration register
 
  //  Initialize Message Object 3
  C1MOBJ[3].msg_ctl  =  MCR_ENA_TXIE;          // set message control register
  C1MOBJ[3].msg_cfg  =  ID3TYP;                // set message configuration register
  CanSetID (ID3, 3);                           // set arbitration register
  
  //  Initialize Message Object 4
  C1MOBJ[4].msg_ctl  =  MCR_ENA_RXIE;          // set message control register
  C1MOBJ[4].msg_cfg  =  ID4TYP;                // set message configuration register
  CanSetID (ID4, 4);                           // set marbitration register

  //  Initialize Message Object 5
  C1MOBJ[5].msg_ctl  =  MCR_ENA;               // set message control register
  C1MOBJ[5].msg_cfg  =  ID5TYP;                // set message configuration register
  CanSetID (ID5, 5);                           // set arbitration register

  //  Initialize Message Object 6
  C1MOBJ[6].msg_ctl  =  MCR_ENA;               // set message control register
  C1MOBJ[6].msg_cfg  =  ID6TYP;                // set message configuration register
  CanSetID (ID6, 6);                           // set arbitration register

  //  Disable Message Object 7 .. 15
  for (i = 7; i <= 15; i++)  {
    C1MOBJ[i].msg_ctl =  MCR_CLRALL;           // Disable Message Control register
  } 
#ifdef C167CS
    C1IR  = 0;                                 // required by C167CS to enable outputs
#endif
  // Enable XP0INT (CAN1 Interrupt)
  XP0IC = IC_IE(1) | IC_ILVL(1) | IC_GLVL(1);  // Enable, Interrupt Level 1, Group Level 1

  // Initialize CAN Control/Status Register, Enable Interrupts
  C1CSR = CAN_IE_;                             // Reset CCE & INIT,  Set IE
}


/***** CAN I/O Routines for Polling Mode ******************************************/

/*
 * Can1Send:
 *   Input Parameter:  ch :=  message object channel (1 .. 15)
 *                      p :=  Pointer to data
 *
 *   Return Value:      0     message transferred to buffer, transmission started
 *                     -1     message object not defined for transmission
 *                     -2     previous message not yet transferred
 *               
 *    - check if CAN message object is defined for transmit
 *    - check if a previous message is transmitted OK
 *    - copy new message to message object buffer
 *    - set message object for transmission
 */

int CAN1Send(unsigned int ch, void *p)  {
  unsigned char typ;

// check if CAN message object is defined for transmit
  if (ch >= sizeof (id_typ))       return (-1);
  typ = id_typ[ch];
  if ((typ & DIR_MASK) != CanTX) {
    return (-1);                               // channel is not a transmission channel
  }

  if ((C1MOBJ[ch].msg_ctl & TXRQ_)) {
    return (-2);                               // previous message not yet send!
  }

  memcpy (C1MOBJ[ch].msg, p, (typ >> 4));
  C1MOBJ[ch].msg_ctl = TXRQ_SET & CPUUPD_CLR;  // set TXRQ, reset CPUUPD
  return 0;
}


/*
 * CAN1Read:
 *   Input Parameter:  ch :=  message object channel (1 .. 15)
 *                      p :=  Pointer to data buffer
 *
 *   Return Value:      0     new message read from message data registers
 *                     -1     message object not defined for receiving

⌨️ 快捷键说明

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