打印
[DemoCode下载]

NUC131的CAN例程序

[复制链接]
2282|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wahahaheihei|  楼主 | 2017-10-1 14:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/****************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V2.0
* $Revision: 8 $
* $Date: 15/01/16 1:45p $
* @brief
*           Implement receive message in Normal mode.
*           This sample code needs to work with CAN_NormalMode_Transmit.
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "NUC131.h"


#define PLL_CLOCK       48000000

/*---------------------------------------------------------------------------*/
/*  Function Declare                                                         */
/*---------------------------------------------------------------------------*/
extern char GetChar(void);
void CAN_ShowMsg(STR_CANMSG_T* Msg);

/*---------------------------------------------------------------------------------------------------------*/
/* Define global variables and constants                                                                   */
/*---------------------------------------------------------------------------------------------------------*/
/* Declare a CAN message structure */
STR_CANMSG_T rrMsg;


/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle CAN interrupt event                                                                       */
/*---------------------------------------------------------------------------------------------------------*/
void CAN_MsgInterrupt(CAN_T *tCAN, uint32_t u32IIDR)
{
    if(u32IIDR == 1)
    {
        //printf("Msg-0 INT and Callback\n");
        CAN_Receive(tCAN, 0, &rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
    if(u32IIDR == 5 + 1)
    {
        //printf("Msg-5 INT and Callback \n");
        CAN_Receive(tCAN, 5, &rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
    if(u32IIDR == 31 + 1)
    {
        //printf("Msg-31 INT and Callback \n");
        CAN_Receive(tCAN, 31, &rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
}

/*---------------------------------------------------------------------------------------------------------*/
/* CAN0 interrupt handler                                                                                  */
/*---------------------------------------------------------------------------------------------------------*/
void CAN0_IRQHandler(void)
{
    uint32_t u8IIDRstatus;

    u8IIDRstatus = CAN0->IIDR;

    if(u8IIDRstatus == 0x00008000)        /* Check Status Interrupt Flag (Error status Int and Status change Int) */
    {
        /**************************/
        /* Status Change interrupt*/
        /**************************/
        if(CAN0->STATUS & CAN_STATUS_RXOK_Msk)
        {
            CAN0->STATUS &= ~CAN_STATUS_RXOK_Msk;   /* Clear RxOK status*/
        }

        if(CAN0->STATUS & CAN_STATUS_TXOK_Msk)
        {
            CAN0->STATUS &= ~CAN_STATUS_TXOK_Msk;    /* Clear TxOK status*/
        }

        /**************************/
        /* Error Status interrupt */
        /**************************/
        if(CAN0->STATUS & CAN_STATUS_BOFF_Msk)
        {
            printf("BOFF INT\n") ;
        }
        else if(CAN0->STATUS & CAN_STATUS_EWARN_Msk)
        {
            printf("EWARN INT\n") ;
        }
        else if((CAN0->ERR & CAN_ERR_TEC_Msk) != 0)
        {
            printf("Transmit error!\n") ;
        }
        else if((CAN0->ERR & CAN_ERR_REC_Msk) != 0)
        {
            printf("Receive error!\n") ;
        }
    }
    else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20))
    {
        CAN_MsgInterrupt(CAN0, u8IIDRstatus);

        CAN_CLR_INT_PENDING_BIT(CAN0, (u8IIDRstatus - 1)); /* Clear Interrupt Pending */
    }
    else if(CAN0->WU_STATUS == 1)
    {
        printf("Wake up\n");

        CAN0->WU_STATUS = 0;    /* Write '0' to clear */
    }

}

/*---------------------------------------------------------------------------------------------------------*/
/* Reset message interface parameters                                                                      */
/*---------------------------------------------------------------------------------------------------------*/
void CAN_ResetIF(CAN_T *tCAN, uint8_t u8IF_Num)
{
    if(u8IF_Num > 1)
        return;
    tCAN->IF[u8IF_Num].CREQ     = 0x0;          // set bit15 for sending
    tCAN->IF[u8IF_Num].CMASK    = 0x0;
    tCAN->IF[u8IF_Num].MASK1    = 0x0;          // useless in basic mode
    tCAN->IF[u8IF_Num].MASK2    = 0x0;          // useless in basic mode
    tCAN->IF[u8IF_Num].ARB1     = 0x0;          // ID15~0
    tCAN->IF[u8IF_Num].ARB2     = 0x0;          // MsgVal, eXt, xmt, ID28~16
    tCAN->IF[u8IF_Num].MCON     = 0x0;          // DLC
    tCAN->IF[u8IF_Num].DAT_A1   = 0x0;          // data0,1
    tCAN->IF[u8IF_Num].DAT_A2   = 0x0;          // data2,3
    tCAN->IF[u8IF_Num].DAT_B1   = 0x0;          // data4,5
    tCAN->IF[u8IF_Num].DAT_B2   = 0x0;          // data6,7
}

/*---------------------------------------------------------------------------*/
/*  Show Message Function                                                    */
/*---------------------------------------------------------------------------*/
void CAN_ShowMsg(STR_CANMSG_T* Msg)
{
    uint8_t i;

    /* Show the message information */
    printf("Read ID=0x%X, Type=%s, DLC=%d, Data=", Msg->Id, Msg->IdType ? "EXT" : "STD", Msg->DLC);
    for(i = 0; i < Msg->DLC; i++)
        printf("%X,", Msg->Data[i]);
    printf("\n\n");
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC 22.1184MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external XTAL 12MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    /* Waiting for external XTAL clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Enable CAN module clock */
    CLK_EnableModuleClock(CAN0_MODULE);
    //CLK_EnableModuleClock(CAN1_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_PLL, CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set GPB multi-function pins for UART0 RXD and TXD */
    SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
    SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

    /* Set PD multi-function pins for CANTX0, CANRX0 */
    SYS->GPD_MFP &= ~(SYS_GPD_MFP_PD6_Msk | SYS_GPD_MFP_PD7_Msk);
    SYS->GPD_MFP = SYS_GPD_MFP_PD6_CAN0_RXD | SYS_GPD_MFP_PD7_CAN0_TXD;

}

/*---------------------------------------------------------------------------------------------------------*/
/* Init UART                                                                                               */
/*---------------------------------------------------------------------------------------------------------*/
void UART0_Init()
{
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* Disable CAN Clock and Reset it                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
void CAN_STOP(void)
{
    /* Disable CAN0 Clock and Reset it */
    SYS_ResetModule(CAN0_RST);
    CLK_DisableModuleClock(CAN0_MODULE);
}

/*----------------------------------------------------------------------------*/
/*  Some description about how to create test environment                     */
/*----------------------------------------------------------------------------*/
void Note_Configure()
{
    printf("\n\n");
    printf("+--------------------------------------------------------------------------+\n");
    printf("|  About CAN sample code configure                                         |\n");
    printf("+--------------------------------------------------------------------------+\n");
    printf("|   The sample code provide a simple sample code for you study CAN         |\n");
    printf("|   Before execute it, please check description as below                   |\n");
    printf("|                                                                          |\n");
    printf("|   1.CAN_TX and CAN_RX should be connected to your CAN transceiver        |\n");
    printf("|   2.Using two module board and connect to the same CAN BUS               |\n");
    printf("|   3.Check the terminal resistor of bus is connected                      |\n");
    printf("|   4.Using UART0 as print message port                                    |\n");
    printf("|                                                                          |\n");
    printf("|  |--------|       |-----------|   CANBUS  |-----------|       |--------| |\n");
    printf("|  |        |------>|           |<--------->|           |<------|        | |\n");
    printf("|  |        |CAN_TX |    CAN    |   CAN_H   |   CAN     |CAN_TX |        | |\n");
    printf("|  | NUC131 |       |Transceiver|           |Transceiver|       | NUC131 | |\n");
    printf("|  |        |<------|           |<--------->|           |------>|        | |\n");
    printf("|  |        |CAN_RX |           |   CAN_L   |           |CAN_RX |        | |\n");
    printf("|  |--------|       |-----------|           |-----------|       |--------| |\n");
    printf("|  |                                                            |          |\n");
    printf("|  |                                                            |          |\n");
    printf("|  V                                                            V          |\n");
    printf("| UART0                                                         UART0      |\n");
    printf("|(print message)                                          (print message)  |\n");
    printf("+--------------------------------------------------------------------------+\n");
}

/*----------------------------------------------------------------------------*/
/*  Check the real baud-rate                                                  */
/*----------------------------------------------------------------------------*/
void BaudRateCheck(uint32_t u32BaudRate, uint32_t u32RealBaudRate)
{
    /* Get Core Clock Frequency */
    SystemCoreClockUpdate();

    if(u32BaudRate != u32RealBaudRate)
    {
        printf("\nSet CAN baud-rate is fail\n");
        printf("Real baud-rate value(bps): %d\n", u32RealBaudRate);
        printf("CAN baud-rate calculation equation as below:\n");
        printf("CAN baud-rate(bps) = Fin/(BPR+1)*(Tseg1+Tseg2+3)\n");
        printf("where: Fin: System clock freq.(Hz)\n");
        printf("       BRP: The baud rate prescale. It is composed of BRP (CAN_BTIME[5:0]) and BRPE (CAN_BRPE[3:0]).\n");
        printf("       Tseg1: Time Segment before the sample point. You can set tseg1 (CAN_BTIME[11:8]).\n");
        printf("       Tseg2: Time Segment after the sample point. You can set tseg2 (CAN_BTIME[14:12]).\n");

        if(SystemCoreClock % u32BaudRate != 0)
            printf("\nThe BPR does not calculate, the Fin must be a multiple of the CAN baud-rate.\n");

        else
            printf("\nThe BPR does not calculate, the (Fin/(CAN baud-rate)) must be a multiple of the (Tseg1+Tseg1+3).\n");
    }
    else
        printf("\nReal baud-rate value(bps): %d\n", u32RealBaudRate);
}

/*----------------------------------------------------------------------------*/
/*  Set the CAN speed                                                         */
/*----------------------------------------------------------------------------*/
void SelectCANSpeed(CAN_T  *tCAN)
{
    uint32_t unItem, BaudRate = 0, RealBaudRate = 0;

    printf("Please select CAN speed you desired\n");
    printf("[0] 1000Kbps\n");
    printf("[1]  800Kbps\n");
    printf("[2]  500Kbps\n");
    printf("[3]  250Kbps\n");
    printf("[4]  125Kbps\n");
    printf("[5]  100Kbps\n");
    printf("[6]   50Kbps\n");

    unItem = GetChar();
    printf("%c\n", unItem);

    switch(unItem)
    {
        case '0':
            BaudRate = 1000000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);//Set target baud-rate and operation mode.
            break;

        case '1':
            BaudRate = 800000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;

        case '2':
            BaudRate = 500000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;

        case '3':
            BaudRate = 250000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;

        case '4':
            BaudRate = 125000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;

        case '5':
            BaudRate = 100000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;

        case '6':
            BaudRate = 50000;
            RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
            break;
    }

    /* Check the real baud-rate is OK */
    BaudRateCheck(BaudRate, RealBaudRate);

}

/*----------------------------------------------------------------------------*/
/*  Test Menu                                                                 */
/*----------------------------------------------------------------------------*/
void TestItem(void)
{
    printf("\n");
    printf("+------------------------------------------------------------------ +\n");
    printf("|  Nuvoton CAN BUS DRIVER DEMO                                      |\n");
    printf("+-------------------------------------------------------------------+\n");
    printf("|                                                                   |\n");
    printf("|      Receive a message by normal mode                             |\n");
    printf("|                                                                   |\n");
    printf("+-------------------------------------------------------------------+\n");
}

/*----------------------------------------------------------------------------*/
/*  Send Rx Msg by Normal Mode Function (With Message RAM)                    */
/*----------------------------------------------------------------------------*/
void Test_NormalMode_Rx(CAN_T *tCAN)
{
    CAN_EnableInt(tCAN, CAN_CON_IE_Msk | CAN_CON_SIE_Msk);      /* Enable CAN interrupt and corresponding NVIC of CAN */
    NVIC_SetPriority(CAN0_IRQn, (1 << __NVIC_PRIO_BITS) - 2);   /* Install CAN call back functions */
    NVIC_EnableIRQ(CAN0_IRQn);

    if(CAN_SetRxMsg(tCAN, MSG(0), CAN_STD_ID, 0x7FF) == FALSE)
    {
        printf("Set Rx Msg Object failed\n");
        return;
    }

    if(CAN_SetRxMsg(tCAN, MSG(5), CAN_EXT_ID, 0x12345) == FALSE)
    {
        printf("Set Rx Msg Object failed\n");
        return;
    }

    if(CAN_SetRxMsg(tCAN, MSG(31), CAN_EXT_ID, 0x7FF01) == FALSE)
    {
        printf("Set Rx Msg Object failed\n");
        return;
    }

    printf("Wait Msg\n");
    printf("Enter any key to exit\n");
    GetChar();

}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    CAN_T *tCAN;
    tCAN = (CAN_T *) CAN0;

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Some description about how to create test environment */
    Note_Configure();

    /* Configuring the Bit Timing */
    SelectCANSpeed(tCAN);

    /* Test Menu */
    TestItem();

    printf("Receive a message by normal mode\n\n");

    /* Send Rx Msg by Normal Mode Function (With Message RAM) */
    Test_NormalMode_Rx(tCAN);

    /* Disable CAN */
    CAN_Close(tCAN);

    /* Disable CAN Clock and Reset it */
    CAN_STOP();

    while(1);

}




沙发
wahahaheihei|  楼主 | 2017-10-1 14:00 | 只看该作者
有人看完觉得怎么中断处理函数一样啊,好奇怪,其实不是。是为了方便当初写代码的人,写一起了。
/*---------------------------------------------------------------------------------------------------------*/
/* CAN0 interrupt handler                                                                                  */
/*---------------------------------------------------------------------------------------------------------*/
void CAN0_IRQHandler(void)
{
    uint32_t u8IIDRstatus;

    u8IIDRstatus = CAN0->IIDR;

    if(u8IIDRstatus == 0x00008000)        /* Check Status Interrupt Flag (Error status Int and Status change Int) */
    {
        /**************************/
        /* Status Change interrupt*/
        /**************************/
        if(CAN0->STATUS & CAN_STATUS_RXOK_Msk)
        {
            CAN0->STATUS &= ~CAN_STATUS_RXOK_Msk;   /* Clear RxOK status*/
        }

        if(CAN0->STATUS & CAN_STATUS_TXOK_Msk)
        {
            CAN0->STATUS &= ~CAN_STATUS_TXOK_Msk;    /* Clear TxOK status*/
        }

        /**************************/
        /* Error Status interrupt */
        /**************************/
        if(CAN0->STATUS & CAN_STATUS_BOFF_Msk)
        {
            printf("BOFF INT\n") ;
        }
        else if(CAN0->STATUS & CAN_STATUS_EWARN_Msk)
        {
            printf("EWARN INT\n") ;
        }
        else if((CAN0->ERR & CAN_ERR_TEC_Msk) != 0)
        {
            printf("Transmit error!\n") ;
        }
        else if((CAN0->ERR & CAN_ERR_REC_Msk) != 0)
        {
            printf("Receive error!\n") ;
        }
    }
    else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20))
    {
        CAN_MsgInterrupt(CAN0, u8IIDRstatus);

        CAN_CLR_INT_PENDING_BIT(CAN0, (u8IIDRstatus - 1)); /* Clear Interrupt Pending */
    }
    else if(CAN0->WU_STATUS == 1)
    {
        printf("Wake up\n");

        CAN0->WU_STATUS = 0;    /* Write '0' to clear */
    }

}

使用特权

评论回复
板凳
wahahaheihei|  楼主 | 2017-10-1 14:01 | 只看该作者
我们可以看到有判断是接受还是发送的部分,其实就是这里来实现接收和发送中断的区分的。

使用特权

评论回复
地板
yiy| | 2017-10-1 19:21 | 只看该作者
    printf("|  |--------|       |-----------|   CANBUS  |-----------|       |--------| |\n");
    printf("|  |        |------>|           |<--------->|           |<------|        | |\n");
    printf("|  |        |CAN_TX |    CAN    |   CAN_H   |   CAN     |CAN_TX |        | |\n");
    printf("|  | NUC131 |       |Transceiver|           |Transceiver|       | NUC131 | |\n");
    printf("|  |        |<------|           |<--------->|           |------>|        | |\n");
    printf("|  |        |CAN_RX |           |   CAN_L   |           |CAN_RX |        | |\n");
    printf("|  |--------|       |-----------|           |-----------|       |--------| |\n");
    printf("|  |                                                            |          |\n");
    printf("|  |                                                            |          |\n");

这种字符图怎么做?

使用特权

评论回复
5
598330983| | 2017-10-1 21:51 | 只看该作者
楼上的,那是人家手工做的,你复制几行空格,然后替换对应字符,就排列整齐了,然后把每行复制到printf中

使用特权

评论回复
6
heisexingqisi| | 2017-10-3 10:08 | 只看该作者
/ ******************* ***************************
* [url = home.php?mod = space&uid = 288409] [url=home.php?mod=space&uid=288409]@file[/url] [/ url] main.c
* [url = home.php?mod = space&uid = 895143] [url=home.php?mod=space&uid=895143]@version[/url] [/ url] V2.0
* $修订:8 $
* $日期:15/01/16 1:45p $
* @brief
*在正常模式下实现接收消息。
*此示例代码需要使用CAN_NormalMode_Transmit。
* @注意
*版权所有(C)2014 Nuvoton Technology Corp.保留所有权利。
*
************************************************** ************ /
#include <stdio.h>
#include“NUC131.h”


#define PLL_CLOCK 48000000

/ * ------------------------------------------------ --------------------------- * /
/ *函数声明* /
/ * ------------------------------------------------ --------------------------- * /
extern char GetChar(void);
void CAN_ShowMsg(STR_CANMSG_T * Msg);

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ *定义全局变量和常量* /
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ *声明一个CAN消息结构* /
STR_CANMSG_T rrMsg;


/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ * ISR来处理CAN中断事件* /
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
void CAN_MsgInterrupt(CAN_T * tCAN,uint32_t u32IIDR)
{
    if(u32IIDR == 1)
    {
        // printf(“Msg-0 INT and Callback \ n”);
        CAN_Receive(tCAN,0,&rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
    if(u32IIDR == 5 + 1)
    {
        // printf(“Msg-5 INT and Callback \ n”);
        CAN_Receive(tCAN,5,&rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
    if(u32IIDR == 31 + 1)
    {
        // printf(“Msg-31 INT and Callback \ n”);
        CAN_Receive(tCAN,31,&rrMsg);
        CAN_ShowMsg(&rrMsg);
    }
}

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ * CAN0中断处理程序* /
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
void CAN0_IRQHandler(void)
{
    uint32_t u8IIDRstatus;

    u8IIDRstatus = CAN0-> IIDR;

    if(u8IIDRstatus == 0x00008000)/ *检查状态中断标志(错误状态Int和状态改变Int)* /
    {
        / *************** /
        / *状态更改中断* /
        / *************** /
        如果(CAN0-> STATUS&CAN_STATUS_RXOK_Msk)
        {
            CAN0-> STATUS&=〜CAN_STATUS_RXOK_Msk; / *清除RxOK状态* /
        }

        if(CAN0-> STATUS&CAN_STATUS_TXOK_Msk)
        {
            CAN0-> STATUS&=〜CAN_STATUS_TXOK_Msk; / *清除TxOK状态* /
        }

        / *************** /
        / *错误状态中断* /
        / *************** /
        if(CAN0-> STATUS&CAN_STATUS_BOFF_Msk)
        {
            printf(“BOFF INT \ n”);
        }
        else if(CAN0-> STATUS&CAN_STATUS_EWARN_Msk)
        {
            printf(“EWARN INT \ n”);
        }
        else if((CAN0-> ERR&CAN_ERR_TEC_Msk)!= 0)
        {
            printf(“Transmit error!\ n”);
        }
        else if((CAN0-> ERR&CAN_ERR_REC_Msk)!= 0)
        {
            printf(“Receive error!\ n”);
        }
    }
    else if((u8IIDRstatus> = 0x1)||(u8IIDRstatus <= 0x20))
    {
        CAN_MsgInterrupt(CAN0,u8IIDRstatus);

        CAN_CLR_INT_PENDING_BIT(CAN0,(u8IIDRstatus - 1)); / *清除中断挂起* /
    }
    else if(CAN0-> WU_STATUS == 1)
    {
        printf(“唤醒\ n”);

        CAN0-> WU_STATUS = 0; / *写'0'清除* /
    }

}

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ *重置消息界面参数* /
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
void CAN_ResetIF(CAN_T * tCAN,uint8_t u8IF_Num)
{
    if(u8IF_Num> 1)
        返回;
    tCAN-> IF [u8IF_Num] .CREQ = 0x0; //设置bit15发送
    tCAN-> IF [u8IF_Num] .CMASK = 0x0;
    tCAN-> IF [u8IF_Num] .MASK1 = 0x0; //在基本模式下无用
    tCAN-> IF [u8IF_Num] .MASK2 = 0x0; //在基本模式下无用
    tCAN-> IF [u8IF_Num] .ARB1 = 0x0; // ID15〜0
    tCAN-> IF [u8IF_Num] .ARB2 = 0x0; // MsgVal,eXt,xmt,ID28〜16
    tCAN-> IF [u8IF_Num] .MCON = 0x0; // DLC
    tCAN-> IF [u8IF_Num] .DAT_A1 = 0x0; // data0,1
    tCAN-> IF [u8IF_Num] .DAT_A2 = 0x0; // data2,3
    tCAN-> IF [u8IF_Num] .DAT_B1 = 0x0; // data4,5
    tCAN-> IF [u8IF_Num] .DAT_B2 = 0x0; // data6,7
}

/ * ------------------------------------------------ --------------------------- * /
/ *显示消息功能* /
/ * ------------------------------------------------ --------------------------- * /
void CAN_ShowMsg(STR_CANMSG_T * Msg)
{
    uint8_t我

    / *显示消息信息* /
    printf(“Read ID = 0x%X,Type =%s,DLC =%d,Data =”,Msg-> Id,Msg-> IdType?“EXT”:“STD”,Msg-> DLC)
    for(i = 0; i <Msg-> DLC; i ++)
        printf(“%X”,Msg-> Data [i]);
    的printf( “\ n \ n”);
}

void SYS_Init(void)
{
    / * ------------------------------------------------ -------------------------------------------------- ------- * /
    / * Init系统时钟* /
    / * ------------------------------------------------ -------------------------------------------------- ------- * /

    / *启用内部RC 22.1184MHz时钟* /
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    / *等待内部RC时钟准备好* /
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    / *将HCLK时钟源切换到内部RC和HCLK源除法1 * /
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC,CLK_CLKDIV_HCLK(1));

    / *启用外部XTAL 12MHz时钟* /
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    / *等待外部XTAL时钟准备好* /
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    / *将内核时钟设置为PLL_CLOCK从PLL * /
    CLK_SetCoreClock(PLL_CLOCK);

    / *使能UART模块时钟* /
    CLK_EnableModuleClock(UART0_MODULE);

    / *使能CAN模块时钟* /
    CLK_EnableModuleClock(CAN0_MODULE);
    // CLK_EnableModuleClock(CAN1_MODULE);

    / *选择UART模块时钟源* /
    CLK_SetModuleClock(UART0_MODULE,CLK_CLKSEL1_UART_S_PLL,CLK_CLKDIV_UART(1));

    / * ------------------------------------------------ -------------------------------------------------- ------- * /
    / * Init I / O多功能* /
    / * ------------------------------------------------ -------------------------------------------------- ------- * /

    / *设置用于UART0的GPB多功能引脚RXD和TXD * /
    SYS-> GPB_MFP&=〜(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
    SYS-> GPB_MFP | = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

    / *设置CAN多功能引脚CANTX0,CANRX0 * /
    SYS-> GPD_MFP&=〜(SYS_GPD_MFP_PD6_Msk | SYS_GPD_MFP_PD7_Msk);
    SYS-> GPD_MFP = SYS_GPD_MFP_PD6_CAN0_RXD | SYS_GPD_MFP_PD7_CAN0_TXD;

}

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ * Init UART * /
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
void UART0_Init()
{
    / *重置IP * /
    SYS_ResetModule(UART0_RST);

    / *配置UART0并设置UART0波特率* /
    UART_Open(UART0,115200);
}

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/ *禁用CAN时钟并重置*
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
void CAN_STOP(void)
{
    / *禁用CAN0时钟并将其复位* /
    SYS_ResetModule(CAN0_RST);
    CLK_DisableModuleClock(CAN0_MODULE);
}

/ * ------------------------------------------------ ---------------------------- * /
/ *关于如何创建测试环境的一些描述* /
/ * ------------------------------------------------ ---------------------------- * /
void Note_Configure()
{
    的printf( “\ n \ n”);
    的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
    printf(“|关于CAN示例代码配置| \ n”);
    的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
    printf(“|示例代码为您学习CAN | \ n”提供了一个简单的示例代码);
    printf(“|执行前请检查下面的描述| \ n”);
    printf(“| | \ n”);
    printf(“| 1.CAN_TX和CAN_RX应连接到CAN收发器| \ n”);
    printf(“| 2.使用两个模块板并连接到相同的CAN总线| \ n”);
    printf(“| 3.检查总线的端子电阻是否连接| \ n”);
    printf(“| 4.使用UART0作为打印消息端口| \ n”);
    printf(“| | \ n”);
    printf(“| | -------- | | ----------- | CANBUS | ----------- | | -------- | | \ n“);
    printf(“| | | ------> | | <---------> | | <------ | | | \ n”);
    printf(“| | | CAN_TX | CAN | CAN_H | CAN | CAN_TX | | | \ n”);
    printf(“| | NUC131 | |收发器| |收发器| | NUC131 | | \ n”);
    printf(“| | | <------ | | <---------> | | ------> | | | \ n”);
    printf(“| | | CAN_RX | | CAN_L | | CAN_RX | | | \ n”);
    printf(“| | -------- | | ----------- | | ----------- | | -------- | | \ n“);
    printf(“| | | | \ n”);
    printf(“| | | | \ n”);
    printf(“| V V | \ n”);
    printf(“| UART0 UART0 | \ n”);
    printf(“|(打印消息)(打印消息)| \ n”);
    的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
}

/ * ------------------------------------------------ ---------------------------- * /
/ *检查真正的波特率* /
/ * ------------------------------------------------ ---------------------------- * /
void BaudRateCheck(uint32_t u32BaudRate,uint32_t u32RealBaudRate)
{
    / *获取核心时钟频率* /
    SystemCoreClockUpdate();

    if(u32BaudRate!= u32RealBaudRate)
    {
        printf(“\ n设置CAN波特率失败\ n”);
        printf(“实数波特率值(bps):%d \ n”,u32RealBaudRate);
        printf(“CAN波特率计算公式如下:\ n”);
        printf(“CAN波特率(bps)= Fin /(BPR + 1)*(Tseg1 + Tseg2 + 3)\ n”);
        printf(“其中:Fin:系统时钟频率(Hz)\ n”);
        printf(“BRP:波特率预分频比,由BRP(CAN_BTIME [5:0])和BRPE(CAN_BRPE [3:0])组成。
        printf(“Tseg1:采样点之前的时间段”,可以设置tseg1(CAN_BTIME [11:8])\ n“);
        printf(“Tseg2:采样点后的时间段”,可以设置tseg2(CAN_BTIME [14:12])。\ n“);

        if(SystemCoreClock%u32BaudRate!= 0)
            printf(“\ n BPR不计算,Fin必须是CAN波特率的倍数。\ n”);

        其他
            printf(“\ n BPR不计算,(Fin /(CAN波特率))必须是(Tseg1 + Tseg1 + 3)的倍数。
    }
    其他
        printf(“\ nReal波特率值(bps):%d \ n”,u32RealBaudRate);
}

/ * ------------------------------------------------ ---------------------------- * /
/ *设置CAN速度* /
/ * ------------------------------------------------ ---------------------------- * /
void SelectCANSpeed(CAN_T * tCAN)
{
    uint32_t unItem,BaudRate = 0,RealBaudRate = 0;

    printf(“请选择您想要的CAN速度\ n”);
    printf(“[0] 1000Kbps \ n”);
    printf(“[1] 800Kbps \ n”);
    printf(“[2] 500Kbps \ n”);
    printf(“[3] 250Kbps \ n”);
    printf(“[4] 125Kbps \ n”);
    printf(“[5] 100Kbps \ n”);
    printf(“[6] 50Kbps \ n”);

    unItem = GetChar();
    printf(“%c \ n”,unItem);

    开关(unItem)
    {
        情况'0':
            BaudRate = 1000000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE); //设置目标波特率和操作模式。
            打破;

        情况1':
            BaudRate = 800000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;

        案例'2':
            BaudRate = 500000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;

        案例'3':
            波特率= 250000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;

        情况'4':
            BaudRate = 125000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;

        案件'5':
            BaudRate = 100000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;

        个案'6':
            BaudRate = 50000;
            RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
            打破;
    }

    / *检查真正的波特率是OK * /
    BaudRateCheck(BaudRate,RealBaudRate);

}

/ * ------------------------------------------------ ---------------------------- * /
/ *测试菜单* /
/ * ------------------------------------------------ ---------------------------- * /
void TestItem(void)
{
    的printf( “\ n”);
    的printf(“+ ---------------------------------------------- -------------------- + \ n“);
    printf(“| Nuvoton CAN BUS DRIVER DEMO | \ n”);
    的printf(“+ ---------------------------------------------- --------------------- + \ n“);
    printf(“| | \ n”);
    printf(“|通过普通模式接收消息| \ n”);
    printf(“| | \ n”);
    的printf(“+ ---------------------------------------------- --------------------- + \ n“);
}

/ * ------------------------------------------------ ---------------------------- * /
/ *通过正常模式功能发送Rx消息(带消息RAM)* /
/ * ------------------------------------------------ ---------------------------- * /
void Test_NormalMode_Rx(CAN_T * tCAN)
{
    CAN_EnableInt(tCAN,CAN_CON_IE_Msk | CAN_CON_SIE_Msk); / *使能CAN中断和相应的NVIC CAN * /
    NVIC_SetPriority(CAN0_IRQn,(1 << __NVIC_PRIO_BITS) - 2); / *安装CAN回拨功能* /
    NVIC_EnableIRQ(CAN0_IRQn);

    if(CAN_SetRxMsg(tCAN,MSG(0),CAN_STD_ID,0x7FF)== FALSE)
    {
        printf(“设置Rx消息对象失败\ n”);
        返回;
    }

    if(CAN_SetRxMsg(tCAN,MSG(5),CAN_EXT_ID,0x12345)== FALSE)
    {
        printf(“设置Rx消息对象失败\ n”);
        返回;
    }

    if(CAN_SetRxMsg(tCAN,MSG(31),CAN_EXT_ID,0x7FF01)== FALSE)
    {
        printf(“设置Rx消息对象失败\ n”);
        返回;
    }

    printf(“Wait Msg \ n”);
    printf(“Enter any key to exit \ n”);
    的getchar();

}

/ * ------------------------------------------------ -------------------------------------------------- ------- * /
/* 主功能 */
/ * ------------------------------------------------ -------------------------------------------------- ------- * /
int main(void)
{
    CAN_T * tCAN;
    tCAN =(CAN_T *)CAN0;

    / *解锁保护的寄存器* /
    SYS_UnlockReg();

    / * Init系统,IP时钟和多功能I / O * /
    SYS_Init();

    / *锁定保护寄存器* /
    SYS_LockReg();

    / * Init UART0 for printf * /
    UART0_Init();

    / * ------------------------------------------------ -------------------------------------------------- ------- * /
    / *样品代码* /
    / * ------------------------------------------------ -------------------------------------------------- ------- * /

    / *关于如何创建测试环境的一些描述* /
    Note_Configure();

    / *配置位时序* /
    SelectCANSpeed(TCAN);

    / *测试菜单* /
    TestItem();

    printf(“通过普通模式接收消息\ n \ n”);

    / *通过正常模式功能发送Rx消息(带消息RAM)* /
    Test_NormalMode_Rx(TCAN);

    / *禁用CAN * /
    CAN_Close(TCAN);

    / *禁用CAN时钟并重置*
    CAN_STOP();

    而(1);

}



发现网页自带的翻译,还可以翻译这个语句。。。如果看不懂的注释,以后有救了。

使用特权

评论回复
7
xixi2017| | 2017-10-3 17:24 | 只看该作者
谷歌翻译不错,可以识别程序代码?

使用特权

评论回复
8
稳稳の幸福| | 2017-10-4 21:41 | 只看该作者
电梯通信中应该也是用的这个协议完成的

使用特权

评论回复
9
515192147| | 2017-10-5 10:52 | 只看该作者
本帖最后由 515192147 于 2017-10-7 08:52 编辑

这个 芯片 啥价格?要是 性价比 好的话,我有空 将这个芯片的CAN的高层协议CANWeb 开放源码
搞出来,方便用户开发。
CANweb是结合CAN和以太网优点的CAN现场总线高层协议,比CANOpen\DeviceNet\iCAN简易、好用
详细见:
https://bbs.21ic.com/icview-1945634-1-1.html

使用特权

评论回复
10
gejigeji521| | 2017-10-5 12:29 | 只看该作者
看来看去还是新唐的代码舒心。

使用特权

评论回复
11
稳稳の幸福| | 2017-10-6 22:04 | 只看该作者
通过消息的形式传输数据

使用特权

评论回复
12
vunese| | 2017-10-16 21:25 | 只看该作者
请问楼主,当有数据进来,进入CAN0中断函数,状态中断(主要TxOK\RxOK)与报文对象中断哪个先触发?是会进两次中断函数吗?if(u8IIDRstatus == 0x00008000)与 else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20)),u8IIDRstatus的值不可能同时满足这两个if语句,那么就是说这个中断会连续两次吗?

使用特权

评论回复
13
sopc12| | 2017-12-4 14:29 | 只看该作者
有更多的资料说明吗?

使用特权

评论回复
14
734774645| | 2017-12-15 21:07 | 只看该作者
还没怎么用过CAN呢,学习学习。

使用特权

评论回复
15
wahahaheihei|  楼主 | 2017-12-17 22:14 | 只看该作者
想真的学懂,需要先看看CAN协议。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

197

主题

2975

帖子

12

粉丝