打印
[STM32F0]

072can发送突然无法发送了,怎么回事

[复制链接]
2422|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liguang02|  楼主 | 2014-8-27 22:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CAN, IO, pi, GPIO, gp
使用官方的初始化,以及发送判断函数,50ms发送一次,有什么原因会导致可以正常发送的但是突然无法在发送了,重新上电有正常了
下面是相关代码:
/**
  * @brief  This function :
             - Enables GPIO clock
             - Configures the CAN pins on GPIO PA11 PA12
  * @param  None
  * @retval None
  */
__INLINE void Configure_GPIO_CAN(void)
{
  /* Enable the peripheral clock of GPIOA */
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
   
  /* GPIO configuration for CAN signals */
  /* (1) Select AF mode (10) on PA11 and PA12 */
  /* (2) AF4 for CAN signals */
  GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER11 | GPIO_MODER_MODER12))\
                 | (GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1); /* (1) */
  GPIOA->AFR[1] = (GPIOA->AFR[1] &~ (GPIO_AFRH_AFR11 | GPIO_AFRH_AFR12))\
                  | (4 << (3 * 4)) | (4 << (4 * 4)); /* (2) */
}


/**
  * @brief  This function configures CAN.
  * @param  None
  * @retval None
  */
__INLINE void Configure_CAN(void)
{
  /* Enable the peripheral clock CAN */
  RCC->APB1ENR |= RCC_APB1ENR_CANEN;
  uint32_t wait_ack = 0x00000000;
  /* Configure CAN */
  /* (1) Enter CAN init mode to write the configuration */
  /* (2) Wait the init mode entering */
  /* (3) Exit sleep mode */
  /* (4) Loopback mode, set timing to 1Mb/s: BS1 = 4, BS2 = 3, prescaler = 6 */
  /* (5) Leave init mode */
  /* (6) Wait the init mode leaving */
  /* (7) Enter filter init mode, (16-bit + mask, filter 0 for FIFO 0) */
  /* (8) Acivate filter 0 */
  /* (9) Identifier list mode */
  /* (11) Set the Id list */
  /* (12) Set the Id + mask (all bits of standard id will care) */
  /* (13) Leave filter init */
  /* (14) Set FIFO0 message pending IT enable */
  CAN->MCR |= CAN_MCR_INRQ; /* (1) */
  while((CAN->MSR & CAN_MSR_INAK)!=CAN_MSR_INAK) /* (2) */
  {
    wait_ack++;
    /* add time out here for a robust application */
  }
  wait_ack=0;
  CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
  //CAN->BTR |= CAN_BTR_LBKM | 2 << 20 | 3 << 16 | 5 << 0; /* (4) */
  //CAN->BTR |= 2 << 20 | 3 << 16 | 5 << 0; /* (4) 左移20位表示BS2,左移16位表示BS1,低十位表示预分频,位25,24表示同步,然后加1表示实际同步*/
  //CAN->BTR |= 2 << 20 | 3 << 16 | 47 << 0; /*125000波特率*/
  CAN->BTR |= 2 << 20 | 3 << 16 | 11 << 0;      /*500000波特率,48/(1+3+4)/(11+1)*/
  CAN->MCR &=~ CAN_MCR_INRQ; /* (5) */
  while((CAN->MSR & CAN_MSR_INAK)==CAN_MSR_INAK) /* (6) */
  {
    wait_ack++;
    /* add time out here for a robust application */
  }
  wait_ack=0;  
  CAN->FMR = CAN_FMR_FINIT; /* (7) 进入过滤器初始化模式*/
  CAN->FA1R = CAN_FA1R_FACT0; /* (8)激活过滤器0 */
#if (FILTER_LIST)  
  CAN->FM1R = CAN_FM1R_FBM0; /* (9) */
  CAN->sFilterRegister[0].FR1 = CAN_ID2 << 5 | CAN_ID1 << (16+5); /* (10) */
#else  
  //CAN->sFilterRegister[0].FR1 = CAN_ID1 << 5 | CAN_ID_MASK << 16; /* (11)关注低16位, */
  CAN->sFilterRegister[0].FR1 = 0;
#endif /* FILTER_LIST */
  
  CAN->FMR &=~ CAN_FMR_FINIT; /* (12)激活过滤器0 */
  CAN->IER |= CAN_IER_FMPIE0; /* (13) 接收中断*/
  
  /* Configure IT */
  /* (14) Set priority for CAN_IRQn */
  /* (15) Enable CAN_IRQn */
  NVIC_SetPriority(CEC_CAN_IRQn, 0); /* (16) */
  NVIC_EnableIRQ(CEC_CAN_IRQn); /* (17) */
}


