打印
[ModusToolbox™]

【英飞凌CYW20829测评】篇四 蓝牙之CANFD测试

[复制链接]
1139|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、概述
CANFD简介:
  • CANFD是CAN 2.0的升级版,主要解决了传统CAN总线在传输速率和数据长度上的限制。
  • 它通过增加数据域的传输速率和长度,满足了现代汽车和工业应用中对高速、大数据量通信的需求。
CYW20829与CANFD:
  • CYW20829是英飞凌(Infineon)推出的一款高度集成的蓝牙LE 5.4 MCU,专为需要长距离和良好噪声免疫力的应用而设计。该MCU集成了CAN FD功能,使其能够支持高速、大数据量的通信需求。CYW20829支持一个CAN FD通道的CAN FD控制器。所有CAN FD控制器均符合ISO 11898-1:2015标准;同时提供ISO 16845:2015证书。此外,它还完全在硬件中实现了ISO 11898-4中指定的时间触发CAN(TTCAN)协议(TTCAN协议级别1和2)。与消息处理相关的所有功能均由RX(接收)和TX(发送)处理程序实现。RX处理程序管理消息的接受过滤,将从CAN核心接收到的消息传输到消息RAM,并提供接收消息的状态。TX处理程序负责将发送消息从消息RAM传输到CAN核心,并提供发送消息的状态。
  •    CYW20829还包含一个LIN通道。每个通道都支持根据ISO标准17987的LIN协议进行数据的发送/接收。每个LIN通道都通过一个3引脚接口(包括使能功能)连接到外部收发器,并支持主从功能。每个模块还支持经典和增强的校验和,以及在消息接收过程中的中断检测和唤醒信号。中断检测、同步字段、校验和计算以及错误中断都在硬件中处理。
    CYW20829中的CANFD(Controller Area Network with Flexible Data-Rate,可变速率的CAN)是该微控制器单元(MCU)的一个重要特性,它提供了比传统CAN总线更高的传输速度和数据长度。


二、技术特点
传输速率:
  • CAN FD的传输速率可达到8Mbps(数据比特率),远高于传统CAN总线的1Mbps(仲裁比特率)。
  • 这意味着CYW20829在数据传输速度上具有显著优势。
数据长度:
  • CAN FD支持的数据域长度最长可达64字节,而传统CAN总线的数据域长度最长为8字节。
  • 这使得CYW20829能够传输更多的数据,满足更复杂的应用需求。
帧格式:
  • CAN FD采用了可变速率的帧格式,即在控制场中的BRS(Bit Rate Switch)位之后,数据段的传输速率可以高于仲裁段的传输速率。
  • 这种设计使得CAN FD在保持仲裁段低速率以保证通信稳定性的同时,提高了数据段的传输速率。
三、应用场景
由于CYW20829集成了CAN FD功能,因此它非常适合于需要高速、大数据量通信的应用场景,如:
  • 智能家居:通过CAN FD实现设备间的快速、可靠通信。
  • 医疗健康:在医疗设备中传输大量医疗数据。
  • 工业自动化:在工业自动化系统中实现设备间的实时通信和数据交换。
  • 汽车电子:满足汽车内部各种元件之间的高速通信需求。
