我在用STM32F107做双CAN口测试时,遇到的问题是不管如何设置过滤器和ID,发送的数据都能够传送过去,先做个标记。程序代码如下,后续会回复问题的解决办法
问题解决办法:由于过滤器MASKID的设置错误,STDID所处的位置如下图所示,位于最高的11位,所以MASKID应该设置位0XFFF0 0000,简单设置位0XFFFF FFFF也可以。
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;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//ʹÄÜPORTAʱÖÓ
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//ʹÄÜCAN1ʱÖÓ
GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍì
GPIO_Init(GPIOB, &GPIO_InitStructure); //³õʼ»¯IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//ÉÏÀÊäÈë
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯IO
//CANµ¥ÔªÉèÖÃ
CAN_InitStructure.CAN_TTCM=DISABLE; //·Çʱ¼ä´¥·¢Í¨ÐÅģʽ //
CAN_InitStructure.CAN_ABOM=DISABLE; //Èí¼þ×Ô¶¯ÀëÏß¹ÜÀí //
CAN_InitStructure.CAN_AWUM=DISABLE; //˯Ãßģʽͨ¹ýÈí¼þ»½ÐÑ(Çå³ýCAN->MCRµÄSLEEPλ)//
CAN_InitStructure.CAN_NART=ENABLE; //½ûÖ¹±¨ÎÄ×Ô¶¯´«ËÍ //
CAN_InitStructure.CAN_RFLM=DISABLE; //±¨ÎIJ»Ëø¶¨,еĸ²¸Ç¾ÉµÄ //
CAN_InitStructure.CAN_TXFP=DISABLE; //ÓÅÏȼ¶Óɱ¨Îıêʶ·û¾ö¶¨ //
CAN_InitStructure.CAN_Mode= mode; //ģʽÉèÖ㺠mode:0,ÆÕͨģʽ;1,»Ø»·Ä£Ê½; //
//ÉèÖò¨ÌØÂÊ
CAN_InitStructure.CAN_SJW=tsjw; //ÖØÐÂͬ²½ÌøÔ¾¿í¶È(Tsjw)Ϊtsjw+1¸öʱ¼äµ¥Î» CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1¸öʱ¼äµ¥Î»CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1¸öʱ¼äµ¥Î»CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //·ÖƵϵÊý(Fdiv)Ϊbrp+1 //
CAN_Init(CAN1, &CAN_InitStructure); // ³õʼ»¯CAN1
CAN_FilterInitStructure.CAN_FilterNumber=0; //¹ýÂËÆ÷0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //±êʶ·ûÆÁ±Îλģʽ
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32λ
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32λID ÓÃÀ´È·¶¨½ÓÊÕµ½µÄÊý¾ÝIDµÄÆÚÍûÖµ
CAN_FilterInitStructure.CAN_FilterIdLow=0x0022;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32λMASK ÓÃÀ´È·¶¨±ØÐë¹ØÐĵÄÄǼ¸Î»Îª±ØÐë·ûºÏµÄIDλ
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x00FF;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//¹ýÂËÆ÷0¹ØÁªµ½FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //¼¤»î¹ýÂËÆ÷0
CAN_FilterInit(&CAN_FilterInitStructure);//Â˲¨Æ÷³õʼ»¯
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0ÏûÏ¢¹ÒºÅÖжÏÔÊÐí.
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // Ö÷ÓÅÏȼ¶Îª1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // ´ÎÓÅÏȼ¶Îª0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
//ÖжϷþÎñº¯Êý
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
int res;
LED2=!LED2;
CAN_Receive(CAN1, 0, &RxMessage);
if(RxMessage.Data[0]==112)
{
// canbuf[0]=111;
// res=Can2_Send_Msg(canbuf,8);//·¢ËÍ8¸ö×Ö½Ú
// if(res==0)
// {
// LED0=!LED0;
// }
LED1=!LED1;
}
// else if(RxMessage.Data[0]==112)
// {
// LED5=!LED5;
// }
// for(i=0;i<8;i++)
// printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}
//can·¢ËÍÒ»×éÊý¾Ý(¹Ì¶¨¸ñʽ:IDΪ0X12,±ê×¼Ö¡,Êý¾ÝÖ¡)
//len:Êý¾Ý³¤¶È(×î´óΪ8)
//msg:Êý¾ÝÖ¸Õë,×î´óΪ8¸ö×Ö½Ú.
//·µ»ØÖµ:0,³É¹¦;
// ÆäËû,ʧ°Ü;
u8 Can1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x0033; // ±ê×¼±êʶ·ûΪ0
TxMessage.ExtId=0x0000; // ÉèÖÃÀ©Õ¹±êʾ·û£¨29룩
TxMessage.IDE=0; // ʹÓñê×¼±êʶ·û
TxMessage.RTR=0; // ÏûÏ¢ÀàÐÍΪÊý¾ÝÖ¡£¬Ò»Ö¡8λ
TxMessage.DLC=len; // ·¢ËÍÁ½Ö¡ÐÅÏ¢
for(i=0;i=0XFFF)return 1;
return 0;
}
//can¿Ú½ÓÊÕÊý¾Ý²éѯ
//buf:Êý¾Ý»º´æÇø;
//·µ»ØÖµ:0,ÎÞÊý¾Ý±»ÊÕµ½;
// ÆäËû,½ÓÊÕµÄÊý¾Ý³¤¶È;
u8 Can1_Receive_Msg(u8 *buf)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //ûÓнÓÊÕµ½Êý¾Ý,Ö±½ÓÍ˳ö
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//¶ÁÈ¡Êý¾Ý
for(i=0;i<8;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}
/************************************************************************************************/
//CAN2³õʼ»¯º¯Êý
u8 CAN2_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//ʹÄÜPORTAʱÖÓ
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//ʹÄÜCAN1ʱÖÓ
GPIO_PinRemapConfig(GPIO_Remap_CAN2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍì
GPIO_Init(GPIOB, &GPIO_InitStructure); //³õʼ»¯IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//ÉÏÀÊäÈë
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯IO
//CANµ¥ÔªÉèÖÃ
CAN_InitStructure.CAN_TTCM=DISABLE; //·Çʱ¼ä´¥·¢Í¨ÐÅģʽ //
CAN_InitStructure.CAN_ABOM=DISABLE; //Èí¼þ×Ô¶¯ÀëÏß¹ÜÀí //
CAN_InitStructure.CAN_AWUM=DISABLE; //˯Ãßģʽͨ¹ýÈí¼þ»½ÐÑ(Çå³ýCAN->MCRµÄSLEEPλ)//
CAN_InitStructure.CAN_NART=ENABLE; //½ûÖ¹±¨ÎÄ×Ô¶¯´«ËÍ //
CAN_InitStructure.CAN_RFLM=DISABLE; //±¨ÎIJ»Ëø¶¨,еĸ²¸Ç¾ÉµÄ //
CAN_InitStructure.CAN_TXFP=DISABLE; //ÓÅÏȼ¶Óɱ¨Îıêʶ·û¾ö¶¨ //
CAN_InitStructure.CAN_Mode= mode; //ģʽÉèÖ㺠mode:0,ÆÕͨģʽ;1,»Ø»·Ä£Ê½; //
//ÉèÖò¨ÌØÂÊ
CAN_InitStructure.CAN_SJW=tsjw; //ÖØÐÂͬ²½ÌøÔ¾¿í¶È(Tsjw)Ϊtsjw+1¸öʱ¼äµ¥Î» CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1¸öʱ¼äµ¥Î»CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1¸öʱ¼äµ¥Î»CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //·ÖƵϵÊý(Fdiv)Ϊbrp+1 //
CAN_Init(CAN2, &CAN_InitStructure); // ³õʼ»¯CAN2
CAN_FilterInitStructure.CAN_FilterNumber=14; //¹ýÂËÆ÷14
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //±êʶ·ûÆÁ±Îλģʽ
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32λ
CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)0x33<<21)&0xffff0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)0x33<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;//32λMASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//¹ýÂËÆ÷14¹ØÁªµ½FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //¼¤»î¹ýÂËÆ÷0
// CAN_FilterInitStructure.CAN_FilterNumber=0;
// CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
// CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//CAN_FilterScale_16bit; //32bit
// CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<21)&0xffff0000)>>16;
// CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
// CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
// CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //?????
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1,CAN_IT_FMP0|CAN_IT_EPV, ENABLE);
CAN_FilterInit(&CAN_FilterInitStructure);//Â˲¨Æ÷³õʼ»¯
CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);//FIFO0ÏûÏ¢¹ÒºÅÖжÏÔÊÐí.
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // Ö÷ÓÅÏȼ¶Îª1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // ´ÎÓÅÏȼ¶Îª0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
//ÖжϷþÎñº¯Êý
void CAN2_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
int res;
CAN_Receive(CAN2, 0, &RxMessage);
if(RxMessage.Data[0]==1)
{
// canbuf[0]=112;
// res=Can1_Send_Msg(canbuf,8);//·¢ËÍ8¸ö×Ö½Ú
// if(res==0)
// {
LED1=!LED1;
// }
LED2=!LED2;
}
// else if(RxMessage.Data[0]==112)
// {
// LED5=!LED5;
// }
// for(i=0;i<8;i++)
// printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}
//can·¢ËÍÒ»×éÊý¾Ý(¹Ì¶¨¸ñʽ:IDΪ0X12,±ê×¼Ö¡,Êý¾ÝÖ¡)
//len:Êý¾Ý³¤¶È(×î´óΪ8)
//msg:Êý¾ÝÖ¸Õë,×î´óΪ8¸ö×Ö½Ú.
//·µ»ØÖµ:0,³É¹¦;
// ÆäËû,ʧ°Ü;
u8 Can2_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // ±ê×¼±êʶ·ûΪ0
TxMessage.ExtId=0x12; // ÉèÖÃÀ©Õ¹±êʾ·û£¨29룩
TxMessage.IDE=0; // ʹÓÃÀ©Õ¹±êʶ·û
TxMessage.RTR=0; // ÏûÏ¢ÀàÐÍΪÊý¾ÝÖ¡£¬Ò»Ö¡8λ
TxMessage.DLC=len; // ·¢ËÍÁ½Ö¡ÐÅÏ¢
for(i=0;i=0XFFF)return 1;
return 0;
}
//can¿Ú½ÓÊÕÊý¾Ý²éѯ
//buf:Êý¾Ý»º´æÇø;
//·µ»ØÖµ:0,ÎÞÊý¾Ý±»ÊÕµ½;
// ÆäËû,½ÓÊÕµÄÊý¾Ý³¤¶È;
u8 Can2_Receive_Msg(u8 *buf)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN2,CAN_FIFO0)==0)return 0; //ûÓнÓÊÕµ½Êý¾Ý,Ö±½ÓÍ˳ö
CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);//¶ÁÈ¡Êý¾Ý
for(i=0;i<8;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}