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

📄 fcancont.c51

📁 RTX51 example for Intel 82526. it contains example use of CAN.
💻 C51
📖 第 1 页 / 共 3 页
字号:
#pragma large
#pragma debug
#pragma registerbank(3)
#pragma pagelength(80) pagewidth(110)
/***********************************************************************
************************************************************************
*                                                                      *
*  F U L L - C A N   C O N T R O L L E R                               *
*                                                                      *
************************************************************************
************************************************************************
*                                                                      *
*  Funktion:                                                           *
*                                                                      *
*     Direkte HW-Steuerung des Intel 82526 Full-CAN Controllers.       *
*     Ausf乭rung aller Low-Level Funktionen. Dieses Modul ist das      *
*     einzige, dass direkt in die HW-Register des CAN-Controllers      *
*     schreiben darf.                                                  *
*                                                                      *
*     Die Adressierung der einzelnen Objekte im DPRAM des Controllers  *
*     erscheint im ersten Moment vielleicht ein wenig simpel           *
*     gel攕t. Da bei dieser Implementation jedoch vorallem bez乬lich   *
*     des Laufzeitverhaltens optimiert wurde, liess sich ein gewisses  *
*     Mass an fehlender Eleganz nicht vermeiden.
*                                                                      *
*                                                                      *
*  Filename           :  FCANCONT.C51                                  *
*                                                                      *
*  Modulename         :  FCANCONT                                      *
*                                                                      *
*  Zielsystem         :  jedes 8051 System mit einem Intel 82526       *
*                        CAN-Controller                                *
*                                                                      *
*  Entwicklungssystem :  Keil C-51                                     *
*                                                                      *
************************************************************************
*  Versionen:                                                          *
*                                                                      *
*  1.0  28.01.1991  Th. Fischler : Erste Version                       *
*                                                                      *
************************************************************************
*    Copyright 1991 .. 2001 METTLER  &  FUCHS  AG,  CH-8953 Dietikon   *
************************************************************************/

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

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

/* Maximale Anzahl der Sende-Versuche bei Bus-Problemen */
/* von BCACNCONF.A51                                    */
extern const unsigned int code NBR_OF_SEND_TRIALS;


/* Definition der einzelnen Bits im STATUS-REGISTER    */
/* des CAN-Controllers                                 */
union can_status_typ {
   struct {
      byte reset_request    : 1;
      byte halt_status      : 1;
      byte error_status     : 1;
      byte transmit_status  : 1;
      byte rec_status       : 1;
      byte bus_status       : 1;
      byte dpram_status     : 1;
      byte                  : 1;
   } status_bits;
   byte status_byte;
};



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

#include "canutil.h"


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

   /* Definition der Intel 82526 HW-Register, diese werden an die    */
   /* Speicherstelle des Symbols FCAN_REG im Assembler-Modul         */
   /* FCANCONF.A51 alloziert. (absolute Variable)                    */
   extern xdata volatile union {
                           struct {
                              byte control;
                              byte status;
                              byte intr;
                              byte bus_tim_0;
                              byte bus_tim_1;
                              byte out_contr;
                           } r;           /* Allgemeine Register im DPRAM */
                           byte mem[63];  /* Ganzes DPRAM als Array       */
                        } fcan_reg;



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

/*---------------------------------------------------------------------*
 *     C A N _ R E S E T _ R E Q U E S T
 *---------------------------------------------------------------------*
 *  Funktion:
 *     Setzt den CAN-Controller in den Reset-Zustand
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *     --
 *
 *---------------------------------------------------------------------*/

static void can_reset_request (void)
{
   fcan_reg.r.control = fcan_reg.r.control | 0x01;
   /* Testen ob ein Reset-Request w刪rend dem Betrieb verlangt wurde */
   /* und solange warten, bis Reset-Zustand quittiert wird           */
   while (!(fcan_reg.r.status & 0x01)) {
      /* Falls n攖ig den Interrupt-Pointer zur乧ksetzen */
      if (fcan_reg.r.intr != 0xff) {
         fcan_reg.r.intr = 0xff;
      }
   }
   /* Falls n攖ig den Interrupt-Pointer zur乧ksetzen */
   if (fcan_reg.r.intr != 0xff) {
      fcan_reg.r.intr = 0xff;
   }
}



/*---------------------------------------------------------------------*
 *     C A N _ H A L T _ R E Q U E S T
 *---------------------------------------------------------------------*
 *  Funktion:
 *     Setzt den CAN-Controller in den Halt-Zustand
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *     --
 *
 *---------------------------------------------------------------------*/

