[GD32F103] CAN抓包小工具

[复制链接]
1250|10
 楼主| xiong57785 发表于 2022-4-9 15:11 | 显示全部楼层 |阅读模式

首先感谢21ic和小管家举办的这个活动【第1期】你选开发板,二姨家买单;很荣幸因为得到了这次活动的中奖名额,很抱歉这么晚才发,实在是太忙(lan)了。 好了闲话少说,还是开启这次主题任务。

首先介绍下开发板情况,主控是GD32F103C8T6,带两个LED,一个USB,一个串口,一个SWD下载接口,一个CAN接口,三个按键,基本上算是个最小开发板。

1.png

原理图见附件: 原理图.pdf (277.96 KB, 下载次数: 12)

我们可以用这个开发板实现CAN数据转USB的功能,通过电脑来抓包显示。具体思路就是主控通过CAN中断采集收到的CAN数据,将收到的数据放到FIFO缓冲区中,然后通过USB传输到电脑,这个USB其实是个串口,电路是通过CH340将串口转成USB的,速度最高2M。

CAN接收中断代码:

  1. RAMVale SRAMCOUNT;
  2. __IO CanRxMsg ReRAM[750];
  3. __IO u32 FTIME[750];
  4. void USB_LP_CAN1_RX0_IRQHandler(void)
  5. {
  6.     CanRxMsg RxMessage;
  7.     CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
  8.     if(SRAMCOUNT.RxCount < 749)
  9.     {
  10.         ReRAM[SRAMCOUNT.RxCount++] = RxMessage;
  11.         FTIME[SRAMCOUNT.RxCount-1] = FTCount;
  12.         FTCount = 0;
  13.         GPIO_WriteBit(LED_IO, LED_D6, Bit_RESET);
  14.     }
  15.     else
  16.     {
  17.         ReRAM[SRAMCOUNT.RxCount++] = RxMessage;
  18.         FTIME[SRAMCOUNT.RxCount-1] = FTCount;
  19.         FTCount = 0;
  20.         SRAMCOUNT.RxCount = 0;
  21.         SRAMCOUNT.TURN = 1;
  22.     }
  23.     can_message_received=1;
  24. }

这里FTCount是一个32位整数,在Systick中断中++。

  1. __IO u32 FTCount = 0;
  2. void SysTick_Handler(void)
  3. {
  4.     FTCount++;
  5. }

往电脑上发送的函数如下:

  1. __IO char DisRAM[50];
  2. // Whether to enable time display
  3. FlagStatus ENABLEDisTime = RESET;
  4. void DisplayCAN(void)
  5. {
  6.     __IO CanRxMsg RxMessage;
  7.     __IO u8 i;


  8.     if((SRAMCOUNT.TxCount <  SRAMCOUNT.RxCount && SRAMCOUNT.TURN == 0) || (SRAMCOUNT.TxCount > SRAMCOUNT.RxCount && SRAMCOUNT.TURN == 1))
  9.     {
  10.         FormatText(40,(const char *)DisRAM);
  11.         if(ENABLEDisTime == RESET)
  12.         {
  13.             printf("%4.0fms\r\n",(float)(FTIME[SRAMCOUNT.TxCount])*0.01);
  14.         }
  15.         else
  16.         {
  17.             printf("\r\n");
  18.             ENABLEDisTime = RESET;
  19.         }
  20.         ClearRAM((u8*)DisRAM,50);
  21.         RxMessage = ReRAM[SRAMCOUNT.TxCount++];
  22.         if(RxMessage.IDE == CAN_ID_STD)
  23.         {
  24.             sprintf((char*)DisRAM,"     %03X",RxMessage.StdId);
  25.         }
  26.         else
  27.         {
  28.             sprintf((char*)DisRAM,"%08X",RxMessage.ExtId);
  29.         }
  30.         sprintf((char*)(DisRAM+strlen((char*)DisRAM))," %1X ",RxMessage.DLC);
  31.         for(i = 0; i < RxMessage.DLC; i++)
  32.         {
  33.             sprintf((char*)(DisRAM+strlen((char*)DisRAM)),"%02X",RxMessage.Data[i]);
  34.             strcpy((char*)(DisRAM+strlen((char*)DisRAM))," ");
  35.         }
  36.         printf((const char *)DisRAM);
  37.         if(SRAMCOUNT.TxCount >= 750)
  38.         {
  39.             SRAMCOUNT.TxCount   = 0;
  40.             SRAMCOUNT.TURN = 0;
  41.         }
  42.     }
  43. }

主函数很简单如下,主要是不断轮训DisplayCAN,其他的函数是调试时加的:

  1. int main(void)
  2. {
  3.     Bsp_Init();
  4.     printf("Start!");
  5.     while(1)
  6.     {
  7.         if(CotrolVale == 0x03) // STD
  8.         {
  9.             SetSTDFilter();
  10.         }
  11.         else if(CotrolVale == 0x04)  // EXT
  12.         {
  13.             SetEXTFilter();
  14.         }
  15.         else if(CotrolVale == 0x05) // SEND
  16.         {
  17.             SendCANFrame();
  18.         }
  19.         else if(CotrolVale == 0x07) // BREAK
  20.         {
  21.             SetTIMEOUT();
  22.         }
  23.         else if(CotrolVale == 0x10)  // Display
  24.         {
  25.             DisplayCAN();
  26.         }
  27.         if(CotrolVale == 0x80) // 0x80
  28.         {
  29.             WarningText();
  30.         }

  31.         if(can_message_received)
  32.         {
  33.             can_message_received=0;

  34.             if(led_status)
  35.             {
  36.                 led_status=0;
  37.                 GPIO_ResetBits(GPIOC,GPIO_Pin_14);// Open LED
  38.             }
  39.             else
  40.             {
  41.                 led_status=1;
  42.                 GPIO_SetBits(GPIOC,GPIO_Pin_14);// Close LED
  43.             }
  44.         }
  45.     }
  46. }

最后再次感谢小管家这个给力的活动!!  21ic YYDS!!!



@zxc1234 发表于 2022-4-24 21:16 | 显示全部楼层
请教楼主一个问题GD32F103C8T6有USB_LP_CAN1_RX0_IRQHandler中断服务函数吗,怎么从startup_gd32f10x_hd.s文件中找不到
 楼主| xiong57785 发表于 2022-4-27 16:34 | 显示全部楼层
@zxc1234 发表于 2022-4-24 21:16
请教楼主一个问题GD32F103C8T6有USB_LP_CAN1_RX0_IRQHandler中断服务函数吗,怎么从startup_gd32f10x_hd.s ...

我这个是用的STM32F103C8T6的库,和GD32的通用。
tpgf 发表于 2022-5-2 18:33 | 显示全部楼层
自己开发的抓包小工具?
观海 发表于 2022-5-2 18:37 | 显示全部楼层
非常实用的小工具
guanjiaer 发表于 2022-5-2 18:55 | 显示全部楼层
应该是非常好用的了
heimaojingzhang 发表于 2022-5-2 19:01 | 显示全部楼层
可以自动识别波特率吗
keaibukelian 发表于 2022-5-2 19:08 | 显示全部楼层
还有其他下载方式吗
labasi 发表于 2022-5-2 19:21 | 显示全部楼层
can如何轮询呀
redone 发表于 2022-5-7 17:58 | 显示全部楼层
这个可以有,哈哈哈
gouguoccc 发表于 2022-5-7 19:33 来自手机 | 显示全部楼层
可以用CAN分析仪的上位机软件
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

55

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部