esp32开发与应用(题外话之PCAN调试器)

esp32开发与应用(题外话之PCAN调试器)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

can其实在工业、医疗和运输业用的很多,但是很多朋友可能仅仅用过ttl,最多加上一个232或者是485,这个时候就可以看看can。如果自己需要调试can,特别是只有一个板子的情况下,可以买一个pcan调试器。

1、pcan是什么

pcan就是一个usb转can的模块,插在电脑上。买过来的时候,里面的hex都是烧入好的,不需要自己烧入了。

2、安装驱动PEAK

和hid/com口类的免驱模块相比较,pcan需要自己安装驱动文件。驱动文件的名称就是PEAK-System_Driver-Setup-v500.zip。

3、安装上位机软件pcanview

驱动安装好,pcan插上去的时候,在设备管理器上就不会显示异常节点了。这个时候,我们需要安装一个上位机就可以了,这个上位机就是pcanview。

4、物理连线

连线的时候,除了canh和canl,另外别忘记连接gnd。

5、没有can设备怎么办

自己想学习can设备,但是没有板子发can报文怎么办,其实可以找一个带can接口的stm32f103c8t6发can协议报文即可,

#include "stm32f10x.h" // Device header #include <stdio.h> #include <string.h> /* ================= Delay Functions ================= */ static void Delay_us(uint32_t xus) { SysTick->LOAD = 72 * xus; SysTick->VAL = 0x00; SysTick->CTRL = 0x00000005; while(!(SysTick->CTRL & 0x00010000)); SysTick->CTRL = 0x00000004; } static void Delay_ms(uint32_t xms) { while(xms--) { Delay_us(1000); } } /* ================= USART1 (Debug output, PA9-TX / PA10-RX) ================= */ void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); // PA9 - TX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // PA10 - RX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void USART1_SendByte(uint8_t byte) { USART_SendData(USART1, byte); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } void USART1_SendString(char *str) { while (*str) { USART1_SendByte((uint8_t)*str); str++; } } /* ================= CAN1 (Remapped to PB8-RX / PB9-TX) ================= */ void CAN1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // CAN1 remap: CAN_RX -> PB8, CAN_TX -> PB9 GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); // PB8 - CAN_RX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); // PB9 - CAN_TX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = ENABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq; CAN_InitStructure.CAN_Prescaler = 4; // 500kbps @ APB1=36MHz CAN_Init(CAN1, &CAN_InitStructure); // Filter: accept all IDs CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); } // Send a standard data frame, returns 1 on success, 0 on failure uint8_t CAN1_SendData(uint32_t id, uint8_t *data, uint8_t len) { CanTxMsg TxMessage; uint8_t mbox; uint32_t i = 0; TxMessage.StdId = id; TxMessage.ExtId = 0; TxMessage.IDE = CAN_ID_STD; TxMessage.RTR = CAN_RTR_Data; TxMessage.DLC = len; for (i = 0; i < len; i++) { TxMessage.Data[i] = data[i]; } mbox = CAN_Transmit(CAN1, &TxMessage); i = 0; while ((CAN_TransmitStatus(CAN1, mbox) != CANTXOK) && (i < 0xFFFFF)) { i++; } return (i < 0xFFFFF) ? 1 : 0; } /* ================= main ================= */ int main(void) { char buf[96]; uint16_t counter = 0; uint8_t txData[8]; USART1_Init(); CAN1_Init(); USART1_SendString("===== CAN TX Demo Start (PB8/PB9, 500kbps) =====\r\n"); while (1) { txData[0] = (uint8_t)(counter >> 8); txData[1] = (uint8_t)(counter & 0xFF); txData[2] = 0xAA; txData[3] = 0xBB; txData[4] = 0xCC; txData[5] = 0xDD; txData[6] = 0xEE; txData[7] = 0xFF; if (CAN1_SendData(0x123, txData, 8)) { sprintf(buf, "[TX] ID:0x123 DATA: %02X %02X %02X %02X %02X %02X %02X %02X\r\n", txData[0], txData[1], txData[2], txData[3], txData[4], txData[5], txData[6], txData[7]); } else { sprintf(buf, "[TX] send failed!\r\n"); } USART1_SendString(buf); counter++; Delay_ms(500); // Send one frame every 500ms } }

6、配置pcanview,查看报文

一切都准备好之后,就可以打开pcanview,查看can报文了。注意有一点,就是波特率的设置。也就是pcan设置的速率,要和对应电路板上的can速率一致,比如都是500kb,不然看不到对应的报文。