STM32
直播中

陈伟

7年用户 1448经验值
私信 关注
[问答]

TJA1050与CAN模块是怎样进行连接的

STM32F103C8T6与TJA1050是怎样进行连接的?

TJA1050与CAN模块是怎样进行连接的?

回帖(1)

刘璇

2021-10-22 10:44:00
  这是我聪明做的一个功能,有一些细节没注意,导致移植没通,现在记下来。
  一、硬件部分
  STM32F103C8T6:2个,记为STM32(1),STM32(2)
  TJA1050(CAN模块) ):2个,记为TJA(1),TJA(2)
  STM32(1)的RX接TJA(1)的RX,TX接TX。TJA(1)的CAN_H接另一个TJA(2)的CAN_H, CAN_L接CAN_L。然后TJA(2)的RX接STM32(2)的RX,TX接TX。
  二、软件部分
  注释:软件参考了网上的一些朋友的代码,如果雷同,纯属参考学习,谢谢!
  u8 CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  CAN_InitTypeDef CAN_InitStructure;
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  #if CAN1_RX0_INT_ENABLE
  NVIC_InitTypeDef NVIC_InitStructure;
  #endif
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  CAN_InitStructure.CAN_TTCM=DISABLE;
  CAN_InitStructure.CAN_ABOM=DISABLE;
  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=tsjw;
  CAN_InitStructure.CAN_BS1=tbs1;
  CAN_InitStructure.CAN_BS2=tbs2;
  CAN_InitStructure.CAN_Prescaler=brp;
  CAN_Init(CAN1, &CAN_InitStructure);
  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);
  #if CAN1_RX0_INT_ENABLE
  CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
  CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);
  CAN_ITConfig(CAN1,CAN_IT_BOF,ENABLE);
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  #endif
  return 0;
  }
  #if CAN1_RX0_INT_ENABLE
  void USB_LP_CAN1_RX0_IRQHandler(void)
  {
  int i=0;
  CanRxMsg RxMessage;
  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.RTR=0;
  RxMessage.FMI=0;
  for(i=0;i《8;i++)
  RxMessage.Data[i]=0;
  CAN_Receive(CAN1, 0, &RxMessage);
  //USART1_DATA(RxMessage.Data,RxMessage.DLC);
  printf(“IRQ RxMessage.Data = %srn”, RxMessage.Data);
  }
  #endif
  u8 CAN1_Send_Msg(u8* msg,u8 len)
  {
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;
  TxMessage.ExtId=0x12;
  TxMessage.IDE=CAN_ID_STD;
  TxMessage.RTR=CAN_RTR_Data;
  TxMessage.DLC=len;
  for(i=0;i《len;i++)
  TxMessage.Data[i]=*(msg+i);
  mbox= CAN_Transmit(CAN1, &TxMessage);
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i《0XFFF))i++; /
  if(i》=0XFFF)return 1;
  return 0;
  }
  int main(void)
  {
  u8 i,cnt,len,res;
  u8 canbuf[8];
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  uart_init();
  CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,0);
  printf(“stm32 startup!rn”);
  while(1)
  {
  #if 1
  delay_ms(1000);
  len = 8;
  cnt = ‘a’;
  for(i=0;i《len;i++)
  {
  canbuf[i]=cnt+i;
  }
  res = CAN1_Send_Msg(canbuf, len);
  #endif
  }
  }
  两个STM32都烧写程序,然后接上字节,1s会收到另一个STM32发来的8个字节的abcdefgh。
  注意事项:
  1、TJA1050供电5V
  2、用printf打印数据,如果使用USART_SendData必须等待发送完成再发送下一个编码。循环打印可以参考如下:
  void USART1_DATA(unsigned char *lb,unsigned int len)
  {
  unsigned int i;
  for(i=0;i《len;i++)
  {
  USART_SendData(USART1,*lb);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
  {
  }
  lb ++;
  }
  }
  3、CAN_TX和CAN_RX的GPIO属性配置不一样,要注意一下。
  4、CAN1_RX0_INT_ENABLE置为1。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分