stm1024 发表于 2018-2-28 09:12:19

关于STM32F10x CAN不进入接收中断的问题

本帖最后由 stm1024 于 2018-2-28 09:30 编辑

手头有一块开发板,用的是STM32F103ZET6,确认使用的CAN1 RX和TX是标准的PA11和PA12,驱动电路为TJA1040。然后想学习一下CAN的发送和接收,以下是代码:

CAN函数
已经将其配置为环回模式,然后也在NVIC中打开了相应的中断。
#include "XDCAN.h"

void XDCAN_Config(void)
{
    XDCAN_GPIO_Config();
    XDCAN_NVIC_config();
   
    XDCAN_Mode_Config();
    XDCAN_Add_Filter(0x6666,14);
}

//config PA11 and PA12 for CAN1
void XDCAN_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
    //PA11 For CAN1-RX
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    //PA12 For CAN1-TX
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
      GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStruct);      
}

//config NVIC for CAN1
void XDCAN_NVIC_config(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
      NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStruct);
   
    //CAN interrupt sources
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
   
}


//Config CAN1 work mode, baudrate 250kbps
void XDCAN_Mode_Config(void)
{
    CAN_InitTypeDef CAN_InitStruct;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    CAN_DeInit(CAN1);
      CAN_StructInit(&CAN_InitStruct);
    CAN_InitStruct.CAN_TTCM = DISABLE;
      CAN_InitStruct.CAN_ABOM = DISABLE;
      CAN_InitStruct.CAN_AWUM = DISABLE;
      CAN_InitStruct.CAN_NART = DISABLE;
      CAN_InitStruct.CAN_RFLM = DISABLE;
      CAN_InitStruct.CAN_TXFP = DISABLE;
      CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack;
      CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
   
    /*
      APB1 36MHz
      36M/((1+3+2)*24)=250kbps
    */
    CAN_InitStruct.CAN_BS1 = CAN_BS1_3tq;
      CAN_InitStruct.CAN_BS2 = CAN_BS2_2tq;
      CAN_InitStruct.CAN_Prescaler = 24;
      CAN_Init(CAN1, &CAN_InitStruct);
   
}

//
void XDCAN_Add_Filter(uint32_t id,uint8_t fn)
{
    CAN_FilterInitTypeDef CAN_FilterInitStruct;
    CAN_FilterInitStruct.CAN_FilterNumber=fn;//filter number,can be 0-13
    CAN_FilterInitStruct.CAN_FilterMode=CAN_FilterMode_IdMask;
    CAN_FilterInitStruct.CAN_FilterScale=CAN_FilterScale_32bit;
    CAN_FilterInitStruct.CAN_FilterIdHigh=0x0000;
    CAN_FilterInitStruct.CAN_FilterIdLow=0x0000;
    //do not Match
    CAN_FilterInitStruct.CAN_FilterMaskIdHigh=0x0000;
    CAN_FilterInitStruct.CAN_FilterMaskIdLow=0x0000;
   
    CAN_FilterInitStruct.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;   
    CAN_FilterInitStruct.CAN_FilterActivation=ENABLE;
   
    CAN_FilterInit(&CAN_FilterInitStruct);
    //CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIF0消息挂号中断允许
}

//Send a CAN Message, Extended Data Frame
uint8_t XDCAN_SendMsg(uint32_t id, uint8_t len, uint8_t *dat)
{
      uint8_t i = 0,tm;
      CanTxMsg TxMsg;
    if(len > 8)
      return 0xff;

    TxMsg.ExtId=id;
      TxMsg.RTR = CAN_RTR_DATA;
    TxMsg.IDE = CAN_ID_EXT;   
      TxMsg.DLC = len;

      for(i=0; i<len; i++)               
      {
                TxMsg.Data = *dat;
                dat++;      
      }
      tm=CAN_Transmit(CAN1, &TxMsg);
    return tm;
}
main函数
#include "stm32f10x.h"
#include "XDUtility.h"//Delay_ms
#include "led.h"
#include "XDCAN.h"

