赞
踩
由于CAN通讯具有速度快,距离远的优势,现在越来越多设备采用can通讯,尤其是车企。本文形容can通讯的初始化配置以及应用。
采用GD32F105互联型产品。有两路CAN。APB1时钟为16M,CAN波特率为250K。
/*********************************************************************** *@brief :CAN初始化 *@param :None *@return:None ***********************************************************************/ void CANLoad_Init(DataRate_t DataRate) { uint8_t i; // uint32_t Clock; rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_CAN1); can_parameter_struct can_parameter; can_struct_para_init(CAN_INIT_STRUCT, &can_parameter); /*GPIO Init*/ gpio_init(CAN0_RX_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN0_RX_PIN); gpio_init(CAN0_TX_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN0_TX_PIN); gpio_init(CAN1_RX_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN1_RX_PIN); gpio_init(CAN1_TX_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN1_TX_PIN); /* initialize CAN register */ can_deinit(CAN0); can_deinit(CAN1); //CAN由APB1时钟而来 // Clock = rcu_clock_freq_get(CK_APB1); /* initialize CAN parameters */ can_parameter.time_triggered = DISABLE; can_parameter.auto_bus_off_recovery = ENABLE; can_parameter.auto_wake_up = DISABLE; can_parameter.no_auto_retrans = DISABLE; can_parameter.rec_fifo_overwrite = DISABLE; can_parameter.trans_fifo_order = DISABLE; can_parameter.working_mode = CAN_NORMAL_MODE; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.time_segment_1 = CAN_BT_BS1_6TQ; can_parameter.time_segment_2 = CAN_BT_BS2_1TQ; can_parameter.prescaler = 8; /* initialize CAN */ can_init(CAN0, &can_parameter); can_parameter.prescaler = 8; can_init(CAN1, &can_parameter); can_filter_parameter_struct can_filter; can_struct_para_init(CAN_INIT_STRUCT, &can_filter); can_filter.filter_number = 0; can_filter.filter_list_high = 0x3000; //过滤器高字节 can_filter.filter_list_low = 0x0000; //过滤器低字节 can_filter.filter_mask_high = 0x3000//过滤器掩码数高位 can_filter.filter_mask_low = 0x0000 //过滤器掩码数低位 can_filter.filter_fifo_number = CAN_FIFO0; //滤过器关联FIFO0 can_filter.filter_mode = CAN_FILTERMODE_MASK; //掩码模式 can_filter.filter_bits = CAN_FILTERBITS_32BIT;//32位 can_filter.filter_enable = ENABLE; can_filter_init(&can_filter); /* CAN1 filter number */ can_filter.filter_number = 15; can_filter_init(&can_filter); /* enable can receive FIFO0 not empty interrupt */ can_interrupt_enable(CAN0, CAN_INT_RFNE0); can_interrupt_enable(CAN1, CAN_INT_RFNE0); }
CAN滤波分为掩码模式和列表按模式,掩码模式是接收什么ID。这里我们只讨论掩码模式。
在掩码模式下,标识符寄存器与掩码寄存器相关联,掩码寄存器指定将标识符的哪些位处理为“必须匹配”或“不关心”。
例如
标识符:
ID | 二进制 |
---|---|
0x18FFA1A1 | 1 1000 1111 1111 1010 0001 1010 |
掩码:
ID | 二进制 |
---|---|
0x1FFFFFFE | 1 1111 1111 1111 1111 1111 1110 |
可以过滤的CAN ID为 0x18FFA1A1和0x18FFA1A0即最后一位不关心为什么。
对CANID的长度、ID和扩展帧进行判断
/*----------------------------------------------------------------------- @brief :CAN1接收中断 -----------------------------------------------------------------------*/ void CAN1_RX0_IRQHandler(void) { can_receive_message_struct RxMessage; can_message_receive(CAN1, CAN_FIFO0, &RxMessage); CAN1_RxMessage(&RxMessage); } /*----------------------------------------------------------------------- @brief :CAN1接收函数 -----------------------------------------------------------------------*/ void CAN1_RxMessage(can_receive_message_struct* RxMessage) { if((0x18FFFFFF == RxMessage->rx_efid)&&(CAN_FF_EXTENDED == RxMessage->rx_ff)&&(8 == RxMessage->rx_dlen)) { Name = RxMessage->rx_data[0]; } /*----------------------------------------------------------------------- @brief :CAN发送函数 -----------------------------------------------------------------------*/ void CAN1_HAILI_1(void) { can_trasnmit_message_struct SendMessage; TxMessage_Init(&Tx1_Data); SendMessage.tx_data[0] = 0x11; SendMessage.tx_data[1] = 0x22; SendMessage.tx_dlen = 8; SendMessage.tx_ff = CAN_FF_EXTENDED; SendMessage.tx_ft = CAN_FT_DATA; SendMessage.tx_sfid = 0x18FF1234; can_message_transmit(CAN0, &SendMessage); }
实际还需要结合自己的逻辑进行改动。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。