CH32V203 中 CAN 测试模式疑问

CH32V203 中 CAN 在测试模式中,比如开启静默环回模式。重新进入初始化模式,对寄存器 CAN_BTIMR 的 SILM 和 LBKM 位置0(寄存器置0成功),退出初始化模式,静默环回模式依旧存在,需重新上下电才能恢复,请问这是特性吗?

/* 官方程序 */
uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
{
  uint8_t InitStatus = CAN_InitStatus_Failed;
  uint32_t wait_ack = 0x00000000;

  CANx->CTLR &= (~(uint32_t)CAN_CTLR_SLEEP);
  CANx->CTLR |= CAN_CTLR_INRQ ;

  while (((CANx->STATR & CAN_STATR_INAK) != CAN_STATR_INAK) && (wait_ack != INAK_TIMEOUT))
  {
    wait_ack++;
  }

  if ((CANx->STATR & CAN_STATR_INAK) != CAN_STATR_INAK)
  {
    InitStatus = CAN_InitStatus_Failed;
  }
  else 
  {
    if (CAN_InitStruct->CAN_TTCM == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_TTCM;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_TTCM;
    }

    if (CAN_InitStruct->CAN_ABOM == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_ABOM;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_ABOM;
    }

    if (CAN_InitStruct->CAN_AWUM == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_AWUM;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_AWUM;
    }

    if (CAN_InitStruct->CAN_NART == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_NART;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_NART;
    }

    if (CAN_InitStruct->CAN_RFLM == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_RFLM;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_RFLM;
    }

    if (CAN_InitStruct->CAN_TXFP == ENABLE)
    {
      CANx->CTLR |= CAN_CTLR_TXFP;
    }
    else
    {
      CANx->CTLR &= ~(uint32_t)CAN_CTLR_TXFP;
    }

    CANx->BTIMR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | \
                ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | \
                ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | \
                ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | \
                ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1);
    CANx->CTLR &= ~(uint32_t)CAN_CTLR_INRQ;
    wait_ack = 0;

    while (((CANx->STATR & CAN_STATR_INAK) == CAN_STATR_INAK) && (wait_ack != INAK_TIMEOUT))
    {
      wait_ack++;
    }

    if ((CANx->STATR & CAN_STATR_INAK) == CAN_STATR_INAK)
    {
      InitStatus = CAN_InitStatus_Failed;
    }
    else
    {
      InitStatus = CAN_InitStatus_Success ;
    }
  }

  return InitStatus;
}


您好,CH32V203 CAN有3种工作模式:初始化模式、睡眠模式和正常模式3种模式。只能在初始化模式下修改CAN_BTIMR 的 SILM 和 LBKM位配置来选择一种测试模式,测试模式有3种:静默模式,环回模式,静默环回模式。若要切换工作模式,需要对寄存器CAN_CTLR 中的 SLEEP 或 INRQ 位进行操作切换3种工作模式,具体可参考CH32V203应用手册介绍,如下图。后续若有问题,可通过邮箱和我沟通(lzs@wch.cn)

CH32V203应用手册:https://www.wch.cn/downloads/CH32FV2x_V3xRM_PDF.html?

image.png


int main(void)
{
    u8 i;
    u8 cnt = 0;
    u8 tx, rx;
    u8 txbuf[8];
    u8 rxbuf[8];

    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
/*
Bps = 250Kbps 
选择静默环回模式
*/
    CAN_Test_Mode_Init(CAN_SJW_1tq, CAN_BS2_5tq, CAN_BS1_6tq, 12, CAN_Mode_Silent_LoopBack);
    
/* 再选择正常模式,发现静默环回依旧存在 */
    CAN_Test_Mode_Init(CAN_SJW_1tq, CAN_BS2_5tq, CAN_BS1_6tq, 12, CAN_Mode_Normal);

    while(1)
    {
        for(i = 0; i < 8; i++) {
            txbuf[i] = cnt + i;
        }

        tx = CAN_Send_Msg(txbuf, 8);

        if(tx)
        {
            printf("Send Failed\r\n");
        }
        else
        {
            printf("Send Success\r\n");
            printf("Send Data:\r\n");

            for(i = 0; i < 8; i++) {
                printf("%02x\r\n", txbuf[i]);
            }
        }

        rx = CAN_Receive_Msg(rxbuf);

        if(rx)
        {
            printf("Receive Data:\r\n");

            for(i = 0; i < 8; i++) {
                printf("%02x\r\n", txbuf[i]);
            }
        }
        else
        {
            printf("No Receive Data\r\n");
        }

        Delay_Ms(1000);
        cnt++;
        if(cnt == 0xFF)
        {
            cnt = 0;
        }
    }
}

是的,我知道怎么切换工作模式,但是在切换的过程中出现了问题,静默环回无法退出。


您好,你可以按照下图配置一下就可以了,加个CAN_DeInit函数

image.png


谢谢,已解决。确实是我能力不够,没有想到这方面。


只有登录才能回复,可以选择微信账号登录