void CAN_send_0(void)
{
  if((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0)/* check mailbox 0 is empty */
  {
    CAN->sTxMailBox[0].TDTR = 8; /* fill data length = 1 */
    CAN->sTxMailBox[0].TDLR = value_0; /* fill 8-bit data */
    CAN->sTxMailBox[0].TDHR = 0; /* fill 8-bit data */
    CAN->sTxMailBox[0].TIR = (uint32_t)(CAN_ID1 << 21 | CAN_TI0R_TXRQ); /* fill Id field and request a transmission */
  }
  else
  {
   CAN->TSR |= CAN_TSR_ABRQ0; /* abort transmission if not empty */
  }
}
can发送代码,
void CAN_send_1(void)
{
  if((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1)/* check mailbox 1 is empty */
  {
    CAN->sTxMailBox[1].TDTR = 8; /* fill data length = 1 */
    CAN->sTxMailBox[1].TDLR = value_1; /* fill 8-bit data */
    CAN->sTxMailBox[1].TDHR = 0; /* fill 8-bit data */
    CAN->sTxMailBox[1].TIR = (uint32_t)(CAN_ID2 << 21 | CAN_TI0R_TXRQ); /* fill Id field and request a transmission */
  }
  else
  {
    CAN->TSR |= CAN_TSR_ABRQ1; /* abort transmission if not empty */
  }
}

void CAN_send_2(void)
{
  if((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2)/* check mailbox 1 is empty */
  {
    CAN->sTxMailBox[2].TDTR = 8; /* fill data length = 1 */
    CAN->sTxMailBox[2].TDLR = 0xffffffff; /* fill 8-bit data */
    CAN->sTxMailBox[2].TDHR = value_2; /* fill 8-bit data */
    CAN->sTxMailBox[2].TIR = (uint32_t)(CAN_ID3 << 21 | CAN_TI0R_TXRQ); /* fill Id field and request a transmission */
  }
  else
  {
    CAN->TSR |= CAN_TSR_ABRQ2; /* abort transmission if not empty */
  }
}
有没有人了解原因的?

沙发
grant_jx| | 2014-8-27 22:18 | 只看该作者
Debug下,监视你的发送错误状态寄存器,看看里面有啥变化?

使用特权

评论回复
板凳
mmuuss586| | 2014-8-28 08:40 | 只看该作者
有可能电源,复位,晶振不稳定,或板子画的不好导致抗干扰差……

先找下问题的规律,看是偶尔出现,还是有规律的;
偶尔就比较麻烦;
有规律的话,在你怀疑的有问题的程序点,通过串口或显示屏输出调试信息,判断在哪段程序出问题了;

使用特权

评论回复
地板
liguang02|  楼主 | 2014-8-28 13:03 | 只看该作者
grant_jx 发表于 2014-8-27 22:18
Debug下,监视你的发送错误状态寄存器,看看里面有啥变化?

我使用3个发送邮箱一起发送数据会怎么样?  CAN_send_0(); CAN_send_1();     
      CAN_send_2();

使用特权

评论回复
5
liguang02|  楼主 | 2014-8-28 13:05 | 只看该作者
mmuuss586 发表于 2014-8-28 08:40
有可能电源,复位,晶振不稳定,或板子画的不好导致抗干扰差……

先找下问题的规律,看是偶尔出现,还是有 ...

我使用3个发送邮箱一起发送数据会怎么样?
    if(tim_2_flag==1)
    {
      touch_process();
      VOL_processing();
      CAN_send_0();             /* 发送id0x222can控制命令 */
      CAN_send_1();     /* 发送id0x362can控制命令 */
      CAN_send_2();
      tim_2_flag=0;
    }

使用特权

评论回复
6
zh113214| | 2014-8-28 21:54 | 只看该作者
进来看看 好长的代码啊,表示学习一下。

使用特权

评论回复
7
grant_jx| | 2014-9-1 20:53 | 只看该作者
liguang02 发表于 2014-8-28 13:05
我使用3个发送邮箱一起发送数据会怎么样?
    if(tim_2_flag==1)
    {

不会怎么样啊,按次序呗,邮箱有优先级;显性优先的原则,报文的ID也有优先级。谁高谁先出去。

使用特权

评论回复
8
zh113214| | 2014-9-1 23:18 | 只看该作者
进来看看,好长的代码啊,感觉Debug也挺多的。。呵呵

使用特权

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

本版积分规则

56

主题

307

帖子

2

粉丝