📄 zlg_can.c
字号:
/****************************************Copyright (c)****************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**--------------File Info---------------------------------------------------------------------------------
** File Name: zlg_can.c
** Last modified Date: 2010.02.25
** Last Version: 1.0
** Description: CAN API驱动程序,适用于具有多路CAN控制器的CPU
**--------------------------------------------------------------------------------------------------------
** Created By: 张展威
** Created date: 2010.02.25
** Version: 1.0
** Descriptions: The original version 初始版本
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
#include "LPC11xx.h" /* LPC11xx Peripheral Registers */
#include "zlg_can.h"
#include "can.h"
#include "can_reg_cfg.h"
//#include "interrupt.h"
/*********************************************************************************************************
波特率参数表
第一项:传输段及相位缓冲段1的和,取值范围:2~16
第二项:相位缓冲段2,取值范围:1~8
第三项:同步跳转宽度,取值范围1~4
第四项:分频值,取值范围1~1024
*********************************************************************************************************/
const CAN_BIT_CLK_PARM CANBitClkSettings[] =
{
/*
* Fcan = 50MHz
*/
#if FCAN == FCAN48M
{15, 8, 4, 2}, /* CANBAUD_1M */
{15, 8, 4, 4}, /* CANBAUD_500K */
{15, 8, 4, 8}, /* CANBAUD_250K */
{15, 8, 4, 16}, /* CANBAUD_125K */
{15, 8, 4, 20}, /* CANBAUD_100k */
{15, 8, 4, 40}, /* CANBAUD_50k */
{15, 8, 4, 80}, /* CANBAUD_25k */
{15, 8, 4, 100}, /* CANBAUD_20k */
{15, 8, 4, 200}, /* CANBAUD_10k */
{15, 8, 4, 400}, /* CANBAUD_5k */
{15, 8, 4, 800}, /* CANBAUD_2k5 */
#elif FCAN == FCAN6M
/*
* Fcan = 6MHz
*/
{3, 2, 2, 1}, /* CANBAUD_1M */
{6, 5, 4, 1}, /* CANBAUD_500K */
{6, 5, 4, 2}, /* CANBAUD_250K */
{15, 8, 4, 2}, /* CANBAUD_125K */
{11, 8, 4, 3}, /* CANBAUD_100k */
{15, 8, 4, 5}, /* CANBAUD_50k */
{15, 8, 4, 10}, /* CANBAUD_25k */
{16, 8, 4, 12}, /* CANBAUD_20k */
{15, 8, 4, 25}, /* CANBAUD_10k */
{15, 8, 4, 50}, /* CANBAUD_5k */
{15, 8, 4, 100}, /* CANBAUD_2k5 */
#elif FCAN == FCAN2M
/*
* Fcan = 2MHz
*/
{0, 0, 0, 0}, /* CANBAUD_1M (无法达到) */
{2, 1, 1, 1}, /* CANBAUD_500K */
{4, 3, 3, 1}, /* CANBAUD_250K */
{4, 3, 3, 2}, /* CANBAUD_125K */
{5, 4, 4, 2}, /* CANBAUD_100k */
{5, 4, 4, 4}, /* CANBAUD_50k */
{5, 4, 3, 8}, /* CANBAUD_25k */
{5, 4, 3, 10}, /* CANBAUD_20k */
{5, 4, 3, 20}, /* CANBAUD_10k */
{5, 4, 3, 40}, /* CANBAUD_5k */
{5, 4, 3, 80}, /* CANBAUD_2k5 */
#else
/*
* Fcan = 8MHz
*/
{4, 3, 3, 1}, /* CANBAUD_1M */
{8, 7, 4, 1}, /* CANBAUD_500K */
{8, 7, 4, 2}, /* CANBAUD_250K */
{11, 4, 4, 4}, /* CANBAUD_125K */
{11, 4, 4, 5}, /* CANBAUD_100k */
{11, 4, 4, 10}, /* CANBAUD_50k */
{11, 4, 4, 20}, /* CANBAUD_25k */
{11, 4, 4, 25}, /* CANBAUD_20k */
{11, 4, 4, 50}, /* CANBAUD_10k */
{11, 4, 4, 100}, /* CANBAUD_5k */
{11, 4, 4, 200}, /* CANBAUD_2k5 */
#endif
};
/*********************************************************************************************************
** 用于初始化CAN缓存块的数据
*********************************************************************************************************/
const CANFRAME GtCanFrameInit = {
BUF_BLANK, /* 空白帧 */
0, /* 数据域长度为0 */
0, /* 报文ID为 */
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} /* 数据域内容 */
};
/*********************************************************************************************************
** Function name: canCirBufInit
** Descriptions: 初始化帧接收软件FIFO
** input parameters: ptBuf 指向接收循环队列的指针
** output parameters: 无
** Returned value: 无
** Created By: 张展威
** Created date: 2008.09.03
**--------------------------------------------------------------------------------------------------------
** Modified by: 张展威
** Modified date: 2009.04.29
** Descriptions: 将帧类型格式初始化为BUF_BLANK,用于防止误读
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void canCirBufInit(CANCIRBUF *ptCanCirBuf, CANFRAME *ptCanFrameBuf, INT8U ucLength)
{
unsigned int i;
ptCanCirBuf->ulWriteIndex = 0; /* Buffer[]写下标清零 */
ptCanCirBuf->ulReadIndex = 0; /* Buffer[]读下标清零 */
ptCanCirBuf->bIsFull = false; /* 循环队列不满 */
ptCanCirBuf->ulLength = ucLength; /* 记录长度,此值不允再许更改 */
ptCanCirBuf->ptCanFramBuf = ptCanFrameBuf; /* 指向数据缓存区首地址 */
for (i = 0; i < ucLength; i++) {
ptCanCirBuf->ptCanFramBuf[i] = GtCanFrameInit; /* 初始化为空帧 */
}
}
/*********************************************************************************************************
** Function name: canCirBufMalloc
** Descriptions: 向循环队列(软件FIFO)申请一块帧缓存区域 帧类型格式将被初始化为BUF_BLANK
** input parameters: ptBuf 指向循环队列的指针
** output parameters: 无
** Returned value: ptCanFrame 帧缓存地址,若为0则表示循环队列满
** Created By: 张展威
** Created date: 2008.09.02
**--------------------------------------------------------------------------------------------------------
** Modified by: 张展威
** Modified date: 2009.04.29
** Descriptions: 添加临界区保护
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
static CANFRAME *canCirBufMalloc(CANCIRBUF *ptCanCirBuf)
{
CANFRAME *ptCanFrame;
unsigned char ucEnable = 0;
if (ptCanCirBuf == (CANCIRBUF *)0) {
return 0; /* 队列错误 */
}
if (ptCanCirBuf->bIsFull == true) {
return 0; /* 队列满,则返回 0 */
}
ucEnable = __ENTER_CIRTICAL(); /* 进入临界区 */
ptCanFrame = &(ptCanCirBuf->ptCanFramBuf[ptCanCirBuf->ulWriteIndex++]);
/* 取得需要返回的地址 */
if (ptCanCirBuf->ulWriteIndex == ptCanCirBuf->ulLength) {
ptCanCirBuf->ulWriteIndex = 0; /* 构成循环队列 */
}
if (ptCanCirBuf->ulWriteIndex == ptCanCirBuf->ulReadIndex) { /* 写指针赶上读指针,队列满 */
ptCanCirBuf->bIsFull = true; /* 置位队列满标志 */
}
__EXIT_CIRTICAL(ucEnable); /* 退出临界区 */
*ptCanFrame = GtCanFrameInit; /* 初始化申请的存储空间 */
return ptCanFrame;
}
/*********************************************************************************************************
** Function name: canCirBufRead
** Descriptions: 从循环队列读取一帧数据
** input parameters: ptCanBuf 指向循环队列的指针
** output parameters: ptFrame 数据输出指针
** Returned value: EMPTY 循环队列为空,循环队列中无可用数据
** NOT_EMPTY 循环队列非空
** CAN_ERROR 循环队列错误,操作失败
** Created By: 张展威
** Created date: 2008.09.02
**--------------------------------------------------------------------------------------------------------
** Modified by: 张展威
** Modified date: 2009.04.29
** Descriptions: 添加临界区保护及误读保护
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
INT8U canCirBufRead(CANCIRBUF *ptCanCirBuf, CANFRAME *ptCanFrame)
{
INT8U ucReturn = CAN_ERROR;
unsigned long ulIndex;
unsigned char ucEnable = 0;
if (ptCanCirBuf == (CANCIRBUF *)0) {
return CAN_ERROR; /* 队列错误 */
}
ucEnable = __ENTER_CIRTICAL(); /* 进入临界区 */
if ((ptCanCirBuf->ulReadIndex != ptCanCirBuf->ulWriteIndex) || (ptCanCirBuf->bIsFull == true)) {
ulIndex = ptCanCirBuf->ulReadIndex; /* 缓存下标 */
if (ptCanCirBuf->ptCanFramBuf[ulIndex].ucTtypeFormat != BUF_BLANK) {
//帧允许读(帧写结束之前ucTtypeFormat = BUF_BLANK)
*ptCanFrame = ptCanCirBuf->ptCanFramBuf[ulIndex];
ptCanCirBuf->ulReadIndex += 1; /* 读指针加1 */
if (ptCanCirBuf->ulReadIndex == ptCanCirBuf->ulLength) {
ptCanCirBuf->ulReadIndex = 0; /* 形成环形缓冲器 */
}
ptCanCirBuf->bIsFull = false; /* 清零缓冲区满标志 */
ucReturn = CAN_OK;
}
}
__EXIT_CIRTICAL(ucEnable); /* 退出临界区 */
return ucReturn;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -