GD32通过CAN回环模式实现串口数据回显功能

一、需求:
通过上位机与UART连接,将接收到的100个字节数据通过CAN进行发送并接收 (使用回环模式)接收的数据通过对应串口再发送到上位机进行显示;CAN总线的参数为500K波特率,80%采样点,发送周期为100ms。

二、功能分析:
就是电脑 串口助手发100个数据到串口 DMA接收,经过can 回环模式,再用串口DMA发回电脑。

三、代码如下:
int main(void)
{
GPIO_init();
Systick_Config();
GD_eval_com_init(EVAL_COM0);
RCU_periph_clock_enable(RCU_CAN0);
NVIC_irq_enable(CAN0_RX1_IRQn,0,0);
UART_DmaConfig();
DMA_channel_enable(DMA1, DMA_CH7);
DMA_channel_enable(DMA1, DMA_CH2);
UART_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);
UART_dma_transmit_config(USART0, USART_TRANSMIT_DMA_ENABLE);
CAN_loopback_init();
while(1)
{
us_tmp_cnt1++;
dma_channel_disable(DMA1, DMA_CH2);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FEE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_SDE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_TAE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_HTF);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF);
dma_transfer_number_config(DMA1, DMA_CH2, 100);
dma_channel_enable(DMA1, DMA_CH2);
usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);
/* wait until USART0 RX DMA1 channel transfer complete */
///等待USART0 RX DMA1信道传输完成/
while(RESET == dma_flag_get(DMA1, DMA_CH2, DMA_INTF_FTFIF))
{
}
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FEE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_SDE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_TAE);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_HTF);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF);
us_tmp_cnt2++;
can_loopback();
us_tmp_cnt3++;
dma_channel_disable(DMA1, DMA_CH7);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FEE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_SDE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_TAE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_HTF);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FTF);
dma_transfer_number_config(DMA1, DMA_CH7, 100);
dma_channel_enable(DMA1, DMA_CH7);
while(RESET == dma_flag_get(DMA1, DMA_CH7, DMA_INTF_FTFIF)){
}
us_tmp_cnt4++;
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FEE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_SDE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_TAE);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_HTF);
dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FTF);
}
}

void UART_DmaConfig(void)
{
dma_single_data_parameter_struct dma_init_struct;
/* enable DMA1 /
rcu_periph_clock_enable(RCU_DMA1);
/
deinitialize DMA channel7(USART0 tx) /
dma_deinit(DMA1, DMA_CH7);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
dma_init_struct.memory0_addr = (uint32_t)tx_buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
dma_init_struct.number = ARRAYNUM(tx_buffer);
dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(DMA1, DMA_CH7, &dma_init_struct);
/
configure DMA mode */
dma_circulation_disable(DMA1, DMA_CH7);
dma_channel_subperipheral_select(DMA1, DMA_CH7, DMA_SUBPERI4);

dma_deinit(DMA1, DMA_CH2);
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.memory0_addr = (uint32_t)rx_buffer;
dma_single_data_mode_init(DMA1, DMA_CH2, &dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA1, DMA_CH2);
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4);

}
void CAN_LoopBack_init(void)
{
can_parameter_struct can_parameter;
can_filter_parameter_struct can_filter;

can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);

/* initialize CAN register */
can_deinit(CAN0);

/* initialize CAN */
can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = DISABLE;
can_parameter.auto_wake_up = DISABLE;
can_parameter.auto_retrans = ENABLE;
can_parameter.rec_fifo_overwrite = DISABLE;
can_parameter.trans_fifo_order = DISABLE;
//回环模式
can_parameter.working_mode = CAN_LOOPBACK_MODE;

/* configure baudrate to 500kbps */  
/*
50MHz / 500000 / 10
*/

can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
can_parameter.prescaler = 10;
can_init(CAN0, &can_parameter);

/* initialize filter */

