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

📄 candrv.c51

📁 RTX51 example for Intel 82526. it contains example use of CAN.
💻 C51
📖 第 1 页 / 共 2 页
字号:
#pragma large
#pragma debug
#pragma registerbank(3)
#pragma pagelength(80) pagewidth(110)
/***********************************************************************
************************************************************************
*                                                                      *
*  C A N   D R I V E R                                                 *
*                                                                      *
************************************************************************
************************************************************************
*                                                                      *
*  Funktion:                                                           *
*                                                                      *
*     Diese Modul enth刲t den eigentlichen CAN-Task. Der CAN-Task      *
*     乥ernimmt die gesammte Steuerung der CAN-Treiber Software.       *
*     Er reagiert auf Befehle von der Applikation (Signal und Daten    *
*     vom Modul CANAPIF) und auf Interrupts vom CAN-Controller.        *
*     Gestartet wird der CAN-Task vom Modul CANAPIF.                   *
*                                                                      *
*     Beim kompilieren muss ein Makro mit dem Namen I82526 oder        *
*     P82C200 (f乺 den Intel oder Philips Controller) angegeben werden *
*                                                                      *
*                                                                      *
*  Filename           :   CANDRV.C51                                   *
*                                                                      *
*  Modulename         :   CANDRV                                       *
*                                                                      *
*  Zielsystem         :   Jedes 8051 System mit einem Philips          *
*                         82C200 oder Intel 82526 CAN-Controller       *
*                                                                      *
*  Entwicklungssystem :   Keil C-51                                    *
*                                                                      *
************************************************************************
*  Versionen:                                                          *
*                                                                      *
*  0.1  26.10.1990  Th. Fischler : Erste Version                       *
*  1.0   7.12.1990  Th. Fischler : Bus-off Handling eingebaut          *
*        21.1.1991  Th. Fischler : Send-Error Verhalten eingebaut      *
*        14.1.1991  Th. Fischler : Full-CAN eingebaut                  *
*        20.8.1991  Th. Fischler : Beim Basic-CAN wird der Error-INT   *
*                                  nicht mehr benutzt                  *
*  2.0  10.10.1991  Th. Fischler : Version f乺 RTX-51 V4.0             *
*  2.1  24.8.1992   Th. Fischler : Workaround f乺 Signal Mehrfach-     *
*                                  verwendungsproblem                  *
*                                                                      *
*                                                                      *
************************************************************************
*    Copyright 1991 .. 2001 METTLER  &  FUCHS  AG,  CH-8953 Dietikon   *
************************************************************************/

/*---------------------------------------------------------------------*
 *     D E F I N I T I O N E N                                         *
 *---------------------------------------------------------------------*/

/* Debug */
/* #define I82526 */

/* Test ob der CAN-Controller angew刪lt wurde */
#ifndef I82526
   #ifndef P82C200
      #ifndef P80592
         #error "I82526 oder P82C200 oder P80592 muss definiert werden"
      #endif
   #endif
#endif


#include "abbrev.h"
#include "candefs.h"


/* Befehle von der Applikation */
#define CAN_HW_INIT_ORDER       1
#define CAN_DEF_OBJ_ORDER       2
#define CAN_STOP_ORDER          3
#define CAN_START_ORDER         4
#define CAN_SEND_ORDER          5
#define CAN_REQUEST_ORDER       6
#define CAN_BIND_OBJ_ORDER      7
#define CAN_UNBIND_OBJ_ORDER    8
#define CAN_WRITE_ORDER         9
#define CAN_READ_W_IND_ORDER    10
#define CAN_READ_W_TID_ORDER    11
#define CAN_READ_ORDER          12
#define CAN_GET_STATUS_ORDER    13
#define CAN_ACTIVATE_WAIT       14   /* Spezial-Funktion zum Anzeigen,      */
                                     /* das ein Task auf ein Objekt wartet  */


/* Function-Prototypes */
static void c_handle_receive_int (void);
static void c_handle_can_int (void);
static void c_get_back (byte ret_val);
static void c_handle_appli_signal (void);


/*---------------------------------------------------------------------*
 *     I M P O R T S                                                   *
 *---------------------------------------------------------------------*/


