/*!
* @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表示程序正常结束
}
```
经过简单的分析后,编译:

没有错误,继而烧录:





|