xiong57785 发表于 2022-4-9 15:11

[GD32F103] CAN抓包小工具

首先感谢21ic和小管家举办的这个活动【第1期】你选开发板,二姨家买单;很荣幸因为得到了这次活动的中奖名额,很抱歉这么晚才发,实在是太忙(lan)了。 好了闲话少说,还是开启这次主题任务。首先介绍下开发板情况,主控是GD32F103C8T6,带两个LED,一个USB,一个串口,一个SWD下载接口,一个CAN接口,三个按键,基本上算是个最小开发板。原理图见附件:我们可以用这个开发板实现CAN数据转USB的功能,通过电脑来抓包显示。具体思路就是主控通过CAN中断采集收到的CAN数据,将收到的数据放到FIFO缓冲区中,然后通过USB传输到电脑,这个USB其实是个串口,电路是通过CH340将串口转成USB的,速度最高2M。CAN接收中断代码:RAMVale SRAMCOUNT;
__IO CanRxMsg ReRAM;
__IO u32 FTIME;
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    CanRxMsg RxMessage;
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
    if(SRAMCOUNT.RxCount < 749)
    {
      ReRAM = RxMessage;
      FTIME = FTCount;
      FTCount = 0;
      GPIO_WriteBit(LED_IO, LED_D6, Bit_RESET);
    }
    else
    {
      ReRAM = RxMessage;
      FTIME = FTCount;
      FTCount = 0;
      SRAMCOUNT.RxCount = 0;
      SRAMCOUNT.TURN = 1;
    }
    can_message_received=1;
}这里FTCount是一个32位整数,在Systick中断中++。__IO u32 FTCount = 0;
void SysTick_Handler(void)
{
    FTCount++;
}往电脑上发送的函数如下:__IO char DisRAM;
// Whether to enable time display
FlagStatus ENABLEDisTime = RESET;
void DisplayCAN(void)
{
    __IO CanRxMsg RxMessage;
    __IO u8 i;


    if((SRAMCOUNT.TxCount <SRAMCOUNT.RxCount && SRAMCOUNT.TURN == 0) || (SRAMCOUNT.TxCount > SRAMCOUNT.RxCount && SRAMCOUNT.TURN == 1))
    {
      FormatText(40,(const char *)DisRAM);
      if(ENABLEDisTime == RESET)
      {
            printf("%4.0fms\r\n",(float)(FTIME)*0.01);
      }
      else
      {
            printf("\r\n");
            ENABLEDisTime = RESET;
      }
      ClearRAM((u8*)DisRAM,50);
      RxMessage = ReRAM;
      if(RxMessage.IDE == CAN_ID_STD)
      {
            sprintf((char*)DisRAM,"   %03X",RxMessage.StdId);
      }
      else
      {
            sprintf((char*)DisRAM,"%08X",RxMessage.ExtId);
      }
      sprintf((char*)(DisRAM+strlen((char*)DisRAM))," %1X ",RxMessage.DLC);
      for(i = 0; i < RxMessage.DLC; i++)
      {
            sprintf((char*)(DisRAM+strlen((char*)DisRAM)),"%02X",RxMessage.Data);
            strcpy((char*)(DisRAM+strlen((char*)DisRAM))," ");
      }
      printf((const char *)DisRAM);
      if(SRAMCOUNT.TxCount >= 750)
      {
            SRAMCOUNT.TxCount   = 0;
            SRAMCOUNT.TURN = 0;
      }
    }
}主函数很简单如下,主要是不断轮训DisplayCAN,其他的函数是调试时加的:int main(void)
{
    Bsp_Init();
    printf("Start!");
    while(1)
    {
      if(CotrolVale == 0x03) // STD
      {
            SetSTDFilter();
      }
      else if(CotrolVale == 0x04)// EXT
      {
            SetEXTFilter();
      }
      else if(CotrolVale == 0x05) // SEND
      {
            SendCANFrame();
      }
      else if(CotrolVale == 0x07) // BREAK
      {
            SetTIMEOUT();
      }
      else if(CotrolVale == 0x10)// Display
      {
            DisplayCAN();
      }
      if(CotrolVale == 0x80) // 0x80
      {
            WarningText();
      }

      if(can_message_received)
      {
            can_message_received=0;

            if(led_status)
            {
                led_status=0;
                GPIO_ResetBits(GPIOC,GPIO_Pin_14);// Open LED
            }
            else
            {
                led_status=1;
                GPIO_SetBits(GPIOC,GPIO_Pin_14);// Close LED
            }
      }
    }
}最后再次感谢小管家这个给力的活动!!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分析仪的上位机软件
页: [1]
查看完整版本: [GD32F103] CAN抓包小工具