📄 can.h
字号:
#ifndef __CAN_H__
#define __CAN_H__
#include "..\CAN\CANREG.h"
/******************************************************************************
CAN滤波器设置内容
******************************************************************************/
/* 定义CAN滤波器标准帧(11位ID)表格单元类型 */
typedef struct tag_AF_SFF_CELL
{
uint32 UpId :11; /* 11bits ID1 */
uint32 UpRsv :1; /* 保留 */
uint32 UpDis :1; /* 禁能位 */
uint32 UpCh :3; /* CAN控制器号 */
uint32 LoId :11; /* 11bits ID0 */
uint32 LoRsv :1; /* 保留 */
uint32 LoDis :1; /* 禁能位 */
uint32 LoCh :3; /* CAN控制器号 */
}_AF_SFF_CELL;
/* 定义CAN滤波器扩展帧(29位ID)表格单元类型 */
typedef struct tag_AF_EFF_CELL
{
uint32 Id :29; /* 29bits ID */
uint32 Ch :3; /* CAN控制器号 */
}_AF_EFF_CELL;
/* 定义验收滤波模式寄存器结构 */
typedef struct _canafmr_
{
uint32 AccOff_BIT :1;
uint32 AccBP_BIT :1;
uint32 eFCAN_BIT :1;
uint32 RSV_BIT29 :29;
}CANAFMR;
/* 验收滤波器表格单个标志符表格起始地址数据结构定义 */
typedef struct _canFF_sa_
{
uint32 RSV_BIT2 :2;
uint32 SADR_BIT :9;
uint32 RSV_BIT21 :21;
}CANSFF_sa, CANEFF_sa;
/* 验收滤波器表格标志符组表格起始地址数据结构定义 */
typedef struct _canGRP_sa_
{
uint32 RSV_BIT2 :2;
uint32 SADR_BIT :10;
uint32 RSV_BIT20 :20;
}CANSFF_GRP_sa, CANEFF_GRP_sa;
/* LUT错误寄存器数据结构定义 */
typedef struct _canLUTerr
{
uint32 LERR_BIT :1;
uint32 RSV_BIT31 :31;
}CANLUTerr, *P_CANLUTerr;
/* LUT状态枚举定义 */
enum LUT_BUILD_ERR
{
LUT_SETTING_OK = 0,
TOTAL_SIZE_TOO_LARGE = 1,
FCAN_SIZE_TOO_LARGE = 2,
EFF_GRP_SIZE_INVALID = 3,
FCAN_STORE_SIZE_INVALID = 4,
TABLE_CELL_TOO_LARGE = 5,
CELL_NUM_INVALID = 6,
CELL_CONTENT_INVALID = 7
};
/* 接收过滤寄存器AFMR的各种模式枚举 */
typedef enum _AF_MODE_
{
AF_NORMAL = 0, /* 正常模式,执行全局过滤操作 */
AF_IGNORE = 1, /* 忽略模式,接收器忽略总线上出现的数据 */
AF_BYPASS = 2, /* 旁路模式,允许所有接收通过,以及用于修改与CAN接收过滤相关的寄存器和LUT内容 */
AF_FULLCAN = 3 /* FullCAN模式,允许在全局接收过滤的基础上添加自动接收和存储功能 */
}eAF_MODE;
/******************************************************************************
CAN控制器设置内容
******************************************************************************/
/* 微处理器所含有的最大CAN模块的数目 */
#define CAN_MAX_NUM 4
/* CAN控制器通道定义 */
typedef enum _cannum_
{
#if CAN_MAX_NUM == 4 /* 微处理器中含有4路CAN */
CAN1 = 0, /* CAN1模块 */
CAN2, /* CAN2模块 */
CAN3, /* CAN3模块 */
CAN4 /* CAN4模块 */
#elif CAN_MAX_NUM == 3
CAN1 = 0, /* CAN1模块 */
CAN2, /* CAN2模块 */
CAN3 /* CAN3模块 */
#elif CAN_MAX_NUM == 2
CAN1 = 0, /* CAN1模块 */
CAN2 /* CAN2模块 */
#elif CAN_MAX_NUM == 1
CAN1 = 0 /* CAN1模块 */
#endif
}eCANNUM;
/* 定义标准11位和扩展29位CAN ID */
#define X11 TRUE
#define X29 FALSE
/* 总线时序器值CAN_BPS_xxK(regCANBTR)的设置方法
CAN_BPS_xxK = (SAM << 23)|(TSEG2 << 20)|(TSEG1 << 16)|(SJW << 14)| BRP
CAN总线时序寄存器中的相关参数与VPB时钟的关系:(BPS——波特率)
((TSEG2 + 3) + (TSEG1 + 1) - (SJW +1)) * (BRP + 1) * BPS = VPB
(TSEG2 + 3 + TSEG1) * (BRP + 1) * BPS = VPB
例如:当VPB = 15MHz时,由语句
#define CAN_BPS_1000K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 2 可知
TSEG2 = 1, TSEG1 = 1, BPS = 1000K, BRP = 2
/* 当VPB时钟为11059200Hz时,常用波特率与CAN总线时序寄存器值对照表
#define CAN_BPS_5K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 199
#define CAN_BPS_10K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 99
#define CAN_BPS_20K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 49
#define CAN_BPS_40K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 24
#define CAN_BPS_50K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 19
#define CAN_BPS_100K (1 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 9
#define CAN_BPS_125K (0 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 7
#define CAN_BPS_200K (0 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 4
#define CAN_BPS_250K (0 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 3
#define CAN_BPS_500K (0 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 1
#define CAN_BPS_1000K (0 << 23)|(1 << 20)|(7 << 16)|(0 << 14)| 0
*/
/* VPB = 15MHz时的波特率 */
#define CAN_BPS_5K (1 << 23)|(1 << 20)|(2 << 16)|(0 << 14)| 499
#define CAN_BPS_10K (1 << 23)|(1 << 20)|(2 << 16)|(0 << 14)| 249
#define CAN_BPS_20K (1 << 23)|(1 << 20)|(2 << 16)|(0 << 14)| 124
#define CAN_BPS_50K (1 << 23)|(1 << 20)|(2 << 16)|(0 << 14)| 19
#define CAN_BPS_100K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 29
#define CAN_BPS_125K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 23
#define CAN_BPS_200K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 14
#define CAN_BPS_250K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 11
#define CAN_BPS_500K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 5
#define CAN_BPS_1000K (0 << 23)|(1 << 20)|(1 << 16)|(0 << 14)| 2
/* CAN初始化参数 */
typedef struct
{
uint32 mod; /* CAN工作模式 */
uint32 ier; /* 中断使能 */
uint32 btr; /* 波特率 */
uint32 ewl; /* 出错值 */
}CAN_Setting;
/******************************************************************************
缓冲区设置
******************************************************************************/
/* 定义接收帧结构 */
typedef struct _stcRxData_
{
uint32 RxID; /* 11位接收帧ID号分为8位ID号和3位帧号 */
uint32 RxDA;
uint32 RxDB;
}stcCANRxData;
/* 接收缓冲区结构 */
typedef struct _stcCANRxBuf_
{
volatile uint32 RxDBufSize; /* 缓冲区大小帧数 */
volatile uint32 RxDBufLen; /* 缓冲区有效帧数 */
/*
uint32 RxDBufInPos; 接收缓冲区下一写入位置
uint32 RxDBufOutPos; 接收缓冲区下一读出位置
*/
stcCANRxData * pRxDBuf; /* 缓冲区指针 */
}CAN_RxBuf;
/* 定义大批量数据接收帧结构 */
typedef struct _stcBatchRxData_
{
uint16 u16_RxID;
uint16 u16_RxD0;
uint16 u16_RxD1;
uint16 u16_RxD2;
uint16 u16_RxD3;
}stcBatchRxData;
/* 大批量数据接收缓冲结构 */
typedef struct _stcBatchRxBuf_
{
volatile uint32 RxDBufSize; /* 缓冲区大小帧数 */
volatile uint32 RxDBufLen; /* 缓冲区有效帧数 */
stcBatchRxData * pRxDBuf; /* 缓冲区指针 */
}BatchRxBuf;
/* 定义发送帧结构 */
typedef struct _stcTxData_
{
uint32 TxID; /* 11位发送帧ID号分为8位ID号和3位帧号 */
uint32 TxDA;
uint32 TxDB;
}stcCANTxData;
/* 发送缓冲区结构 */
typedef struct _stcCANTxBuf_
{
volatile uint32 TxDBufSize; /* 缓冲区大小帧数 */
volatile uint32 TxDBufLen; /* 发送缓冲区有效帧数 */
volatile uint32 TxDBufPos; /* 发送缓冲区下一读出位置 */
stcCANTxData * pTxDBuf; /* 发送缓冲区指针 */
}CAN_TxBuf;
/* 定义全局接收和发送数据区大小 */
/* #define Global_CAN_RxDBufMaxSize 1512 全局接收数据区1512帧(常规信息144帧,揭示信息1368帧)*/
/* #define Global_CAN_TxDBufMaxSize 80 全局发送数据区80帧 */
/******************************************************************************
验收滤波器的设置函数
******************************************************************************/
/* 创建LUT表格 */
uint32 CAN_AFBuildLUT(uint32 nCell[5]);
/* 初始化FullCAN表格 */
uint32 CAN_AFInitFCANTab(_AF_SFF_CELL *pTab, uint32 nCell);
/* 初始化独立标准帧标识符表格 */
uint32 CAN_AFInitSFFIndvTab(_AF_SFF_CELL *pTab, uint32 nCell);
/* 初始化标准帧标识范围表格 */
uint32 CAN_AFInitSFFGrpTab(_AF_SFF_CELL *pTab, uint32 nCell);
/* 初始化独立扩展帧标识符表格 */
uint32 CAN_AFInitEFFIndvTab(_AF_EFF_CELL *pTab, uint32 nCell);
/* 初始化扩展帧标识范围表格 */
uint32 CAN_AFInitEFFGrpTab(_AF_EFF_CELL *pTab, uint32 nCell);
/* 指定接收过滤器的工作模式,启动或关闭全局滤波器 */
void CAN_AFSetMode(eAF_MODE mode);
/* 获得LUT表格结束偏移地址 */
uint32 CAN_AFGetEndOfTabOffset(void);
/******************************************************************************
应用层函数
******************************************************************************/
/* 发送命令枚举 */
typedef enum _send_cmd_
{
NOM_SEND_CMD = 0, /* 正常发送 */
SIG_SEND_CMD = 1, /* 单帧发送 */
SLF_SEND_CMD = 2, /* 自检测 */
SRR_SEND_CMD = 3 /* 只收不发 */
}eSend_CMD;
/* 发送命令数组 */
extern eSend_CMD SendCMD[CAN_MAX_NUM];
#define SEND_TX_BUF1 1
#define SEND_TX_BUF2 2
#define SEND_TX_BUF3 4
/* 初始化缓冲区 */
void CAN_InitBuf(void);
/* 初始化CAN控制器 */
void CAN_Init(eCANNUM CanNum, CAN_Setting* setting);
/* 将数据写到发送缓冲区并启动发送 */
uint32 CAN_Write(eCANNUM CanNum, eSend_CMD Cmd, stcCANTxData* Buf, uint32 nItem);
/* 向CAN发送缓冲区TxBUF写入发送数据并发送 */
uint32 CAN_WriteTxBuf(eCANNUM CanNum);
/* 读取CAN驱动接收到的数据 */
uint32 CAN_Read(uint32 BufNum, stcCANRxData *Buf, uint32 nItem);
/* 从CAN控制器RxBuf中读取数据 */
void CAN_ReadRxBuf(eCANNUM CanNum,stcCANRxData* Buf);
/* 清除驱动程序接收缓冲区 */
uint32 CAN_ClrRxBuf(uint32 BufNum, uint32 lowerItem, uint32 upperItem);
/* 将收到的CAN数据写入环形缓冲区 */
void CAN_WriteRcvBuf(eCANNUM CanNum, uint32 BufNum, uint32 FrameNum);
/* 批量CAN数据写入环形缓冲区 */
void CAN_BatchWriteRcvBuf(eCANNUM CanNum, uint32 BufNum, uint32 FrameNum);
/******************************************************************************
硬件层函数
******************************************************************************/
/* 硬件复位CAN控制器,主要是CAN模块掉电,用于省电处理 */
__inline void CAN_HwRst(eCANNUM CanNum);
/* 硬件使能CAN控制器 */
void CAN_HwEn(eCANNUM CanNum);
/* 软件复位CAN控制器 */
__inline void CAN_SoftRst(eCANNUM CanNum);
/* 软件使能CAN控制器 */
__inline void CAN_SoftEn(eCANNUM CanNum);
/* 发送命令处理 */
void Can_SendCmd(eCANNUM CanNum, eSend_CMD Cmd, uint32 TxBuf);
/* 释放接收缓冲区 */
__inline void CAN_RelRecBuf(eCANNUM CanNum);
/* 清除数据溢出 */
__inline void CAN_ClrDataOver(eCANNUM CanNum);
/* CAN控制器出现总线关闭错误处理 */
__inline void Can_BufOffLinePrg(eCANNUM CanNum);
/* 使CAN控制器进入休眠模式 */
__inline void Can_EntrySM(eCANNUM CanNum);
/* 使CAN控制器退出休眠模式 */
__inline void Can_QuitSM(eCANNUM CanNum);
/******************************************************************************
CAN控制器中断处理函数
******************************************************************************/
__irq void CAN1_Tx_Exception(void);
__irq void CAN1_Rx_Exception(void);
__irq void CAN2_Tx_Exception(void);
__irq void CAN2_Rx_Exception(void);
__irq void CAN3_Tx_Exception(void);
__irq void CAN3_Rx_Exception(void);
__irq void CAN4_Tx_Exception(void);
__irq void CAN4_Rx_Exception(void);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -