【问题标题】:Broken Frame of bxCAN from STM32F103?来自 STM32F103 的 bxCAN 帧损坏?
【发布时间】:2022-09-23 17:14:30
【问题描述】:

您好我正在STM32F103上做beCAN,我尝试发送一个简单的消息,它似乎正在发送,但是它没有正确发送,下面是逻辑分析仪的捕获和代码。 我是否错过了 CAN 配置上的某些内容,或者可能是硬件问题? pic of Logic Analyzer

CAN的单位:

RCC->APB1ENR |= (1 << CANEN);               // Enable CAN clock
RCC->APB2ENR |= (1 << AFIOEN);              // Enable AFIO clock

RCC->APB2ENR |= (1 << IOPAEN);              // Enable GPIOA clock

serialPrintln(\"CAN RCC Config.\");

//clear A11, A12
GPIOA->CRH   &= ~(0xFF000UL);               // Configure PA12(0b0000) and PA11(0b0000)

//Config A11, A12
GPIOA->CRH   |= (INPUT << MODE11)|(IN_PP_PD << CNF11)|(OUT50M << MODE12)|(AFIO_PP << CNF12);

//PA12 PULL-UP (CAN_TX)
GPIOA->ODR |= (1 << 12)|(1 << 11);


serialPrintln(\"CAN GPIO Config.\");

//CAN init

CAN1->MCR |= (1 << INRQ); //init CAN


serialPrintln(\"CAN Init.\");

while (!(   CAN1->MSR & (1 << INAK )  )); //Wait for CAN INIT

serialPrintln(\"CAN in Init mode.\");

GPIOB->ODR |= (1 << 9);

//CAN1->MCR = 0x41UL;
CAN1->MCR &= ~(1 << SLEEP);
CAN1->MCR |= (1 << ABOM);
CAN1->MCR &= ~(1 << DBF);

//CAN Set bitrate
CAN1->BTR = 0x1A000B;
serialPrintln(\"Set CAN Bitrate.\");

CAN1->MCR   &= ~(1 << INRQ);              //CAN1 to normal mode

 // Wait for normal mode
      for (uint16_t wait_ack = 0; wait_ack < 1000; wait_ack++) {
        if ((CAN1->MSR & 0x1UL) == 0) {
           can1 = 1;
          break;
        }
        //LL_mDelay(1000);
      }

      if (can1) {
        serialPrintln(\"CAN1 initialize ok\");
        GPIOB->ODR |= (1 << 8);
          } else {
        serialPrintln(\"CAN1 initialize fail!!\");
      }

这是传输部分:

      CAN1->sTxMailBox[0].TIR &= ~(0x7FF << STID);
      serialPrintln(\"clear Identifier Bits.\");


      CAN1->sTxMailBox[0].TIR |= (0x148 << STID);
      serialPrintln(\"Set Identifier\");

      CAN1->sTxMailBox[0].TIR &= ~((1 << IDE)|(1 << RTR));
      serialPrintln(\"Set Standard Identifire, Data Frame\");

      CAN1->sTxMailBox[0].TDTR &= ~(0x0F << DLC);
      serialPrintln(\"Clear DLC Bits.\");

      CAN1->sTxMailBox[0].TDTR |= (0x08 << DLC);
      serialPrintln(\"Set DLC.\");

      CAN1->sTxMailBox[0].TDLR = 0x42;
      CAN1->sTxMailBox[0].TDLR = (0x96 << 8);
      CAN1->sTxMailBox[0].TDLR = (0x02 << 16);
      CAN1->sTxMailBox[0].TDLR = (0x46 << 24);
      CAN1->sTxMailBox[0].TDHR = 0x55;
      CAN1->sTxMailBox[0].TDHR = (0x43 << 8);
      CAN1->sTxMailBox[0].TDHR = (0x4B << 16);
      CAN1->sTxMailBox[0].TDHR = (0x2E << 24);
      serialPrintln(\"Load Mailbox0\");

      CAN1->sTxMailBox[0].TIR |= (1 << TXRQ);
      serialPrintln(\"Mailbox0 Transmit Request\");

我错过了什么还是我做错了什么?

  • 除非您实际解释您正在测量的内容,否则该图片没有帮助。是 CANH 和 CANL 吗?发送和接收?一些片选信号?
  • 与您的问题无关,请注意带符号的左移是代码异味,因为将数据移入 int 的符号位会调用未定义的行为。例如(0x46 &lt;&lt; 24);,其中0x46 是一个(签名的)int 恰好是明确定义的(碰巧?)但(0x86 &lt;&lt; 24); 会调用未定义的行为。 &lt;&lt; 的左操作数应该总是是无符号类型!如0x46u &lt;&lt; 24

标签: embedded stm32 can-bus stm32f1 mcu


【解决方案1】:

我会写这个作为评论,但我没有足够的互联网点可以这样做,所以这里有一些问题: 您的 PCLK1 和 PCLK2 频率是多少?其他总线参与者的波特率是多少?您可能想查看参考手册中的位时序章节(Rev 21,第 24.7.7 章,p.670f)。这个工具也可以提供帮助:http://www.bittiming.can-wiki.info/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    相关资源
    最近更新 更多