uint8_t MSGBUFF="666";
uint8_t rb;

void USER_Config(void)
{
    //TO DO: Add User Configuration Here      
    USART1_Config();
    LED_GPIO_Config();
    XDCAN_Config();
}

int main(void)
{
    uint8_t ts,tmb,cnt=0,Status;
    uint32_t can_id=0;
    CanRxMsg RxMsg;
    USER_Config();
    LED_On();
    //XD_Delay_ms(500);
    LED_Off();
    while (1)
    {
      LED_On();
      tmb=XDCAN_SendMsg(can_id,3,MSGBUFF);
XD_Delay_ms(100);
      LED_Off();
      can_id++;
      ts=CAN_TransmitStatus(CAN1,tmb);
      if(ts==CAN_TxStatus_Ok)
      {
            cnt++;
      }

XD_Delay_ms(1000);   
    } //while
}


stm32f10x_it.c中的中断函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    CanRxMsg RxMsg;
    CAN_Receive(CAN1,CAN_FIFO0,&RxMsg);
    CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    XD_Delay_ms(500);
}首先,调试可以发现发送是OK的:

然而,不管是用Simulator还是JLink调试,总是进不去中断,接收邮箱也一直是空的(见下图)不知道是怎么回事?


是否在环回模式下不支持这种功能?有碰到过类似问题并解决过的兄弟,能否讲解一下?

另外,我也试过在main函数中直接用polling的方式接收,然而发送完成之后使用CAN_MessagePending每次返回的结果都是0……


cuyebiren 发表于 2018-2-28 10:47:27


把此处的 14 改为 0-13 的数试试。

此处有提到。

此处不应屏蔽,否则进不了中断。

参考手册上多次提到非互联型产品只有0-13个过滤器可用。


STM32F103ZET6是非互联型产品。

stm1024 发表于 2018-2-28 11:39:38

本帖最后由 stm1024 于 2018-2-28 11:42 编辑

cuyebiren 发表于 2018-2-28 10:47
把此处的 14 改为 0-13 的数试试。

此处有提到。

感谢您的认真回复。
第一个地方,我确实是一开始使用的第0组过滤器,然而并不成功。
CAN_IT_Config那个,我把它放在了void XDCAN_NVIC_config(void)的最后一句中,然后我在调试的时候也检查过IER寄存器,FMPIE0是打开的:

另外,我不知道之前怎么鬼改改的,现在发送的状态都一直是CAN_TxStatus_Pending,这么看来发送都不成功了?

toofree 发表于 2018-2-28 23:53:56

建议先把固件库中的CAN例子跑通,内回环模式和正常工作模式样例都有。


mokart 发表于 2019-8-6 15:12:30

我设置为回环模式,刚刚开始也是接收中断不进入,后来检查了半天是接收屏蔽的设置问题。

bird0123 发表于 2019-8-7 09:23:34

学习了

generalcircuits 发表于 2019-8-7 14:50:50

把此处的 14 改为 0-13 的数,还是没用吗?那问题出在哪里?

stm1024 发表于 2019-8-10 08:08:28

generalcircuits 发表于 2019-8-7 14:50
把此处的 14 改为 0-13 的数,还是没用吗?那问题出在哪里?

老早就解决了,是供电问题,必须要用5V供电,我用的是3.3V

yyc123 发表于 2019-8-23 10:19:02

mokart 发表于 2019-8-6 15:12
我设置为回环模式,刚刚开始也是接收中断不进入,后来检查了半天是接收屏蔽的设置问题。 ...

接收屏蔽怎么设置的,我的也是回环模式不能进入中断。发送完成中断和接收中断都不能进入,头都大了
页: [1]
查看完整版本: 关于STM32F10x CAN不进入接收中断的问题