【 声明版权所有欢迎转载请勿用于商业用途。 联系信箱feixiaoxing 163.com】除了大家熟悉的ttl其实485和can用的也很多。485多用于工业can多用于汽车、航空和医疗两者是非常有价值的。ttl和232虽然方便但是容易受到干扰。比如假设旁边是一个运行的电机那么传输的数据就容易受到影响。485和can则没有这方面的烦恼。485可能大家比较熟悉毕竟本来就是ttl转变过来的唯独can其实学习的方法也很多。1、利用loopback学习can学习的时候不用两块板子不用canh和canl短接利用自环就可以学习can。这种情况下哪怕是最便宜的几块钱核心板也能跑起来。2、设计数据流转场景这里设计的场景就是板子借助于ttl从上位机拿到数据发送给can1又从can1接收到数据发回给上位机就是这么一个过程。3、利用ai生成代码如果自己不会写代码其实问题也不大可以通过ai生成代码自己能看懂、会修改就行。这里面为了方便可能会涉及到uart和can的接收中断。4、代码编译和测试生成的代码主要有两个部分一个是中断stm32f10x_it.c#include stm32f10x.h #define FRAME_LEN 8 extern uint8_t g_uartRxBuf[FRAME_LEN]; extern uint8_t g_uartRxIndex; extern uint8_t count; extern CanTxMsg TxMessage; extern CanRxMsg RxMessage; extern void USART1_SendBuffer(uint8_t *,uint8_t); void USART1_IRQHandler(void) { if(USART_GetITStatus( USART1, USART_IT_RXNE)!RESET) { g_uartRxBuf[g_uartRxIndex] USART_ReceiveData(USART1); count 1; if(g_uartRxIndexFRAME_LEN) { uint8_t i; g_uartRxIndex0; for(i0;iFRAME_LEN;i) TxMessage.Data[i]g_uartRxBuf[i]; TxMessage.DLC FRAME_LEN; CAN_Transmit( CAN1, TxMessage); } } } void USB_LP_CAN1_RX0_IRQHandler(void) { if(CAN_GetITStatus( CAN1, CAN_IT_FMP0)!RESET) { CAN_Receive( CAN1, CAN_FIFO0, RxMessage); USART1_SendBuffer( RxMessage.Data, RxMessage.DLC); CAN_ClearITPendingBit( CAN1, CAN_IT_FMP0); } }这部分直接替换原来的代码即可还有就是main.c#include stm32f10x.h #define FRAME_LEN 8 uint8_t g_uartRxBuf[FRAME_LEN]; uint8_t g_uartRxIndex 0; uint8_t count 0; CanTxMsg TxMessage; CanRxMsg RxMessage; void RCC_Config(void); void GPIO_Config(void); void NVIC_Config(void); void USART1_Config(void); void CAN1_Config(void); void USART1_SendBuffer(uint8_t *buf,uint8_t len); void RCC_Config(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN1, ENABLE); } void GPIO_Config(void) { GPIO_InitTypeDef g; g.GPIO_Speed GPIO_Speed_50MHz; g.GPIO_Pin GPIO_Pin_12; g.GPIO_Mode GPIO_Mode_Out_PP; GPIO_Init(GPIOB, g); g.GPIO_Pin GPIO_Pin_9; g.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOA,g); g.GPIO_Pin GPIO_Pin_10; g.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,g); g.GPIO_Pin GPIO_Pin_12; g.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOA,g); g.GPIO_Pin GPIO_Pin_11; g.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,g); } void NVIC_Config(void) { NVIC_InitTypeDef n; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); n.NVIC_IRQChannel USART1_IRQn; n.NVIC_IRQChannelPreemptionPriority 0; n.NVIC_IRQChannelSubPriority 0; n.NVIC_IRQChannelCmd ENABLE; NVIC_Init(n); n.NVIC_IRQChannel USB_LP_CAN1_RX0_IRQn; n.NVIC_IRQChannelPreemptionPriority 1; NVIC_Init(n); } void USART1_Config(void) { USART_InitTypeDef u; u.USART_BaudRate 115200; u.USART_WordLength USART_WordLength_8b; u.USART_StopBits USART_StopBits_1; u.USART_Parity USART_Parity_No; u.USART_HardwareFlowControl USART_HardwareFlowControl_None; u.USART_Mode USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1,u); USART_ITConfig( USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1,ENABLE); } void CAN1_Config(void) { CAN_InitTypeDef c; CAN_FilterInitTypeDef f; CAN_DeInit(CAN1); CAN_StructInit(c); c.CAN_Mode CAN_Mode_LoopBack; // loopback setting here!!! c.CAN_ABOM ENABLE; c.CAN_SJW CAN_SJW_1tq; c.CAN_BS1 CAN_BS1_8tq; c.CAN_BS2 CAN_BS2_3tq; c.CAN_Prescaler 6; CAN_Init(CAN1,c); f.CAN_FilterNumber 0; f.CAN_FilterMode CAN_FilterMode_IdMask; f.CAN_FilterScale CAN_FilterScale_32bit; f.CAN_FilterIdHigh 0; f.CAN_FilterIdLow 0; f.CAN_FilterMaskIdHigh 0; f.CAN_FilterMaskIdLow 0; f.CAN_FilterFIFOAssignment CAN_Filter_FIFO0; f.CAN_FilterActivation ENABLE; CAN_FilterInit(f); CAN_ITConfig( CAN1, CAN_IT_FMP0, ENABLE); } void USART1_SendByte(uint8_t d) { USART_SendData(USART1,d); while( USART_GetFlagStatus( USART1, USART_FLAG_TXE)RESET); } void USART1_SendBuffer(uint8_t *buf,uint8_t len) { uint8_t i; for(i0;ilen;i) USART1_SendByte(buf[i]); } int main(void) { RCC_Config(); GPIO_Config(); NVIC_Config(); USART1_Config(); CAN1_Config(); TxMessage.StdId 0x100; TxMessage.ExtId 0; TxMessage.IDE CAN_ID_STD; TxMessage.RTR CAN_RTR_DATA; TxMessage.DLC FRAME_LEN; while(1) { if(count 125) GPIO_SetBits(GPIOB, GPIO_Pin_12); else GPIO_ResetBits(GPIOB, GPIO_Pin_12); } }5、测试方法测试方法比较简单就是找来xcom或者是sscom循环输入看看有没有循环接收。