#ifdef CAN0_USED
/* CAN0 filter number /
can_filter.filter_number = 0;
#else
/
CAN1 filter number /
can_filter.filter_number = 15;
#endif
/
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_enable=ENABLE;
can_filter_init(&can_filter);
}
ErrStatus CAN_LoopBack(void)
{
can_trasnmit_message_struct transmit_message;
can_receive_message_struct receive_message;
uint32_t timeout = 0xFFFF;
uint8_t transmit_mailbox = 0;
uint8_t i = 0;
uint8_t j = 0;
for(j=0;j<12;j++)
{
/
initialize transmit message /
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
transmit_message.tx_sfid = 0x11;
transmit_message.tx_ft = CAN_FT_DATA;
transmit_message.tx_ff = CAN_FF_STANDARD;
transmit_message.tx_dlen = 8;
for(i = 0; i<8; i++)
{
transmit_message.tx_data[i] = rx_buffer[j
8+i];
}
/* initialize receive message */
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);

/* transmit message */
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
/* waiting for transmit completed */
while((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) && (0 != timeout)){
    timeout--;
}
timeout = 0xFFFF;
/* waiting for receive completed */
while((can_receive_message_length_get(CAN0, CAN_FIFO1) < 1) && (0 != timeout)){
    timeout--; 
}

/* initialize receive message*/
receive_message.rx_sfid = 0x00;
receive_message.rx_ff = 0;
receive_message.rx_dlen = 0;
receive_message.rx_data[0] = 0x00;
receive_message.rx_data[1] = 0x00;
receive_message.rx_data[2] = 0x00;
receive_message.rx_data[3] = 0x00;
receive_message.rx_data[4] = 0x00;
receive_message.rx_data[5] = 0x00;
receive_message.rx_data[6] = 0x00;
receive_message.rx_data[7] = 0x00;
can_message_receive(CAN0, CAN_FIFO1, &receive_message);  
	for(i = 0; i<8; i++)
  {
	tx_buffer[j*8+i] = receive_message.rx_data[i];
  }
	
	
}
    /* initialize transmit message */
    //初始化发送信息
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
transmit_message.tx_sfid = 0x11;
transmit_message.tx_ft = CAN_FT_DATA;
transmit_message.tx_ff = CAN_FF_STANDARD;
transmit_message.tx_dlen = 4;
  for(i = 0; i<4; i++)
{
transmit_message.tx_data[i] = rx_buffer[12*8+i];
}


/* initialize receive message 初始化接收信息 */
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);

/* transmit message    发送信息*/
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
/* waiting for transmit completed  等待传输完成*/
while((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) && (0 != timeout))
{
    timeout--;
}
timeout = 0xFFFF;
/* waiting for receive completed  等待接收完成*/
while((can_receive_message_length_get(CAN0, CAN_FIFO1) < 1) && (0 != timeout)){
    timeout--; 
}

/* initialize receive message*/
receive_message.rx_sfid = 0x00;
receive_message.rx_ff = 0;
receive_message.rx_dlen = 0;
receive_message.rx_data[0] = 0x00;
receive_message.rx_data[1] = 0x00;
receive_message.rx_data[2] = 0x00;
receive_message.rx_data[3] = 0x00;
receive_message.rx_data[4] = 0x00;
receive_message.rx_data[5] = 0x00;
receive_message.rx_data[6] = 0x00;
receive_message.rx_data[7] = 0x00;
can_message_receive(CAN0, CAN_FIFO1, &receive_message);  
	for(i = 0; i<4; i++)
  {
	tx_buffer[12*8+i] = receive_message.rx_data[i];
  }   
	
/* check the receive message */
if((0x11 == receive_message.rx_sfid) && (CAN_FF_STANDARD == receive_message.rx_ff)
   && (2 == receive_message.rx_dlen) && (0xCDAB == (receive_message.rx_data[1]<<8|receive_message.rx_data[0]))){
    return SUCCESS;
}else{
    return ERROR;
}

}
ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length)
{
while(length–){
if(*src++ != *dst++){
return ERROR;
}
}
return SUCCESS;
}

四、代码现象:

在这里插入图片描述发送600个字节数据,经过CAN,输出600个字节数据
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值