打印
[研电赛技术支持]

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

[复制链接]
509|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-7-18 11:24 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、需求:
通过上位机与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 = rx_buffer[j8+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;
  }
       
       
}
    /* 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 = 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;
  }   
       
/* 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个字节数据

————————————————
版权声明:本文为CSDN博主「qq_27091657」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_27091657/article/details/131525318

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2028

主题

15903

帖子

14

粉丝