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