当前位置:   article > 正文

GD32/STM32 CAN通讯配置及应用_gd32 can配置

gd32 can配置

GD32/STM32 CAN通讯配置及应用

由于CAN通讯具有速度快,距离远的优势,现在越来越多设备采用can通讯,尤其是车企。本文形容can通讯的初始化配置以及应用。

程序初始化配置(GD32)例程

采用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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

CAN滤波

CAN滤波分为掩码模式和列表按模式,掩码模式是接收什么ID。这里我们只讨论掩码模式。
在掩码模式下,标识符寄存器与掩码寄存器相关联,掩码寄存器指定将标识符的哪些位处理为“必须匹配”或“不关心”。
例如
标识符:

ID二进制
0x18FFA1A11 1000 1111 1111 1010 0001 1010

掩码:

ID二进制
0x1FFFFFFE1 1111 1111 1111 1111 1111 1110

可以过滤的CAN ID为 0x18FFA1A1和0x18FFA1A0即最后一位不关心为什么。

CAN接收发送及应用

对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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

总结

实际还需要结合自己的逻辑进行改动。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/943832
推荐阅读
相关标签
  

闽ICP备14008679号