/* Verwendeter CAN-Interrupt (definiert in XCANCONF.A51) */
extern const unsigned char code CAN_INT_NBR;

/* RTX-51 Function-Calls */
#include <rtx51.h>

#include "canobja.h"

#ifdef P82C200
   #include "bcancont.h"
#endif
#ifdef I82526
   #include "fcancont.h"
#endif
#ifdef P80592
   #include "ccont592.h"
   #undef P80592
   #define P82C200
#endif





/*---------------------------------------------------------------------*
 *     M O D U L G L O B A L E  V A R I A B L E N                      *
 *---------------------------------------------------------------------*/

   /* Die Applikation erteilt dem CAN-Task 乥er den gemeinsamen        */
   /* Speicherbereich C_ORDER_BUF Befehle. Ueber diesen gemeinsamen    */
   /* Speicherbereich gibt der CAN-Driver ebenfalls Status-Meldungen   */
   /* an die Applikation zur乧k.                                       */
   /* Der C_ORDER_BUF ist im Modul CANAPIF.A51 definiert.              */
   /* Die hier definierte Struktur wird an die selbe Speicherstelle    */
   /* gelegt.                                                          */
   /* ACHTUNG !! : Diese Struktur darf nicht einfach abge刵dert werden */
   /* sie muss mit der Definition im Modul CANAPIF.A51 乥ereinstimmen  */

   extern xdata struct {
                   byte order;
                   byte task_id;
                   byte param[5];
                } c_order_buf;


   /* Ist TRUE falls der CAN-Task gestoppt ist (keine Objekte senden   */
   /* oder empfangen kann) und FALSE falls der CAN-Task l剈ft.         */
   static byte can_stopped;

   /* Z刪lt die Anzahl aufgetretener Overrun-Interrupts vom            */
   /* Philips 82C200 CAN-Controller (f乺 interne Testzwecke)           */
   static unsigned int c_overrun_counter;

   /* Workaround Signal-Problem                                        */
   /* Enth刲t die identifikation aller Tasks an die ein Objekt         */
   /* gebunden ist und an die tats刢hlich mit CAN_WAIT auf das Objekt  */
   /* warten                                                           */
   static struct {
               byte task_id;
               byte task_waits;
            } signal_ok[MAX_BIND_OBJ];


#pragma eject
/*---------------------------------------------------------------------*
 *     L O K A L E   P R O Z E D U R E N                               *
 *---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*
 *     C _ H A N D L E _ R E C E I V E _ I N T
 *---------------------------------------------------------------------*
 *  Funktion:
 *
 *     Steuert den Empfang eines Objektes nach einem Receive-Interrupt
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     --
 *
 *---------------------------------------------------------------------*/

static void c_handle_receive_int (void)
{
   unsigned int stat;
   byte         index, bind, i;

   stat = c_receive_obj ();
   if (stat <= 255) {
      /* Applikation muss benachrichtigt werden */
      index = stat;
      /* testen ob das empfangene Objekt an einen Task gebunden ist */
      bind = c_get_bind (index);
      if (bind != NO_BIND) {
         /* Objekt ist an einen Task gebunden */
         /* Testen ob Task bereit ist */
         for (i=0; i<=MAX_BIND_OBJ-1; i++) {
            if ((signal_ok[i].task_id == bind)
            && (signal_ok[i].task_waits == TRUE)) {
               os_send_signal (bind);
               return;
            }
         }
      }
      else {
         /* Objekt an keinen Task gebunden, an Mailbox senden          */
         /* Die Applikation liest danach mit dem Index die Objektdaten */
         if (os_send_message (7,index,0) == -1) {
            /* Objekt kann von der Applikation nicht empfangen werden */
            c_set_read (index);
         }
      }
   }
   else {
      ;
      /* Ein Objekt wurde empfangen, die Applikation muss aber nicht */
      /* benachrichtigt werden.                                      */
      /* Dieser Fall wurde nur f乺 interne Testzwecke eingef乬t      */
   }
}