static void can_halt_request (void)
{
   /* Status Register testen ob Controller Bus-Off ist */
   if (fcan_reg.r.status & 0x20) {
      /* Controller ist Bus-Off, Halt alleine gen乬t nicht */
      /* Es muss ein Reset ausgel攕t werden                */
      can_reset_request();
   }
   /* Nur Halt-setzen falls nicht schon reset gesetzt ist */
   if (!(fcan_reg.r.status & 0x01)) {
      fcan_reg.r.control = fcan_reg.r.control | 0x02;
      /* Nun Abwarten bis der Haltzustand vom Controller quittiert wird */
      while (!(fcan_reg.r.status & 0x02));
   }
}



/*---------------------------------------------------------------------*
 *     C A N _ S E T _ I M P
 *---------------------------------------------------------------------*
 *  Funktion:
 *     Setzt das IMP-Access-Flag des durch OBJ_ADR adressierten Objektes
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     obj_adr        :  Interne Start-Adresse des Objektes
 *                       (siehe C_INIT_OBJ)
 *
 *---------------------------------------------------------------------*/

static void can_set_imp (byte obj_adr)
{
   fcan_reg.mem[obj_adr] = fcan_reg.mem[obj_adr] | 0x80;
}



/*---------------------------------------------------------------------*
 *     C A N _ C L E A R _ I M P
 *---------------------------------------------------------------------*
 *  Funktion:
 *     L攕cht das IMP-Access-Flag des durch OBJ_ADR adressierten Objektes
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     obj_adr        :  Interne Start-Adresse des Objektes
 *                       (siehe C_INIT_OBJ)
 *
 *---------------------------------------------------------------------*/

static void can_clear_imp (byte obj_adr)
{
   fcan_reg.mem[obj_adr] = fcan_reg.mem[obj_adr] & 0x7f;
}




/*---------------------------------------------------------------------*
 *     C A N _ C H E C K _ W R I T E _ A C C E S S
 *---------------------------------------------------------------------*
 *  Funktion:
 *     Pr乫t ob auf ein Objekt schreibend zugegriffen werden darf
 *     Falls zugegriffen werden darf, ist der IMP-Access nach dieser
 *     Routine gesperrt.
 *
 *---------------------------------------------------------------------*
 *  Parameter:
 *
 *     obj_adr        :  Interne Start-Adresse des Objektes
 *                       (siehe C_INIT_OBJ)
 *
 *     Returnwert     :  TRUE  --> Zugriff ok
 *                       FALSE --> Zugriff verweigert
 *
 *---------------------------------------------------------------------*/

static byte can_check_write_access (byte obj_adr)
{
   unsigned int nbr_of_trials;  /* Anzahl Sendeversuche bis Abbruch */

   nbr_of_trials = 0;
   can_clear_imp (obj_adr);
   if (fcan_reg.mem[obj_adr+2] & 0x80) {
      /* TX-Request = 1, das Objekt ist noch am Senden */
      /* warten bis fertig                             */
      can_set_imp (obj_adr);
      while (fcan_reg.mem[obj_adr+2] & 0x80) {
         /* while TX-Request=1 */
         nbr_of_trials++;
         if (nbr_of_trials > NBR_OF_SEND_TRIALS) {
            /* Vermutlich kein anderer Controller am Bus */
            /* Abbrechen                                 */
            return FALSE;
         }
      }
      nbr_of_trials = 0;
      can_clear_imp (obj_adr);
   }  /* end if */
   /* Das Objekt w剅e bereit zum Senden, pr乫en ob CPU-Access */
   if (!(fcan_reg.mem[obj_adr+1] & 0x01)) {
      /* CPU-Access ist nicht frei */
      if (fcan_reg.mem[obj_adr+1] & 0x02) {
         /* Remote-Frame ist gerade eingetroffen, Controller */
         /* will senden                                      */
         can_set_imp (obj_adr);
      }
      /* Nun warten bis CPU-Access frei ist */
      while (!(fcan_reg.mem[obj_adr+1] & 0x01)) {
         nbr_of_trials++;
         if (nbr_of_trials > NBR_OF_SEND_TRIALS) {
            /* Vermutlich kein anderer Controller am Bus */
            /* Abbrechen                                 */
            return FALSE;
         }
      }
      can_clear_imp (obj_adr);
   }  /* end if */
   return TRUE;
}



#pragma eject
/*---------------------------------------------------------------------*
 *     E X P O R T I E R T E  P R O Z E D U R E N                      *
 *---------------------------------------------------------------------*/

/*---------------------------------------------------------------------*
 *     C _ F I R S T _ I N I T
 *---------------------------------------------------------------------*

⌨️ 快捷键说明

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