| 一、需求: 通过上位机与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
 
 
 |