最近做一个单片机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);
}
}
} |