打印

STM32F103VC CAN

[复制链接]
1282|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huangfeng33|  楼主 | 2014-7-7 20:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近做一个单片机CAN通信的项目, 用的单片机为STM32F103VC,  控制器为NXP的JA1040
设置波特率为20K,帧间发送间隔为100 ms时 总是有1%左右的丢帧率(2000条丢20条左右). 设成20K,发送间隔为500ms时接收正常,没有出现丢帧现象. 期间我已经将CAN接收的中断优先级设为抢占最高级了, 确实找不到软件方面还有其他什么原因.
   而我把发送波特率改为250K时, 接收一切正常,查了好久帧间发送间隔改为50ms仍然能接收正常.小于50ms,由于buffer的原因申请不到缓存,所以不确定能否接收正常.
请各位大大帮忙分析下是哪方面的原因???是我设置的问题还是??

我用的是12M晶振, 72M主频!

void  CAN1Init(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;
//    NVIC_InitTypeDef        NVIC_InitStructure;
    CAN_InitTypeDef         CAN_InitStructure;
    CAN_FilterInitTypeDef   CAN_FilterInitStructure;

    /* Configure CAN1 IOs        */
    /* GPIOA, AFIO clocks enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /* Can Rx */
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    /* Can Tx */
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA,&GPIO_InitStructure);


    /* CAN1 and CAN2 register init */
    CAN_DeInit(CAN1);
    /* Struct init*/
    CAN_StructInit(&CAN_InitStructure);
    /* CAN1 cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;                       // time triggered comnunication mode
    CAN_InitStructure.CAN_ABOM = DISABLE;                       // automatic bus off management
    CAN_InitStructure.CAN_AWUM = DISABLE;                       // automatic wakeup mode
    CAN_InitStructure.CAN_NART = DISABLE;                       // no automatic retransmission
    CAN_InitStructure.CAN_RFLM = DISABLE;                       // receive FIFO locked mode
    CAN_InitStructure.CAN_TXFP = DISABLE;                       // transmit FIFO priority
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;  
    CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;

#if CAN_BAUDRATE == 1000 /* 1MBps */
    CAN_InitStructure.CAN_Prescaler =6;
#elif CAN_BAUDRATE == 500 /* 500KBps */
    CAN_InitStructure.CAN_Prescaler =12;
#elif CAN_BAUDRATE == 250 /* 250KBps */
    CAN_InitStructure.CAN_Prescaler =24;
#elif CAN_BAUDRATE == 125 /* 125KBps */
    CAN_InitStructure.CAN_Prescaler =48;
#elif CAN_BAUDRATE == 100 /* 100KBps */
    CAN_InitStructure.CAN_Prescaler =60;
#elif CAN_BAUDRATE == 50 /* 50KBps */
    CAN_InitStructure.CAN_Prescaler =120;
#elif CAN_BAUDRATE == 20 /* 20KBps */
    CAN_InitStructure.CAN_Prescaler =300;
#elif CAN_BAUDRATE == 10 /* 10KBps */
    CAN_InitStructure.CAN_Prescaler =600;
#else
#error "Please select the CAN Baudrate in Private defines"
#endif  /* CAN_BAUDRATE == 1000 */

    /*Initializes the CAN1  and CAN2 */
    CAN_Init(CAN1, &CAN_InitStructure);

    /* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber         = 0;                     /* 指定了待初始化的过滤器0 */
    CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask; /* 指定了过滤器将被初始化到的模式为标识符屏蔽位模式 */
    CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit; /* 给出了过滤器位宽1个32位过滤器 */
    CAN_FilterInitStructure.CAN_FilterIdHigh         = 0x0000;    /* 用来设定过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个) */
    CAN_FilterInitStructure.CAN_FilterIdLow          = 0x0000;    /* 用来设定过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个)  */
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = 0x0000;    /* 用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个) */
    CAN_FilterInitStructure.CAN_FilterMaskIdLow      = 0x0000;    /* 用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个)  */
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; /* 设定了指向过滤器的FIFO0  */
    CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;    /* 使能过滤器               */
    CAN_FilterInit(&CAN_FilterInitStructure);  

    CAN_ITConfig(CAN1, CAN_IT_FMP0 , ENABLE);  /* fifo0中断 */
//    CAN_ITConfig(CAN1, CAN_IT_FMP1 , ENABLE);  /* fifo1中断 */
    CAN_ITConfig(CAN1, CAN_IT_TME,   DISABLE); /* 发送中断  */
}

void SendCanMsg(CAN_TypeDef* CANx, CanTxMsg *pTxMessage)
{
    CAN_Transmit(CANx, pTxMessage);
    return;
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
    CanRxMsg RxMessage;
    u8 CAN_Len = sizeof(CanRxMsg);

    while(CAN_MessagePending(CAN1, CAN_FIFO0))
    {
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);   /* read the message */

        u8 *pTmpBuf = Get_CirBuf(&g_CAN_Rcv_Q, CAN_Len);
        if(NULL != pTmpBuf)
        {
            memcpy((char *)pTmpBuf, (void *)&RxMessage, CAN_Len);

            ST_MESSAGE stMsg;
            stMsg.udwParam1 = (u32)pTmpBuf;
            stMsg.udwParam2 = CAN_Len;
            PushQueue(&g_CAN_Rcv_Q, &stMsg);
        }
        else
        {
            TRACE("Err,Get CanBuf:%d Fail!\n", CAN_Len);
        }
    }
}
沙发
拿起书本| | 2014-7-8 21:01 | 只看该作者
感觉楼主CAN分频参数有问题吧,仔细确认下。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

506

主题

2446

帖子

8

粉丝