打印
[活动]

【G32A1465测评】CAN_ClassicFrames

[复制链接]
724|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丙丁先生|  楼主 | 2024-12-14 11:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*!
* @file        readme.txt
*
* @brief       示例描述
*
* @version     V1.0.0
*
* @date        2024-03-20
*
* @attention
*
*  版权所有 (C) 2024 Geehy 半导体公司
*
*  除非符合GEEHY COPYRIGHT NOTICE(GEEHY软件包许可协议)的要求,否则您不得使用本文件。
*
*  本程序仅供参考,旨在希望对客户开发他们的软件有所帮助和指导。除非适用法律要求或书面同意,否则本程序按“原样”分发,没有任何明示或暗示的担保或条件。有关许可下的权限和限制,请参阅GEEHY软件包许可协议。
*/

&par 示例描述
此示例展示了经典CAN帧的CAN模块的使用方法。通过两个按钮,它将数据发送到CAN总线,标准CAN ID为1,扩展CAN ID为2。配置了两个消息缓冲区以接收标准CAN ID为1和扩展CAN ID为1的CAN帧。如果收到CAN帧,绿色LED将会闪烁。

&par 硬件描述

  - CAN波特率:250 Kbit/s

&par 目录内容

&par IDE环境

  - MDK-ARM V5.36.0.0
  - EWARM V8.50.5.26295

&par 硬件和软件环境

  - 该示例运行在G32A1465 EVAL设备上。

---


```c
/*!
* @file
* @brief 主程序文件
*/

#include "user_config.h"
#include "board.h"

/** @addtogroup G32A3240C_G32H1440000_Examples
  @{
  */
/** @addtogroup CAN_ClassicFrames
  @{
  */

/*******************************************************************************
* @brief 包含头文件
******************************************************************************/

/*!
* @brief CAN实例
*/
#define CAN0_INSTANCE           (0U)

/*!
* @brief MB0用于接收标准CAN帧
*/
#define RX_MB_0                 (0U)

/*!
* @brief MB1用于接收扩展CAN帧
*/
#define RX_MB_1                 (1U)

/*!
* @brief 用于发送CAN帧的MB
*/
#define TX_MB                   (2U)

/*!
* @brief CAN消息ID
*/
#define RX_CAN_MESSAGE_ID       (1U)
#define TX_CAN_MESSAGE_ID_1     (1U)
#define TX_CAN_MESSAGE_ID_2     (2U)

/*******************************************************************************
* @brief 宏定义部分
******************************************************************************/
/** @addtogroup CAN_ClassicFrames_Macros
  @{
  */
/** @addtogroup CAN_ClassicFrames_Variables
  @{
  */

/*!
* @brief 指示MB0接收完成的标志
*/
volatile bool g_mb0ReceiveCompleted = false;

/*!
* @brief 指示MB1接收完成的标志
*/
volatile bool g_mb1ReceiveCompleted = false;

/**@} end of group CAN_ClassicFrames_Variables*/
/**@} end of group CAN_ClassicFrames_Macros*/

/*******************************************************************************
* @brief 函数声明部分
******************************************************************************/
/** @addtogroup CAN_ClassicFrames_Functions
  @{
  */

/*!
* @brief 当CAN事件发生时调用此函数
*
* @param instance CAN实例编号
* @param eventType 事件类型
* @param mbIndex 发生事件的邮箱索引
* @param driverState 驱动状态指针
*/
void CanEventCallback(uint8_t instance, CAN_EVENT_TYPE_T eventType, uint32_t mbIndex, CAN_STATE_T *driverState);

/*!
* @brief 当按下KEY1按钮时调用此函数
*/
void Key1Handler(void);

/*!
* @brief 当按下KEY2按钮时调用此函数
*/
void Key2Handler();

/*!
* @brief   主函数
* @param   None
* @retval  退出代码
*/
int main(void);

/**@} end of group CAN_ClassicFrames_Functions*/
/**@} end of group CAN_ClassicFrames*/
/**@} end of group Examples*/
```
```c
int main(void)
{
    // 定义一个布尔变量exit,用于控制程序退出
    bool exit = false;
    // 定义CAN状态和时间分段结构体变量
    CAN_STATE_T canState;
    CAN_TIME_SEGMENT_T canBitrate;

    /* 初始化时钟 */
    CLOCK_SYS_Init(&g_clockConfig);

    /* 初始化引脚 */
    PINS_Init(NUM_OF_CONFIGURED_PINS0, g_pinsConfig);

    /* 初始化LED */
    LED_Init();
    // 打开绿色LED灯
    LED_On(LED_GREEN);

    /* 初始化按钮 */
    BTN_Init();
    // 安装按键1的中断处理函数
    BTN_InstallKey1Handler(Key1Handler);
    // 安装按键2的中断处理函数
    BTN_InstallKey2Handler(Key2Handler);

    /* 初始化CAN控制器,比特率为250K */
    CAN_Init(CAN0_INSTANCE, &canState, &g_canConfig);

    /* 获取当前的CAN比特率 */
    CAN_GetBitrate(CAN0_INSTANCE, &canBitrate);

    /* 配置发送邮箱 */
    CAN_DATA_INFO_T txMbInfo = {
        .msgIdType  = CAN_ID_STANDARD,   /* 标准CAN ID */
        .dataLen    = 8,        /* 仅用于初始化MB,发送数据时会更新 */
        .fdEnable   = false,    /* 禁用CAN FD */
        .isRemote   = false     /* 非远程帧 */
    };
    // 配置发送邮箱TX_MB
    CAN_ConfigureTxMb(CAN0_INSTANCE, TX_MB, &txMbInfo, 0);

    /* 使用单独的接收掩码为每个邮箱 */
    CAN_SetRxMaskType(CAN0_INSTANCE, CAN_RX_MASK_INDIVIDUAL);

    /* 配置接收邮箱0,它将接收标准ID为1的标准帧 */
    CAN_DATA_INFO_T rxMb0Info = {
        .msgIdType  = CAN_ID_STANDARD,   /* 标准CAN ID */
        .dataLen    = 8,        /* 经典CAN的最大数据长度为8字节 */
        .fdEnable   = false,    /* 禁用CAN FD */
        .isRemote   = false     /* 非远程帧 */
    };
    // 配置接收邮箱RX_MB_0
    CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_0, &rxMb0Info, RX_CAN_MESSAGE_ID);
    // 设置接收邮箱0的单独掩码
    CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_STANDARD, RX_MB_0, 0xFFFFFFFF);

    /* 配置接收邮箱1,它将接收扩展ID为1的扩展帧 */
    CAN_DATA_INFO_T rxMb1Info = {
        .msgIdType  = CAN_ID_EXTENDED,   /* 扩展CAN ID */
        .dataLen    = 8,        /* 经典CAN的最大数据长度为8字节 */
        .fdEnable   = false,    /* 禁用CAN FD */
        .isRemote   = false     /* 非远程帧 */
    };
    // 配置接收邮箱RX_MB_1
    CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_1, &rxMb1Info, RX_CAN_MESSAGE_ID);
    // 设置接收邮箱1的单独掩码
    CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_EXTENDED, RX_MB_1, 0xFFFFFFFF);

    /* 设置CAN事件回调处理函数 */
    CAN_InstallEventCallback(CAN0_INSTANCE, &CanEventCallback, NULL);

    /* 从邮箱0和邮箱1接收CAN帧 */
    CAN_MSG_BUF_T rxFrame0;
    CAN_MSG_BUF_T rxFrame1;
    while (!exit)
    {
        /* 重置接收完成标志 */
        g_mb0ReceiveCompleted = false;
        g_mb1ReceiveCompleted = false;

        /* 开始非阻塞接收 */
        CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_0, &rxFrame0);
        CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_1, &rxFrame1);

        /* 等待直到其中一个邮箱接收到CAN帧 */
        while ((g_mb0ReceiveCompleted == false) && (g_mb1ReceiveCompleted == false));

        /* 切换绿色LED的状态 */
        LED_Toggle(LED_GREEN);
    }

    // 取消初始化CAN控制器
    CAN_DeInit(CAN0_INSTANCE);
    // 打开红色LED灯
    LED_On(LED_RED);
    return 0; // 返回0表示程序正常结束
}
```

经过简单的分析后,编译:

没有错误,继而烧录:





使用特权

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

本版积分规则

736

主题

2663

帖子

5

粉丝