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

📄 zlg_can.c

📁 LPC11C14 CAN 代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************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 + -