📄 hcancont.c51
字号:
#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 Siemens 81C90 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. *
* *
* *
* Filename : HCANCONT.C51 *
* *
* Modulename : HCANCONT *
* *
* Zielsystem : jedes 8051 System mit einem Siemens 81C90 *
* CAN-Controller *
* *
* Entwicklungssystem : Keil C-51 *
* *
*************************************************************************
* Versionen: *
* *
* 1.0 21.03.1995 K. Birsen : Erste Version *
* 1.1 06.06.1997 K. Birsen : Aenderung in c_read_obj : dummy read *
* 7. Data *
* *
*************************************************************************
* 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 "hcancont.h"
#include "candefs.h"
/* Maximale Anzahl der verschiedenen Versuche */
/* von HCACNCONF.A51 */
extern const unsigned int code NBR_OF_SEND_TRIALS;
/* Definition der einzelnen Register-Bits des CAN-Controllers */
typedef struct {
byte enable_receive_interrupt : 1; /* rw 0 */
byte enable_transmit_interrupt : 1; /* rw 0 */
byte enable_warnig_level_interrupt : 1; /* rw 0 */
byte enable_remote_frame_interrupt : 1; /* rw 0 */
byte enable_wake_up_interrupt : 1; /* rw 0 */
byte enable_buss_off_interrupt : 1; /* rw 0 */
byte enable_error_passive_interrupt : 1; /* rw 0 */
byte enable_tr_check_interrupt : 1; /* rw 0 */
} interrupt_mask_type;
typedef struct {
byte init_mode : 1; /* rw 0 */
byte reset_request : 1; /* rw 0 */
byte bus_state : 1; /* r 0 */
byte receiver_warning_level : 1; /* r 0 */
byte transmit_warning_level : 1; /* r 0 */
byte transmission_complete : 1; /* r 0 */
byte receive_state : 1; /* r 0 */
byte auto_decrement_enable : 1; /* rw 0 */
} mod_status_type;
typedef struct {
byte receive_interrupt : 1; /* rw 0 */
byte transmit_interrupt : 1; /* rw 0 */
byte warnig_level_interrupt : 1; /* rw 0 */
byte remote_frame_interrupt : 1; /* rw 0 */
byte wakeup_interrupt : 1; /* rw 0 */
byte buss_off_interrupt : 1; /* rw 0 */
byte error_passive_interrupt : 1; /* rw 0 */
byte tr_check_interrupt : 1; /* rw 0 */
} interrupt_type;
typedef struct {
byte monitor_mode : 1; /* rw 0 */
byte tr_check_enable : 1; /* rw 0 */
byte sleep_mode_enable : 1; /* rw 0 */
byte time_stamp_overflow : 1; /* rw 0 */
byte time_stamp_prescaler : 2; /* rw 0 */
byte time_stamp_test : 1; /* rw 0 */
byte input_monitor_rx : 1; /* rw 0 */
} control_type;
typedef struct {
byte cc : 4; /* w 1 */
byte not_used_3 : 4; /* */
} clock_control_type;
typedef struct {
byte tcec : 3; /* rw 0 */
byte not_used_4 : 5; /* */
} tr_check_error_counter_type;
typedef struct {
unsigned int dlc : 4; /* rw x */
unsigned int rtr : 1; /* rw x */
unsigned int id : 11; /* rw x */
} descriptor_type;
/* Message type */
typedef struct {
byte datas[8];
} message_type;
/*---------------------------------------------------------------------*
* 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 Siemens 81C90 HW-Register, diese werden an die */
/* Speicherstelle des Symbols FCAN_REG im Assembler-Modul */
/* GCANCONF.A51 alloziert. (absolute Variable) */
extern xdata volatile union
{
struct{
/* 00H */ byte bit_length_1;
/* 01H */ byte bit_length_2;
/* 02H */ byte output_control;
/* 03H */ byte baud_rate_prescaler;
/* 04H */ unsigned int receive_ready;
/* 06H */ unsigned int receive_interrupt_mask;
/* 08H */ unsigned int transmit_request_set;
/* 0AH */ interrupt_mask_type interrupt_mask;
/* 0BH */ byte not_used_5[5];
/* 0CH */
/* 0DH */
/* 0EH */
/* 0FH */
/* 10H */ mod_status_type mod_status;
/* 11H */ interrupt_type interrupt_reg;
/* 12H */ control_type control;
/* 13H */ byte not_used_6;
/* 14H */ clock_control_type clock_control;
/* 15H */ tr_check_error_counter_type tr_check_error_counter;
/* 16H */ byte tr_check_data;
/* 17H */ byte not_used_7;
/* 18H */ unsigned int transmit_request_reset;
/* 1AH */ unsigned int remote_request_pending;
/* 1CH */ unsigned int time_stamp_counter;
/* 1DH */
/* 1EH */ byte not_used_8[10];
/* 1FH */
/* 20H */
/* 21H */
/* 22H */
/* 23H */
/* 24H */
/* 25H */
/* 26H */
/* 27H */
/* 28H */ byte port_director_0;
/* 29H */ byte port_pin_0;
/* 2AH */ byte port_latch_0;
/* 2BH */ byte not_used_9;
/* 2CH */ byte port_director_1;
/* 2DH */ byte port_pin_1;
/* 2EH */ byte port_latch_1;
/* 2FH */ byte not_used_10;
/* 30H */ unsigned int time_stamp[8];
/* 40H */ descriptor_type descriptor[16];
/* 60H */ byte not_used_11[32];
/* 61H *//* 62H *//* 63H */
/* 64H *//* 65H *//* 66H *//* 67H */
/* 68H *//* 69H *//* 6AH *//* 6BH */
/* 6CH *//* 6DH *//* 6EH *//* 6FH */
/* 70H *//* 71H *//* 72H *//* 73H */
/* 74H *//* 75H *//* 76H *//* 77H */
/* 78H *//* 79H *//* 7AH *//* 7BH */
/* 7CH *//* 7DH *//* 7EH *//* 7FH */
/* 80H */ message_type message[16];
} r;
byte mem[256];
} fcan_reg;
#pragma eject
/*---------------------------------------------------------------------*
* L O K A L E P R O Z E D U R E N *
*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*
* C A N _ G E T _O B J _ I N X
*---------------------------------------------------------------------*
* Funktion:
*
*
*---------------------------------------------------------------------*
* Parameter:
*
* obj_adr : Interne Start-Adresse des Objektes
*
* Returnwert : Objekt_Nummer (0 .. 15)
* : 0 wenn obj_adr = 80H
* 1 wenn obj_adr = 80H + 1 * 8
* 2 wenn obj_adr = 80H + 2 * 8
* ................ ..........................
* 15 wenn obj_adr = 80H + 15 * 8
*
*---------------------------------------------------------------------*/
static byte can_get_obj_inx (byte obj_adr)
{
return ( (obj_adr - CONTR_BUF_START_ADR) / MESSAGE_SIZE);
}
/*---------------------------------------------------------------------*
* C A N _ G E T _O B J _ M A S K
*---------------------------------------------------------------------*
* Funktion:
*
*
*---------------------------------------------------------------------*
* Parameter:
*
* obj_adr : Interne Start-Adresse des Objektes
*
* Returnwert : 0000000100000000 wenn obj_adr = 80H
* 0000001000000000 wenn obj_adr = 80H + 1 * 8
* 0000010000000000 wenn obj_adr = 80H + 2 * 8
* ................ ..........................
* 0000000010000000 wenn obj_adr = 80H + 15 * 8
*---------------------------------------------------------------------*/
static unsigned int can_get_obj_mask (byte obj_adr)
{
unsigned int mask;
byte obj_inx;
obj_inx = can_get_obj_inx (obj_adr);
mask = 0x0001;
mask = mask << obj_inx;
/* tausche LOW HIGH bytes */
mask = (mask >> 8 ) | ( mask << 8);
return (mask );
}
/*---------------------------------------------------------------------*
* C A N _ E N A B L E _ I N T E R R U P T S
*---------------------------------------------------------------------*
* Funktion:
* Freigeben receive, bus off, error passive Interrupts
*
*---------------------------------------------------------------------*
* Parameter:
*
*
*---------------------------------------------------------------------*/
static can_enable_interrupts (void)
{
fcan_reg.r.interrupt_mask.enable_receive_interrupt = 1;
fcan_reg.r.interrupt_mask.enable_buss_off_interrupt = 1;
fcan_reg.r.interrupt_mask.enable_error_passive_interrupt = 1;
}
/*---------------------------------------------------------------------*
* C A N _ D I S A B L E _ I N T E R R U P T S
*---------------------------------------------------------------------*
* Funktion:
* Sperren(maskieren) alle Interrupts
*
*---------------------------------------------------------------------*
* Parameter:
*
*
*---------------------------------------------------------------------*/
static can_disable_interrupts (void)
{
fcan_reg.r.interrupt_mask.enable_receive_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_transmit_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_warnig_level_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_remote_frame_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_wake_up_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_buss_off_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_error_passive_interrupt = 0;
fcan_reg.r.interrupt_mask.enable_tr_check_interrupt = 0;
}
/*---------------------------------------------------------------------*
* C A N _ W A I T _ U N T I L _ S E N D E D
*---------------------------------------------------------------------*
* Funktion:
* Warte bis ein Object mit Erfolgt gesendet
*
*---------------------------------------------------------------------*
* Parameter:
*
* obj_adr : Interne Start-Adresse des Objektes
*
* warte bis transmit_request_set des Objektes = 0 oder timeout
* if timeout return FALSE
* fcan_reg.r.transmit_request_set = 0
* else return TRUE
*
* Returnwert : TRUE --> Data mit Erfolg gesendet
* FALSE --> Data nicht gesendet (time out )
*
*---------------------------------------------------------------------*/
static byte can_wait_until_sended (byte obj_adr)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -