[DemoCode下载] NUC131的CAN例程序

[复制链接]
 楼主| wahahaheihei 发表于 2017-10-1 14:00 | 显示全部楼层 |阅读模式
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.0
  4. * $Revision: 8 $
  5. * $Date: 15/01/16 1:45p $
  6. * @brief
  7. *           Implement receive message in Normal mode.
  8. *           This sample code needs to work with CAN_NormalMode_Transmit.
  9. * @note
  10. * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
  11. *
  12. ******************************************************************************/
  13. #include <stdio.h>
  14. #include "NUC131.h"


  15. #define PLL_CLOCK       48000000

  16. /*---------------------------------------------------------------------------*/
  17. /*  Function Declare                                                         */
  18. /*---------------------------------------------------------------------------*/
  19. extern char GetChar(void);
  20. void CAN_ShowMsg(STR_CANMSG_T* Msg);

  21. /*---------------------------------------------------------------------------------------------------------*/
  22. /* Define global variables and constants                                                                   */
  23. /*---------------------------------------------------------------------------------------------------------*/
  24. /* Declare a CAN message structure */
  25. STR_CANMSG_T rrMsg;


  26. /*---------------------------------------------------------------------------------------------------------*/
  27. /* ISR to handle CAN interrupt event                                                                       */
  28. /*---------------------------------------------------------------------------------------------------------*/
  29. void CAN_MsgInterrupt(CAN_T *tCAN, uint32_t u32IIDR)
  30. {
  31.     if(u32IIDR == 1)
  32.     {
  33.         //printf("Msg-0 INT and Callback\n");
  34.         CAN_Receive(tCAN, 0, &rrMsg);
  35.         CAN_ShowMsg(&rrMsg);
  36.     }
  37.     if(u32IIDR == 5 + 1)
  38.     {
  39.         //printf("Msg-5 INT and Callback \n");
  40.         CAN_Receive(tCAN, 5, &rrMsg);
  41.         CAN_ShowMsg(&rrMsg);
  42.     }
  43.     if(u32IIDR == 31 + 1)
  44.     {
  45.         //printf("Msg-31 INT and Callback \n");
  46.         CAN_Receive(tCAN, 31, &rrMsg);
  47.         CAN_ShowMsg(&rrMsg);
  48.     }
  49. }

  50. /*---------------------------------------------------------------------------------------------------------*/
  51. /* CAN0 interrupt handler                                                                                  */
  52. /*---------------------------------------------------------------------------------------------------------*/
  53. void CAN0_IRQHandler(void)
  54. {
  55.     uint32_t u8IIDRstatus;

  56.     u8IIDRstatus = CAN0->IIDR;

  57.     if(u8IIDRstatus == 0x00008000)        /* Check Status Interrupt Flag (Error status Int and Status change Int) */
  58.     {
  59.         /**************************/
  60.         /* Status Change interrupt*/
  61.         /**************************/
  62.         if(CAN0->STATUS & CAN_STATUS_RXOK_Msk)
  63.         {
  64.             CAN0->STATUS &= ~CAN_STATUS_RXOK_Msk;   /* Clear RxOK status*/
  65.         }

  66.         if(CAN0->STATUS & CAN_STATUS_TXOK_Msk)
  67.         {
  68.             CAN0->STATUS &= ~CAN_STATUS_TXOK_Msk;    /* Clear TxOK status*/
  69.         }

  70.         /**************************/
  71.         /* Error Status interrupt */
  72.         /**************************/
  73.         if(CAN0->STATUS & CAN_STATUS_BOFF_Msk)
  74.         {
  75.             printf("BOFF INT\n") ;
  76.         }
  77.         else if(CAN0->STATUS & CAN_STATUS_EWARN_Msk)
  78.         {
  79.             printf("EWARN INT\n") ;
  80.         }
  81.         else if((CAN0->ERR & CAN_ERR_TEC_Msk) != 0)
  82.         {
  83.             printf("Transmit error!\n") ;
  84.         }
  85.         else if((CAN0->ERR & CAN_ERR_REC_Msk) != 0)
  86.         {
  87.             printf("Receive error!\n") ;
  88.         }
  89.     }
  90.     else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20))
  91.     {
  92.         CAN_MsgInterrupt(CAN0, u8IIDRstatus);

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

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

  100. }

  101. /*---------------------------------------------------------------------------------------------------------*/
  102. /* Reset message interface parameters                                                                      */
  103. /*---------------------------------------------------------------------------------------------------------*/
  104. void CAN_ResetIF(CAN_T *tCAN, uint8_t u8IF_Num)
  105. {
  106.     if(u8IF_Num > 1)
  107.         return;
  108.     tCAN->IF[u8IF_Num].CREQ     = 0x0;          // set bit15 for sending
  109.     tCAN->IF[u8IF_Num].CMASK    = 0x0;
  110.     tCAN->IF[u8IF_Num].MASK1    = 0x0;          // useless in basic mode
  111.     tCAN->IF[u8IF_Num].MASK2    = 0x0;          // useless in basic mode
  112.     tCAN->IF[u8IF_Num].ARB1     = 0x0;          // ID15~0
  113.     tCAN->IF[u8IF_Num].ARB2     = 0x0;          // MsgVal, eXt, xmt, ID28~16
  114.     tCAN->IF[u8IF_Num].MCON     = 0x0;          // DLC
  115.     tCAN->IF[u8IF_Num].DAT_A1   = 0x0;          // data0,1
  116.     tCAN->IF[u8IF_Num].DAT_A2   = 0x0;          // data2,3
  117.     tCAN->IF[u8IF_Num].DAT_B1   = 0x0;          // data4,5
  118.     tCAN->IF[u8IF_Num].DAT_B2   = 0x0;          // data6,7
  119. }

  120. /*---------------------------------------------------------------------------*/
  121. /*  Show Message Function                                                    */
  122. /*---------------------------------------------------------------------------*/
  123. void CAN_ShowMsg(STR_CANMSG_T* Msg)
  124. {
  125.     uint8_t i;

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

  132. void SYS_Init(void)
  133. {
  134.     /*---------------------------------------------------------------------------------------------------------*/
  135.     /* Init System Clock                                                                                       */
  136.     /*---------------------------------------------------------------------------------------------------------*/

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

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

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

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

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

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

  149.     /* Enable UART module clock */
  150.     CLK_EnableModuleClock(UART0_MODULE);

  151.     /* Enable CAN module clock */
  152.     CLK_EnableModuleClock(CAN0_MODULE);
  153.     //CLK_EnableModuleClock(CAN1_MODULE);

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

  156.     /*---------------------------------------------------------------------------------------------------------*/
  157.     /* Init I/O Multi-function                                                                                 */
  158.     /*---------------------------------------------------------------------------------------------------------*/

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

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

  165. }

  166. /*---------------------------------------------------------------------------------------------------------*/
  167. /* Init UART                                                                                               */
  168. /*---------------------------------------------------------------------------------------------------------*/
  169. void UART0_Init()
  170. {
  171.     /* Reset IP */
  172.     SYS_ResetModule(UART0_RST);

  173.     /* Configure UART0 and set UART0 Baudrate */
  174.     UART_Open(UART0, 115200);
  175. }

  176. /*---------------------------------------------------------------------------------------------------------*/
  177. /* Disable CAN Clock and Reset it                                                                          */
  178. /*---------------------------------------------------------------------------------------------------------*/
  179. void CAN_STOP(void)
  180. {
  181.     /* Disable CAN0 Clock and Reset it */
  182.     SYS_ResetModule(CAN0_RST);
  183.     CLK_DisableModuleClock(CAN0_MODULE);
  184. }

  185. /*----------------------------------------------------------------------------*/
  186. /*  Some description about how to create test environment                     */
  187. /*----------------------------------------------------------------------------*/
  188. void Note_Configure()
  189. {
  190.     printf("\n\n");
  191.     printf("+--------------------------------------------------------------------------+\n");
  192.     printf("|  About CAN sample code configure                                         |\n");
  193.     printf("+--------------------------------------------------------------------------+\n");
  194.     printf("|   The sample code provide a simple sample code for you study CAN         |\n");
  195.     printf("|   Before execute it, please check description as below                   |\n");
  196.     printf("|                                                                          |\n");
  197.     printf("|   1.CAN_TX and CAN_RX should be connected to your CAN transceiver        |\n");
  198.     printf("|   2.Using two module board and connect to the same CAN BUS               |\n");
  199.     printf("|   3.Check the terminal resistor of bus is connected                      |\n");
  200.     printf("|   4.Using UART0 as print message port                                    |\n");
  201.     printf("|                                                                          |\n");
  202.     printf("|  |--------|       |-----------|   CANBUS  |-----------|       |--------| |\n");
  203.     printf("|  |        |------>|           |<--------->|           |<------|        | |\n");
  204.     printf("|  |        |CAN_TX |    CAN    |   CAN_H   |   CAN     |CAN_TX |        | |\n");
  205.     printf("|  | NUC131 |       |Transceiver|           |Transceiver|       | NUC131 | |\n");
  206.     printf("|  |        |<------|           |<--------->|           |------>|        | |\n");
  207.     printf("|  |        |CAN_RX |           |   CAN_L   |           |CAN_RX |        | |\n");
  208.     printf("|  |--------|       |-----------|           |-----------|       |--------| |\n");
  209.     printf("|  |                                                            |          |\n");
  210.     printf("|  |                                                            |          |\n");
  211.     printf("|  V                                                            V          |\n");
  212.     printf("| UART0                                                         UART0      |\n");
  213.     printf("|(print message)                                          (print message)  |\n");
  214.     printf("+--------------------------------------------------------------------------+\n");
  215. }

  216. /*----------------------------------------------------------------------------*/
  217. /*  Check the real baud-rate                                                  */
  218. /*----------------------------------------------------------------------------*/
  219. void BaudRateCheck(uint32_t u32BaudRate, uint32_t u32RealBaudRate)
  220. {
  221.     /* Get Core Clock Frequency */
  222.     SystemCoreClockUpdate();

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

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

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

  241. /*----------------------------------------------------------------------------*/
  242. /*  Set the CAN speed                                                         */
  243. /*----------------------------------------------------------------------------*/
  244. void SelectCANSpeed(CAN_T  *tCAN)
  245. {
  246.     uint32_t unItem, BaudRate = 0, RealBaudRate = 0;

  247.     printf("Please select CAN speed you desired\n");
  248.     printf("[0] 1000Kbps\n");
  249.     printf("[1]  800Kbps\n");
  250.     printf("[2]  500Kbps\n");
  251.     printf("[3]  250Kbps\n");
  252.     printf("[4]  125Kbps\n");
  253.     printf("[5]  100Kbps\n");
  254.     printf("[6]   50Kbps\n");

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

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

  263.         case '1':
  264.             BaudRate = 800000;
  265.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  266.             break;

  267.         case '2':
  268.             BaudRate = 500000;
  269.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  270.             break;

  271.         case '3':
  272.             BaudRate = 250000;
  273.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  274.             break;

  275.         case '4':
  276.             BaudRate = 125000;
  277.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  278.             break;

  279.         case '5':
  280.             BaudRate = 100000;
  281.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  282.             break;

  283.         case '6':
  284.             BaudRate = 50000;
  285.             RealBaudRate = CAN_Open(tCAN,  BaudRate, CAN_NORMAL_MODE);
  286.             break;
  287.     }

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

  290. }

  291. /*----------------------------------------------------------------------------*/
  292. /*  Test Menu                                                                 */
  293. /*----------------------------------------------------------------------------*/
  294. void TestItem(void)
  295. {
  296.     printf("\n");
  297.     printf("+------------------------------------------------------------------ +\n");
  298.     printf("|  Nuvoton CAN BUS DRIVER DEMO                                      |\n");
  299.     printf("+-------------------------------------------------------------------+\n");
  300.     printf("|                                                                   |\n");
  301.     printf("|      Receive a message by normal mode                             |\n");
  302.     printf("|                                                                   |\n");
  303.     printf("+-------------------------------------------------------------------+\n");
  304. }

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

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

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

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

  328.     printf("Wait Msg\n");
  329.     printf("Enter any key to exit\n");
  330.     GetChar();

  331. }

  332. /*---------------------------------------------------------------------------------------------------------*/
  333. /* MAIN function                                                                                           */
  334. /*---------------------------------------------------------------------------------------------------------*/
  335. int main(void)
  336. {
  337.     CAN_T *tCAN;
  338.     tCAN = (CAN_T *) CAN0;

  339.     /* Unlock protected registers */
  340.     SYS_UnlockReg();

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

  343.     /* Lock protected registers */
  344.     SYS_LockReg();

  345.     /* Init UART0 for printf */
  346.     UART0_Init();

  347.     /*---------------------------------------------------------------------------------------------------------*/
  348.     /* SAMPLE CODE                                                                                             */
  349.     /*---------------------------------------------------------------------------------------------------------*/

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

  352.     /* Configuring the Bit Timing */
  353.     SelectCANSpeed(tCAN);

  354.     /* Test Menu */
  355.     TestItem();

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

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

  359.     /* Disable CAN */
  360.     CAN_Close(tCAN);

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

  363.     while(1);

  364. }




 楼主| wahahaheihei 发表于 2017-10-1 14:00 | 显示全部楼层
有人看完觉得怎么中断处理函数一样啊,好奇怪,其实不是。是为了方便当初写代码的人,写一起了。
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /* CAN0 interrupt handler                                                                                  */
  3. /*---------------------------------------------------------------------------------------------------------*/
  4. void CAN0_IRQHandler(void)
  5. {
  6.     uint32_t u8IIDRstatus;

  7.     u8IIDRstatus = CAN0->IIDR;

  8.     if(u8IIDRstatus == 0x00008000)        /* Check Status Interrupt Flag (Error status Int and Status change Int) */
  9.     {
  10.         /**************************/
  11.         /* Status Change interrupt*/
  12.         /**************************/
  13.         if(CAN0->STATUS & CAN_STATUS_RXOK_Msk)
  14.         {
  15.             CAN0->STATUS &= ~CAN_STATUS_RXOK_Msk;   /* Clear RxOK status*/
  16.         }

  17.         if(CAN0->STATUS & CAN_STATUS_TXOK_Msk)
  18.         {
  19.             CAN0->STATUS &= ~CAN_STATUS_TXOK_Msk;    /* Clear TxOK status*/
  20.         }

  21.         /**************************/
  22.         /* Error Status interrupt */
  23.         /**************************/
  24.         if(CAN0->STATUS & CAN_STATUS_BOFF_Msk)
  25.         {
  26.             printf("BOFF INT\n") ;
  27.         }
  28.         else if(CAN0->STATUS & CAN_STATUS_EWARN_Msk)
  29.         {
  30.             printf("EWARN INT\n") ;
  31.         }
  32.         else if((CAN0->ERR & CAN_ERR_TEC_Msk) != 0)
  33.         {
  34.             printf("Transmit error!\n") ;
  35.         }
  36.         else if((CAN0->ERR & CAN_ERR_REC_Msk) != 0)
  37.         {
  38.             printf("Receive error!\n") ;
  39.         }
  40.     }
  41.     else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20))
  42.     {
  43.         CAN_MsgInterrupt(CAN0, u8IIDRstatus);

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

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

  51. }
 楼主| wahahaheihei 发表于 2017-10-1 14:01 | 显示全部楼层