四、开发测试       Using Eclipse IDE for ModusToolbox™ software     引脚分配

  • code
  • #include <stdio.h>
    #include <string.h>
    #include "cyhal.h"
    #include "cy_pdl.h"
    #include "cybsp.h"
    #include "cy_retarget_io.h"

    /*******************************************************************************
    * Macros
    *******************************************************************************/
    /* CAN-FD message identifier 1*/
    #define CANFD_NODE_1            1
    /* CAN-FD message identifier 2 (use different for 2nd device) */
    #define CANFD_NODE_2            2
    /* message Identifier used for this code */
    #define USE_CANFD_NODE          CANFD_NODE_1
    /* CAN-FD channel number used */
    #define CANFD_HW_CHANNEL        0
    /* CAN-FD data buffer index to send data from */
    #define CANFD_BUFFER_INDEX      0
    /* Maximum incoming data length supported */
    #define CANFD_DLC               8

    #define CANFD_INTERRUPT         canfd_0_interrupts0_0_IRQn

    #define GPIO_INTERRUPT_PRIORITY (7u)

    /*******************************************************************************
    * Global Variables
    *******************************************************************************/
    /* This is a shared context structure, unique for each can-fd channel */
    static cy_stc_canfd_context_t canfd_context;

    /* Variable which holds the button pressed status */
    volatile bool gpio_intr_flag = false;

    cyhal_gpio_callback_data_t gpio_btn_callback_data;

    /* Populate the configuration structure for CAN-FD Interrupt */
    cy_stc_sysint_t canfd_irq_cfg =
    {
        /* Source of interrupt signal */
        .intrSrc = CANFD_INTERRUPT,
        /* Interrupt priority */
        .intrPriority = 1U,
    };

    /*******************************************************************************
    * Function Prototypes
    *******************************************************************************/

    /* can-fd interrupt handler */
    static void isr_canfd (void);

    /* button press interrupt handler */
    static void gpio_interrupt_handler(void *handler_arg, cyhal_gpio_event_t event);

    /* handler for general errors */
    void handle_error(uint32_t status);

    /*******************************************************************************
    * Function Definitions
    *******************************************************************************/

    /*******************************************************************************
    * Function Name: main
    ********************************************************************************
    * Summary:
    * This is the main function. It initializes the CAN-FD channel and interrupt.
    * User button and User LED are also initialized. The main loop checks for the
    * button pressed interrupt flag and when it is set, a CAN-FD frame is sent.
    * Whenever a CAN-FD frame is received from other nodes, the user LED toggles and
    * the received data is logged over serial terminal.
    *
    * Parameters:
    *  none
    *
    * Return:
    *  int
    *
    *******************************************************************************/
    int main(void)
    {
        cy_rslt_t result;

        cy_en_canfd_status_t status;
        /* Initialize the device and board peripherals */
        result = cybsp_init();
        /* Board init failed. Stop program execution */
        handle_error(result);
        /* Initialize retarget-io for uart logging */
        result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
                                    CY_RETARGET_IO_BAUDRATE);
        /* Retarget-io init failed. Stop program execution */
        handle_error(result);

        printf("===========================================================\r\n");
        printf("Welcome to CAN-FD example\r\n");
        printf("===========================================================\r\n\n");

        printf("===========================================================\r\n");
        printf("CAN-FD Node-%d (message id)\r\n", USE_CANFD_NODE);
        printf("===========================================================\r\n\n");

        /* Hook the interrupt service routine */
        (void) Cy_SysInt_Init(&canfd_irq_cfg, &isr_canfd);
        /* enable the CAN-FD interrupt */
        NVIC_EnableIRQ(CANFD_INTERRUPT);

        /* Initialize the user LED */
        result = cyhal_gpio_init(CYBSP_USER_LED, CYHAL_GPIO_DIR_OUTPUT,
                        CYHAL_GPIO_DRIVE_STRONG, CYBSP_LED_STATE_OFF);
        /* User LED init failed. Stop program execution */
        handle_error(result);

        /* Initialize the user button */
        result = cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT,
                        CYBSP_USER_BTN_DRIVE, CYBSP_BTN_OFF);
        /* User button init failed. Stop program execution */
        handle_error(result);

        /* Configure GPIO interrupt */
        gpio_btn_callback_data.callback = gpio_interrupt_handler;
        cyhal_gpio_register_callback(CYBSP_USER_BTN,
                                     &gpio_btn_callback_data);
        cyhal_gpio_enable_event(CYBSP_USER_BTN, CYHAL_GPIO_IRQ_FALL,
                                         GPIO_INTERRUPT_PRIORITY, true);

        /* Enable global interrupts */
        __enable_irq();

        /* Initialize CAN-FD Channel */
        status = Cy_CANFD_Init(CANFD_HW, CANFD_HW_CHANNEL, &CANFD_config,
                               &canfd_context);

        handle_error(status);

        /* Setting Node(message) Identifier to global setting of "USE_CANFD_NODE" */
        CANFD_T0RegisterBuffer_0.id = USE_CANFD_NODE;

        for(;;)
        {
            if (true == gpio_intr_flag)
            {
                /* Sending CAN-FD frame to other node */
                status = Cy_CANFD_UpdateAndTransmitMsgBuffer(CANFD_HW,
                                                        CANFD_HW_CHANNEL,
                                                        &CANFD_txBuffer_0,
                                                        CANFD_BUFFER_INDEX,
                                                        &canfd_context);
                if(CY_CANFD_SUCCESS == status)
                {
                    printf("CAN-FD Frame sent with message ID-%d\r\n\r\n",
                            USE_CANFD_NODE);
                }
                else
                {
                    printf("Error sending CAN-FD Frame with message ID-%d\r\n\r\n",
                            USE_CANFD_NODE);
                }

                gpio_intr_flag = false;
            }
        }
    }
    void canfd_rx_callback (bool  msg_valid, uint8_t msg_buf_fifo_num,
                            cy_stc_canfd_rx_buffer_t* canfd_rx_buf)
    {
        /* Array to hold the data bytes of the CAN-FD frame */
        uint8_t canfd_data_buffer[CANFD_DLC];
        /* Variable to hold the data length code of the CAN-FD frame */
        uint32_t canfd_dlc;
        /* Variable to hold the Identifier of the CAN-FD frame */
        uint32_t canfd_id;

        if (true == msg_valid)
        {
            /* Checking whether the frame received is a data frame */
            if(CY_CANFD_RTR_DATA_FRAME == canfd_rx_buf->r0_f->rtr)
            {

                cyhal_gpio_toggle(CYBSP_USER_LED);

                canfd_dlc = canfd_rx_buf->r1_f->dlc;
                canfd_id  = canfd_rx_buf->r0_f->id;

                printf("%d bytes received with message identifier %d\r\n\r\n",
                                                            (int)canfd_dlc,
                                                            (int)canfd_id);

                memcpy(canfd_data_buffer,canfd_rx_buf->data_area_f,canfd_dlc);

                printf("Rx Data : ");

                for (uint8_t msg_idx = 0U; msg_idx < canfd_dlc ; msg_idx++)
                {
                    printf(" %d ", canfd_data_buffer[msg_idx]);
                }

                printf("\r\n\r\n");
            }
        }
    }





使用特权

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

本版积分规则

认证:项目经理
简介:资深嵌入式开发工程师

83

主题

156

帖子

3

粉丝