当前位置: 首页 > news >正文

GD32F305 CAN配置

GD32F305 CAN配置

CAN STB 是控制 CAN 收发器是否进入待机模式的引脚。

正常模式(STB = 0)

  • CANH/CANL 正常驱动
  • 可以发送/接收数据
  • 功耗正常

待机模式(STB = 1)

  • 关闭总线驱动
  • 进入低功耗模式
  • 不能正常通信
  • 但通常可以唤醒检测

CAN工作时万用表测CAN_H,CAN_L电压为大约2.37V和2.46V

CAN初始化设置

#include "main.h"/* select CAN */
//#define CAN0_USED
#define CAN1_USED#ifdef  CAN0_USED#define CANX CAN0
#else #define CANX CAN1
#endifvolatile ErrStatus test_flag;
volatile ErrStatus test_flag_interrupt;void nvic_config(void);
ErrStatus can_loopback_interrupt(void);
void can_loopback_init(void);/*!\brief      main function\param[in]  none\param[out] none\retval     none
*/
can_trasnmit_message_struct transmit_message;unsigned char flage1,flage2;
int CAN_Text(void)//125K
{can_parameter_struct        can_parameter;can_filter_parameter_struct can_filter;//配置CAN STB(低电平开启can工作)rcu_periph_clock_enable(RCU_GPIOB);/* 2. 配置 GPIO */gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ,GPIO_PIN_14);gpio_bit_reset(GPIOB, GPIO_PIN_14);//配置CAN引脚/* 以 CAN1 为例 (通常是  PB12/PB13(默认) 或 PB5/PB6(需gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);重映射) */rcu_periph_clock_enable(RCU_GPIOB);rcu_periph_clock_enable(RCU_AF);/* configure CAN1 GPIO PB12(RX),13(TX)*/gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_12);gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_13);
//    gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);/* enable CAN clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_CAN1);/* configure NVIC */nvic_config();/* initialize CAN and filter */can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);/* initialize CAN register */can_deinit(CANX);/* initialize CAN */can_parameter.time_triggered = DISABLE;can_parameter.auto_bus_off_recovery = DISABLE;can_parameter.auto_wake_up = DISABLE;can_parameter.auto_retrans = DISABLE;can_parameter.rec_fifo_overwrite = DISABLE;can_parameter.trans_fifo_order = DISABLE;
//    can_parameter.working_mode = CAN_LOOPBACK_MODE;//回环模式can_parameter.working_mode = CAN_NORMAL_MODE;//正常模式/* configure baudrate to 125kbps */can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;can_parameter.prescaler = 48;can_init(CANX, &can_parameter);/* initialize filter *//* CAN1 filter number */can_filter.filter_number = 15;/* initialize filter */    can_filter.filter_mode = CAN_FILTERMODE_MASK;can_filter.filter_bits = CAN_FILTERBITS_32BIT;can_filter.filter_list_high = 0x0000;can_filter.filter_list_low = 0x0000;can_filter.filter_mask_high = 0x0000;can_filter.filter_mask_low = 0x0000;  
//    can_filter.filter_fifo_number = CAN_FIFO1;can_filter.filter_fifo_number = CAN_FIFO0; // 建议先用 FIFO0 测试can_filter.filter_enable=ENABLE;can_filter_init(&can_filter);/* enable CAN receive FIFO1 not empty interrupt  */ 
//    can_interrupt_enable(CANX, CAN_INT_RFNE1);can_interrupt_enable(CAN1, CAN_INT_RFNE0); // 开启 FIFO0 非空中断/* initialize transmit message */transmit_message.tx_sfid = 0;transmit_message.tx_efid = 0x1234;transmit_message.tx_ff = CAN_FF_EXTENDED;transmit_message.tx_ft = CAN_FT_DATA;transmit_message.tx_dlen = 2;transmit_message.tx_data[0] = 0xDE;transmit_message.tx_data[1] = 0xCA;/* transmit a message */can_message_transmit(CANX, &transmit_message);//发送的数据}/*!\brief      configure the nested vectored interrupt controller\param[in]  none\param[out] none\retval     none
*/
void nvic_config(void)
{nvic_irq_enable(CAN1_RX0_IRQn,0,0);//CAN1 FIFO0
}

CAN接收中断配置


extern volatile ErrStatus test_flag;
extern volatile ErrStatus test_flag_interrupt;can_receive_message_struct receive_message2;//接受数据的结构体void CAN1_RX0_IRQHandler(void)//CAN1 FIFO0
{/* initialize receive message */
// 初始化接收消息结构体的各个字段receive_message2.rx_sfid = 0x00;receive_message2.rx_efid = 0x00;receive_message2.rx_ff = 0;receive_message2.rx_dlen = 0;receive_message2.rx_fi = 0;receive_message2.rx_data[0] = 0x00;receive_message2.rx_data[1] = 0x00;/* check the receive message读取硬件 FIFO */can_message_receive(CAN1, CAN_FIFO0, &receive_message2);// ID 是否匹配:是否是扩展帧 ID 0x1234?// 帧类型:是否确实是扩展帧 (CAN_FF_EXTENDED)?// 数据长度:是不是收到了 2 个字节 (dlen == 2)?// 内容自洽:收到的两个字节拼起来是不是 0xCADE?(注意:这里判断的是 0xDE 和 0xCA 的组合)。if((0x1234 == receive_message2.rx_efid) && (CAN_FF_EXTENDED == receive_message2.rx_ff)&& (2 == receive_message2.rx_dlen) && (0xCADE == (receive_message2.rx_data[1]<<8|receive_message2.rx_data[0]))){test_flag_interrupt = SUCCESS; }else{test_flag_interrupt = ERROR; }
}

CAN接收中断配置:

开启对应CANx的FIFOx中断

例如:CAN1,FIFO0

    nvic_irq_enable(CAN1_RX0_IRQn,0,0);//CAN1 FIFO0

CAN数据发送

   volatile can_trasnmit_message_struct transmit_message2;transmit_message2.tx_sfid = 0;transmit_message2.tx_efid = 0x1234;transmit_message2.tx_ff = CAN_FF_EXTENDED;transmit_message2.tx_ft = CAN_FT_DATA;transmit_message2.tx_dlen = 2;transmit_message2.tx_data[0] = 0xDE;transmit_message2.tx_data[1] = 0xCA;can_message_transmit(CAN1, &transmit_message2);//发送的数据

消息队列传输CAN接收中断数据,任务处理CAN数据

1.can接收卡死 核心原因:中断优先级过高

FreeRTOS 要求:所有调用 FromISR 结尾 API 的硬件中断,其优先级数值必须大于或等于 configMAX_SYSCALL_INTERRUPT_PRIORITY

  • 在 ARM Cortex-M 中,优先级数值越小,优先级越高。
  • 如果你的 configMAX_SYSCALL_INTERRUPT_PRIORITY 设置为 5,而 CAN 中断优先级设置为 0-4,一旦执行 xQueueSendFromISR,内核会为了保护临界区尝试关闭中断,但因为硬件优先级过高导致无法屏蔽,直接触发 HardFault 或断言失败卡死。

1、需要修改can初始化中断接收优先级

nvic_irq_enable(CAN1_RX0_IRQn, 5, 0);//CAN1 FIFO0

2、创建队列

void User_Init_Task(void *p)
{   /* 创建队列:每个单元大小为结构体大小,深度为 10 */xCanQueue = xQueueCreate(10, sizeof(can_receive_message_struct));if (xCanQueue == NULL) {// 队列创建失败处理(通常是内存不足)while(1);}CAN_Text();vTaskDelete(NULL);
}

3、队列数据发送

#include "FreeRTOS.h"
#include "queue.h"// 声明外部队列句柄
extern QueueHandle_t xCanQueue;void CAN1_RX0_IRQHandler(void)
{BaseType_t xHigherPriorityTaskWoken = pdFALSE;can_receive_message_struct rx_msg;/* 1. 从硬件 FIFO 读取数据到临时变量 */can_message_receive(CAN1, CAN_FIFO0, &rx_msg);/* 2. 将整个结构体拷贝到队列中 */if (xCanQueue != NULL) {// 使用 FromISR 版本的 API,不等待,如果队列满了就丢弃(或根据需求处理)xQueueSendFromISR(xCanQueue, &rx_msg, &xHigherPriorityTaskWoken);}/* 3. 上下文切换 */portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

4、任务处理can接收数据

void User_Task2(void *p)//接收任务
{can_receive_message_struct rx_msg_local;//保存队列中的can数据while(1){/* 阻塞等待队列消息 *//* 一旦队列有数据,xQueueReceive 会自动将数据拷贝到 rx_msg_local 并弹出 */if (xQueueReceive(xCanQueue, &rx_msg_local, portMAX_DELAY) == pdPASS){// --- 核心处理逻辑 ---if (rx_msg_local.rx_ff == CAN_FF_EXTENDED){switch(rx_msg_local.rx_efid){case 0x1234:if (0xCADE == (rx_msg_local.rx_data[1] << 8 | rx_msg_local.rx_data[0])) {test_flag_interrupt = SUCCESS;} else {test_flag_interrupt = ERROR;}break;default:// 处理其他 IDbreak;}}}}
}
http://www.jsqmd.com/news/439103/

相关文章:

  • 金属表面清洁度检测设备品牌排行 西恩士工业稳居优选榜首 - 仪器权威论
  • 2026年天津离婚房产律师电话查询推荐:精选推荐与使用指南 - 品牌推荐
  • 2026京津冀家庭全屋墙面刷新公司选购,大型靠谱品牌在哪 - mypinpai
  • 2026高空作业车排行榜:曲臂高空作业车/曲臂高空车/电动高空作业车/电动高空车/登高车高空作业车/选择指南 - 优质品牌商家
  • STM32输入捕获测频率
  • 深聊KBSGZY矿用隔爆型移动变电站,山西地区哪家生产商靠谱? - myqiye
  • 2026年天津遗嘱继承律师电话查询推荐:专业服务与联系指引 - 品牌推荐
  • 2026年南昌知名的新能源汽车学校排名,哪家性价比高? - myqiye
  • 2026年天津继承诉讼律师电话查询推荐:高效解决继承纠纷 - 品牌推荐
  • 聊聊北京九州木子办公设备实力如何,京津冀区域值得选的办公设备商 - mypinpai
  • 2026年全国受欢迎的实力强的无人机仿真软件排名TOP10 - 工业推荐榜
  • 2026年天津离婚纠纷律师电话查询推荐:高效联系与沟通建议 - 品牌推荐
  • 2026-03-05 闲话
  • 特殊工况热电偶误差校准与疑难误差排查修复
  • 洁净度测量装置哪家好 西恩士工业实力圈粉高端制造 - 技术权威说
  • 看这!2026年2月市面上口碑好的回收异丙醇实力厂家,工业乙醇/乙醇/回收乙醇/回收废乙醇,回收异丙醇实力厂家选哪家 - 品牌推荐师
  • 洁净度检测仪器品牌优选 西恩士技术领跑全行业 - 仪器权威论
  • 金属表面清洁度设备哪家好 西恩士工业实力出圈成首选 - 仪器权威论
  • 洁净度分析设备选哪个品牌 西恩士稳居行业优选榜 - 仪器权威论
  • Python基于flask的电动汽车智能充电管理系统的设计与实现_u8xoc3r5_
  • 2026年抛丸机厂家电话查询推荐:一站式采购咨询指南 - 十大品牌推荐
  • 2026年高考志愿填报服务机构推荐:北京金榜如愿教育科技有限公司,专注低分策略/新高考/1对1定制化志愿规划服务 - 品牌推荐官
  • 洁净度测试设备品牌推荐 西恩士工业稳居优选前列 - 仪器权威论
  • 再互动解读瓶盖上伊利扫码领红包的火爆活动 - 品牌智鉴榜
  • 275_尚硅谷_管道阻塞的机制
  • 洁净度测量设备哪家好 西恩士工业硬核实力成优选 - 技术权威说
  • (面试题)Redis实现 IP 维度滑动窗口限流实践
  • 2026年3月,为你呈现评价好的钢承口水泥管生产厂家排行,3米水泥管/大型顶管/混凝土管顶管,水泥管直销厂家口碑推荐 - 品牌推荐师
  • 2026年链轮厂家推荐:山东达源机械装备有限公司,提升机链轮/NSE提升机链轮/锯齿链轮/非标链轮/捞渣机链轮全系供应 - 品牌推荐官
  • 健康远程咨询服务,创新智慧就医体验