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