/*---------------------------------------------------------------------*
 *     C _ H A N D L E _ C A N _ I N T
 *---------------------------------------------------------------------*
 *  Funktion:
 *
 *     Abhandlung der Aktionen die beim Auftreten eines CAN-Interrupts
 *     ausgef乭rt werden m乻sen.
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     --
 *
 *---------------------------------------------------------------------*/

static void c_handle_can_int (void)
{
   /* Die Informationsdarstellung ist beim Basic- und Full-CAN        */
   /* Controller nach einem Interrupt sehr unterschiedlich.           */
   /* Daher wird die Auswertung der Interrupt-Informationen f乺       */
   /* die beiden Controller getrennt implementiert                    */


   #ifdef P82C200
	  /*==================================================================*/
	  /* NUR FUER Philips 82C200										  */
	  /*==================================================================*/
		 union can_interrupt_typ int_r; /* Interrupt-Bits im CAN-Controller */

		 /* Interrupt Register lesen, um den Grund des Interrupts zu		*/
		 /* eruieren und zum R乧ksetzen des Interrupts						*/
		 int_r.int_byte = c_get_int_reg ();

		 /* Alle m攇lichen Interrupts testen, es k攏nen mehrere 			*/
		 /* gleichzeitig auftreten											*/
		 if (int_r.int_bits.rec_int) {
			/* Receive-Interrupt */
			c_handle_receive_int();
		 }

		 if (int_r.int_bits.overrun_int) {
			/* Overrun-Interrupt */
			c_overrun_counter++;
			c_clr_overrun ();
		 }

	  /*==================================================================*/
	  /*  ENDE Philips 82C200											  */
	  /*==================================================================*/
   #endif


   #ifdef I82526
	  /*==================================================================*/
	  /* NUR FUER Intel 82526											  */
	  /*==================================================================*/
		 enum interrupt_t int_t;		/* 82526 Interrupt Typen */

		 int_t = c_get_int_typ();
		 if (int_t == obj_int) {
			c_handle_receive_int();
			/* Der Interrupt wird von der Empfangsroutine zur乧kgesetzt */
		 }
		 else if (int_t == error_int) {
			/* Das Status-Register muss ausgewertet werden	   */
			/* Es k攏nen mehrere Fehler gleichzeitig auftreten */
            if (c_get_status() == bus_off) {
               /* Applikation mit Index 0 benachrichtigen */
               os_send_message (7,0,0);
			}
			/* Error-Interrupt zur乧ksetzen */
			c_receipt_error_int();
		 }
		 else if (int_t == no_int) {
			/* Der Controller zeigt keinen Interrupt an 	  */
			/* Sollte eigentlich nicht vorkommen			  */
			/* Wird jedoch aus Sicherheitsgr乶den abgefangen  */
			c_receipt_error_int(); /* Interrupt zur乧ksetzen */
		 }
	  /*==================================================================*/
	  /*  ENDE Intel 82526												  */
	  /*==================================================================*/
   #endif
}



#pragma eject
/*---------------------------------------------------------------------*
 *     C _ G E T _ B A C K
 *---------------------------------------------------------------------*
 *  Funktion:
 *
 *     R乧kgabe des Statuswert RET_VAL an die Applikation, starten
 *     der Applikation mit einem Signal
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     ret_val  :  Wert der an die Applikation zur乧kgegeben werden soll
 *
 *---------------------------------------------------------------------*/

static void c_get_back (byte ret_val)
{
   c_order_buf.param[0] = ret_val;
   os_send_signal (c_order_buf.task_id);
}




/*---------------------------------------------------------------------*
 *     C _ H A N D L E _ A P P L I _ S I G N A L
 *---------------------------------------------------------------------*
 *  Funktion:
 *     Ausf乭rung aller Applikationsbefehle
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     --
 *
 *---------------------------------------------------------------------*/

static void c_handle_appli_signal (void)
{
   byte temp, temp2;
   byte done, i;
   unsigned int w_temp;
   /* Hilfsvariable zum separaten ansprechen von High- und Low-Byte  */
   /* in einem Word                                                  */
   union {
      unsigned int tw;
      byte tb[2];
   } qq;

   /* Union um den den Pointer als einzelne Bytes ansprechen zu k攏nen   */
   union {
      struct
      {  byte offs[2];
      } short_ptr;

⌨️ 快捷键说明

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