我们可以看到有判断是接受还是发送的部分,其实就是这里来实现接收和发送中断的区分的。
yiy 发表于 2017-10-1 19:21 | 显示全部楼层
  1.     printf("|  |--------|       |-----------|   CANBUS  |-----------|       |--------| |\n");
  2.     printf("|  |        |------>|           |<--------->|           |<------|        | |\n");
  3.     printf("|  |        |CAN_TX |    CAN    |   CAN_H   |   CAN     |CAN_TX |        | |\n");
  4.     printf("|  | NUC131 |       |Transceiver|           |Transceiver|       | NUC131 | |\n");
  5.     printf("|  |        |<------|           |<--------->|           |------>|        | |\n");
  6.     printf("|  |        |CAN_RX |           |   CAN_L   |           |CAN_RX |        | |\n");
  7.     printf("|  |--------|       |-----------|           |-----------|       |--------| |\n");
  8.     printf("|  |                                                            |          |\n");
  9.     printf("|  |                                                            |          |\n");

这种字符图怎么做?
598330983 发表于 2017-10-1 21:51 来自手机 | 显示全部楼层
楼上的,那是人家手工做的,你复制几行空格,然后替换对应字符,就排列整齐了,然后把每行复制到printf中
heisexingqisi 发表于 2017-10-3 10:08 | 显示全部楼层
  1. / ******************* ***************************
  2. * [url = home.php?mod = space&uid = 288409] [url=home.php?mod=space&uid=288409]@file[/url] [/ url] main.c
  3. * [url = home.php?mod = space&uid = 895143] [url=home.php?mod=space&uid=895143]@version[/url] [/ url] V2.0
  4. * $修订:8 $
  5. * $日期:15/01/16 1:45p $
  6. * @brief
  7. *在正常模式下实现接收消息。
  8. *此示例代码需要使用CAN_NormalMode_Transmit。
  9. * @注意
  10. *版权所有(C)2014 Nuvoton Technology Corp.保留所有权利。
  11. *
  12. ************************************************** ************ /
  13. #include <stdio.h>
  14. #include“NUC131.h”


  15. #define PLL_CLOCK 48000000

  16. / * ------------------------------------------------ --------------------------- * /
  17. / *函数声明* /
  18. / * ------------------------------------------------ --------------------------- * /
  19. extern char GetChar(void);
  20. void CAN_ShowMsg(STR_CANMSG_T * Msg);

  21. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  22. / *定义全局变量和常量* /
  23. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  24. / *声明一个CAN消息结构* /
  25. STR_CANMSG_T rrMsg;


  26. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  27. / * ISR来处理CAN中断事件* /
  28. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  29. void CAN_MsgInterrupt(CAN_T * tCAN,uint32_t u32IIDR)
  30. {
  31.     if(u32IIDR == 1)
  32.     {
  33.         // printf(“Msg-0 INT and Callback \ n”);
  34.         CAN_Receive(tCAN,0,&rrMsg);
  35.         CAN_ShowMsg(&rrMsg);
  36.     }
  37.     if(u32IIDR == 5 + 1)
  38.     {
  39.         // printf(“Msg-5 INT and Callback \ n”);
  40.         CAN_Receive(tCAN,5,&rrMsg);
  41.         CAN_ShowMsg(&rrMsg);
  42.     }
  43.     if(u32IIDR == 31 + 1)
  44.     {
  45.         // printf(“Msg-31 INT and Callback \ n”);
  46.         CAN_Receive(tCAN,31,&rrMsg);
  47.         CAN_ShowMsg(&rrMsg);
  48.     }
  49. }

  50. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  51. / * CAN0中断处理程序* /
  52. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  53. void CAN0_IRQHandler(void)
  54. {
  55.     uint32_t u8IIDRstatus;

  56.     u8IIDRstatus = CAN0-> IIDR;

  57.     if(u8IIDRstatus == 0x00008000)/ *检查状态中断标志(错误状态Int和状态改变Int)* /
  58.     {
  59.         / *************** /
  60.         / *状态更改中断* /
  61.         / *************** /
  62.         如果(CAN0-> STATUS&CAN_STATUS_RXOK_Msk)
  63.         {
  64.             CAN0-> STATUS&=〜CAN_STATUS_RXOK_Msk; / *清除RxOK状态* /
  65.         }

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

  70.         / *************** /
  71.         / *错误状态中断* /
  72.         / *************** /
  73.         if(CAN0-> STATUS&CAN_STATUS_BOFF_Msk)
  74.         {
  75.             printf(“BOFF INT \ n”);
  76.         }
  77.         else if(CAN0-> STATUS&CAN_STATUS_EWARN_Msk)
  78.         {
  79.             printf(“EWARN INT \ n”);
  80.         }
  81.         else if((CAN0-> ERR&CAN_ERR_TEC_Msk)!= 0)
  82.         {
  83.             printf(“Transmit error!\ n”);
  84.         }
  85.         else if((CAN0-> ERR&CAN_ERR_REC_Msk)!= 0)
  86.         {
  87.             printf(“Receive error!\ n”);
  88.         }
  89.     }
  90.     else if((u8IIDRstatus> = 0x1)||(u8IIDRstatus <= 0x20))
  91.     {
  92.         CAN_MsgInterrupt(CAN0,u8IIDRstatus);

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

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

  100. }

  101. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  102. / *重置消息界面参数* /
  103. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  104. void CAN_ResetIF(CAN_T * tCAN,uint8_t u8IF_Num)
  105. {
  106.     if(u8IF_Num> 1)
  107.         返回;
  108.     tCAN-> IF [u8IF_Num] .CREQ = 0x0; //设置bit15发送
  109.     tCAN-> IF [u8IF_Num] .CMASK = 0x0;
  110.     tCAN-> IF [u8IF_Num] .MASK1 = 0x0; //在基本模式下无用
  111.     tCAN-> IF [u8IF_Num] .MASK2 = 0x0; //在基本模式下无用
  112.     tCAN-> IF [u8IF_Num] .ARB1 = 0x0; // ID15〜0
  113.     tCAN-> IF [u8IF_Num] .ARB2 = 0x0; // MsgVal,eXt,xmt,ID28〜16
  114.     tCAN-> IF [u8IF_Num] .MCON = 0x0; // DLC
  115.     tCAN-> IF [u8IF_Num] .DAT_A1 = 0x0; // data0,1
  116.     tCAN-> IF [u8IF_Num] .DAT_A2 = 0x0; // data2,3
  117.     tCAN-> IF [u8IF_Num] .DAT_B1 = 0x0; // data4,5
  118.     tCAN-> IF [u8IF_Num] .DAT_B2 = 0x0; // data6,7
  119. }

  120. / * ------------------------------------------------ --------------------------- * /
  121. / *显示消息功能* /
  122. / * ------------------------------------------------ --------------------------- * /
  123. void CAN_ShowMsg(STR_CANMSG_T * Msg)
  124. {
  125.     uint8_t我

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

  132. void SYS_Init(void)
  133. {
  134.     / * ------------------------------------------------ -------------------------------------------------- ------- * /
  135.     / * Init系统时钟* /
  136.     / * ------------------------------------------------ -------------------------------------------------- ------- * /

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

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

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

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

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

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

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

  151.     / *使能CAN模块时钟* /
  152.     CLK_EnableModuleClock(CAN0_MODULE);
  153.     // CLK_EnableModuleClock(CAN1_MODULE);

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

  156.     / * ------------------------------------------------ -------------------------------------------------- ------- * /
  157.     / * Init I / O多功能* /
  158.     / * ------------------------------------------------ -------------------------------------------------- ------- * /

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

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

  165. }

  166. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  167. / * Init UART * /
  168. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  169. void UART0_Init()
  170. {
  171.     / *重置IP * /
  172.     SYS_ResetModule(UART0_RST);

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

  176. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  177. / *禁用CAN时钟并重置*
  178. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  179. void CAN_STOP(void)
  180. {
  181.     / *禁用CAN0时钟并将其复位* /
  182.     SYS_ResetModule(CAN0_RST);
  183.     CLK_DisableModuleClock(CAN0_MODULE);
  184. }

  185. / * ------------------------------------------------ ---------------------------- * /
  186. / *关于如何创建测试环境的一些描述* /
  187. / * ------------------------------------------------ ---------------------------- * /
  188. void Note_Configure()
  189. {
  190.     的printf( “\ n \ n”);
  191.     的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
  192.     printf(“|关于CAN示例代码配置| \ n”);
  193.     的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
  194.     printf(“|示例代码为您学习CAN | \ n”提供了一个简单的示例代码);
  195.     printf(“|执行前请检查下面的描述| \ n”);
  196.     printf(“| | \ n”);
  197.     printf(“| 1.CAN_TX和CAN_RX应连接到CAN收发器| \ n”);
  198.     printf(“| 2.使用两个模块板并连接到相同的CAN总线| \ n”);
  199.     printf(“| 3.检查总线的端子电阻是否连接| \ n”);
  200.     printf(“| 4.使用UART0作为打印消息端口| \ n”);
  201.     printf(“| | \ n”);
  202.     printf(“| | -------- | | ----------- | CANBUS | ----------- | | -------- | | \ n“);
  203.     printf(“| | | ------> | | <---------> | | <------ | | | \ n”);
  204.     printf(“| | | CAN_TX | CAN | CAN_H | CAN | CAN_TX | | | \ n”);
  205.     printf(“| | NUC131 | |收发器| |收发器| | NUC131 | | \ n”);
  206.     printf(“| | | <------ | | <---------> | | ------> | | | \ n”);
  207.     printf(“| | | CAN_RX | | CAN_L | | CAN_RX | | | \ n”);
  208.     printf(“| | -------- | | ----------- | | ----------- | | -------- | | \ n“);
  209.     printf(“| | | | \ n”);
  210.     printf(“| | | | \ n”);
  211.     printf(“| V V | \ n”);
  212.     printf(“| UART0 UART0 | \ n”);
  213.     printf(“|(打印消息)(打印消息)| \ n”);
  214.     的printf(“+ ---------------------------------------------- ---------------------------- + \ n“);
  215. }

  216. / * ------------------------------------------------ ---------------------------- * /
  217. / *检查真正的波特率* /
  218. / * ------------------------------------------------ ---------------------------- * /
  219. void BaudRateCheck(uint32_t u32BaudRate,uint32_t u32RealBaudRate)
  220. {
  221.     / *获取核心时钟频率* /
  222.     SystemCoreClockUpdate();

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

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

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

  241. / * ------------------------------------------------ ---------------------------- * /
  242. / *设置CAN速度* /
  243. / * ------------------------------------------------ ---------------------------- * /
  244. void SelectCANSpeed(CAN_T * tCAN)
  245. {
  246.     uint32_t unItem,BaudRate = 0,RealBaudRate = 0;

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

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

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

  263.         情况1':
  264.             BaudRate = 800000;
  265.             RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
  266.             打破;

  267.         案例'2':
  268.             BaudRate = 500000;
  269.             RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
  270.             打破;

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

  275.         情况'4':
  276.             BaudRate = 125000;
  277.             RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
  278.             打破;

  279.         案件'5':
  280.             BaudRate = 100000;
  281.             RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
  282.             打破;

  283.         个案'6':
  284.             BaudRate = 50000;
  285.             RealBaudRate = CAN_Open(tCAN,BaudRate,CAN_NORMAL_MODE);
  286.             打破;
  287.     }

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

  290. }

  291. / * ------------------------------------------------ ---------------------------- * /
  292. / *测试菜单* /
  293. / * ------------------------------------------------ ---------------------------- * /
  294. void TestItem(void)
  295. {
  296.     的printf( “\ n”);
  297.     的printf(“+ ---------------------------------------------- -------------------- + \ n“);
  298.     printf(“| Nuvoton CAN BUS DRIVER DEMO | \ n”);
  299.     的printf(“+ ---------------------------------------------- --------------------- + \ n“);
  300.     printf(“| | \ n”);
  301.     printf(“|通过普通模式接收消息| \ n”);
  302.     printf(“| | \ n”);
  303.     的printf(“+ ---------------------------------------------- --------------------- + \ n“);
  304. }

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

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

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

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

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

  331. }

  332. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  333. /* 主功能 */
  334. / * ------------------------------------------------ -------------------------------------------------- ------- * /
  335. int main(void)
  336. {
  337.     CAN_T * tCAN;
  338.     tCAN =(CAN_T *)CAN0;

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

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

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

  345.     / * Init UART0 for printf * /
  346.     UART0_Init();

  347.     / * ------------------------------------------------ -------------------------------------------------- ------- * /
  348.     / *样品代码* /
  349.     / * ------------------------------------------------ -------------------------------------------------- ------- * /

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

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

  354.     / *测试菜单* /
  355.     TestItem();

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

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

  359.     / *禁用CAN * /
  360.     CAN_Close(TCAN);

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

  363.     而(1);

  364. }



发现网页自带的翻译,还可以翻译这个语句。。。如果看不懂的注释,以后有救了。
xixi2017 发表于 2017-10-3 17:24 | 显示全部楼层
谷歌翻译不错,可以识别程序代码?
稳稳の幸福 发表于 2017-10-4 21:41 来自手机 | 显示全部楼层
电梯通信中应该也是用的这个协议完成的
515192147 发表于 2017-10-5 10:52 | 显示全部楼层
本帖最后由 515192147 于 2017-10-7 08:52 编辑

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

gejigeji521 发表于 2017-10-5 12:29 | 显示全部楼层
看来看去还是新唐的代码舒心。
稳稳の幸福 发表于 2017-10-6 22:04 | 显示全部楼层
通过消息的形式传输数据
vunese 发表于 2017-10-16 21:25 | 显示全部楼层
请问楼主,当有数据进来,进入CAN0中断函数,状态中断(主要TxOK\RxOK)与报文对象中断哪个先触发?是会进两次中断函数吗?if(u8IIDRstatus == 0x00008000)与 else if((u8IIDRstatus >= 0x1) || (u8IIDRstatus <= 0x20)),u8IIDRstatus的值不可能同时满足这两个if语句,那么就是说这个中断会连续两次吗?
sopc12 发表于 2017-12-4 14:29 | 显示全部楼层
有更多的资料说明吗?
734774645 发表于 2017-12-15 21:07 | 显示全部楼层
还没怎么用过CAN呢,学习学习。
 楼主| wahahaheihei 发表于 2017-12-17 22:14 | 显示全部楼层
想真的学懂,需要先看看CAN协议。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

231

主题

3196

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部

231

主题

3196

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部