CAN 一传输HAL_CAN_Transmit就死在函数里!求解~!

2019-07-21 07:45发布

本帖最后由 db520136 于 2018-11-17 15:07 编辑

代码也是使用原子哥的CAN例程移植的,只是我的板子是STM32F103CB的,型号不一样!下面的模式 回环和正常模式都试过
[mw_shl_code=applescript,true]#include "STM32F103_CAN.h"
#include "stm32f1xx_hal_can.h"
CAN_HandleTypeDef   CAN1_Handler;
CanTxMsgTypeDef     TxMessage;
CanRxMsgTypeDef     RxMessage;

u8 CAN1_Mode_Init(u32 tsjw,u32 tbs2,u32 tbs1,u16 brp,u32 mode)
{
    CAN_FilterConfTypeDef  CAN1_FilerConf;
    printf("OK0! ");
    CAN1_Handler.Instance=CAN1;
    CAN1_Handler.pTxMsg=&TxMessage;
    CAN1_Handler.pRxMsg=&RxMessage;
    CAN1_Handler.Init.Prescaler=brp;
    CAN1_Handler.Init.Mode=mode;
    CAN1_Handler.Init.SJW=tsjw;
    CAN1_Handler.Init.BS1=tbs1;
    CAN1_Handler.Init.BS2=tbs2;
    CAN1_Handler.Init.TTCM=DISABLE;
    CAN1_Handler.Init.ABOM=DISABLE;
    CAN1_Handler.Init.AWUM=DISABLE;
    CAN1_Handler.Init.NART=ENABLE;
    CAN1_Handler.Init.RFLM=DISABLE;
    CAN1_Handler.Init.TXFP=DISABLE;
    if(HAL_CAN_Init(&CAN1_Handler)!=HAL_OK) return 1;
     
    CAN1_FilerConf.FilterIdHigh=0X0000;
    CAN1_FilerConf.FilterIdLow=0X0000;
    CAN1_FilerConf.FilterMaskIdHigh=0X0000;
    CAN1_FilerConf.FilterMaskIdLow=0X0000;  
    CAN1_FilerConf.FilterFIFOAssignment=CAN_FILTER_FIFO0;
    CAN1_FilerConf.FilterNumber=0;
    CAN1_FilerConf.FilterMode=CAN_FILTERMODE_IDMASK;
    CAN1_FilerConf.FilterScale=CAN_FILTERSCALE_32BIT;
    CAN1_FilerConf.FilterActivation=ENABLE;
    CAN1_FilerConf.BankNumber=14;
    if(HAL_CAN_ConfigFilter(&CAN1_Handler,&CAN1_FilerConf)!=HAL_OK) return 2;
        printf("CAN Init OK! ");
    return 0;
}

void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
    GPIO_InitTypeDef GPIO_Initure;
      
   
    __HAL_RCC_CAN1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
     
    GPIO_Initure.Pin=GPIO_PIN_12;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;
    GPIO_Initure.Pull=GPIO_PULLUP;
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
     
    GPIO_Initure.Pin=GPIO_PIN_11;               //PA11
    GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
     
#if CAN1_RX0_INT_ENABLE
    __HAL_CAN_ENABLE_IT(&CAN1_Handler,CAN_IT_FMP0);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn,6,0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
#endif  
}


void CAN1_RX0_IRQHandler(void)
{
    HAL_CAN_IRQHandler(&CAN1_Handler);//′Ëoˉêy»áμ÷óÃCAN_Receive_IT()½óêÕêy¾Y
}


void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
    int i=0;

    __HAL_CAN_ENABLE_IT(&CAN1_Handler,CAN_IT_FMP0);
    printf("id:%d ",CAN1_Handler.pRxMsg->StdId);
    printf("ide:%d ",CAN1_Handler.pRxMsg->IDE);
    printf("rtr:%d ",CAN1_Handler.pRxMsg->RTR);
    printf("len:%d ",CAN1_Handler.pRxMsg->DLC);
    for(i=0;i<8;i++)
    printf("rxbuf[%d]:%d ",i,CAN1_Handler.pRxMsg->Data);
}
#endif  

u8 CAN1_Send_Msg(u8* msg,u8 len)
{  
    u16 i=0;
    CAN1_Handler.pTxMsg->StdId=0X12;
AN1_Handler.pTxMsg->ExtId=0x12;
    CAN1_Handler.pTxMsg->IDE=CAN_ID_STD;
    CAN1_Handler.pTxMsg->RTR=CAN_RTR_DATA;
    CAN1_Handler.pTxMsg->DLC=len;               
    for(i=0;i<len;i++)
    CAN1_Handler.pTxMsg->Data=msg;
    if(HAL_CAN_Transmit(&CAN1_Handler,10)!=HAL_OK)
        {
            printf("CAN Send ERR ");
            return 1;
        }
        printf("CAN Send OK ");
    return 0;      
}


u8 CAN1_Receive_Msg(u8 *buf)
{                 
u32 i;
    if(HAL_CAN_Receive(&CAN1_Handler,CAN_FIFO0,0)!=HAL_OK) return 0;
    for(i=0;i<CAN1_Handler.pRxMsg->DLC;i++)
    buf=CAN1_Handler.pRxMsg->Data;
    printf("Recv Data! ");
    return CAN1_Handler.pRxMsg->DLC;
}[/mw_shl_code]

初始化也正常,一调用发送,进入下面这段代码,就死循环这了;因为我是上了FreeRTOS的,工程架构也是使用原子哥提供的例程,滴答中断重写过的,uwTick++;没了,所以HAL_GetTick()得到的永远是0的!
__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox) 返回的一直是True; 退不出这个函数
[mw_shl_code=applescript,true]/* Check End of transmission flag */
while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
{
   /* Check for the Timeout */
   if(Timeout != HAL_MAX_DELAY)
   {
     if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
     {
       hcan->State = HAL_CAN_STATE_TIMEOUT;
        
       /* Process unlocked */
       __HAL_UNLOCK(hcan);
        
       return HAL_TIMEOUT;
     }
   }
}[/mw_shl_code]
硬件接法是 MCU CAN Rx,Tx 接到sn65hvd230芯片上,单板回环模式,双板正常收发模式都试过,不行!!!求解 !!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
db520136
1楼-- · 2019-07-21 18:59
Polychromatic 发表于 2018-11-17 19:50
HardFault_Handler 通常都是 定义的数组读写超了、定义的中断却没有 定义中断函数,定义了指针但是没 ...

找到原因了! 好坑啊!是我的启动文件有问题!
都是startup_stm32f103xb.s启动文件,我先前的里面没有定义USB_LP_CAN1_RX0_IRQHandler;所以一发生CAN 接收中断就挂了;后来我重新下载了个,也是同样V4.2.0版本的;启动文件定义了这个,就成功了;
还是谢谢哥帮忙!
Polychromatic
2楼-- · 2019-07-21 08:35
看这个问题跟我现在遇见的有点像,最新的Hal库 在底层都用了  uwtick, 如果不使能 systcik 就会一直死在HAL_Delay(XXXX);  没有具体调试也只能猜测是这个问题
db520136
3楼-- · 2019-07-21 11:01
Polychromatic 发表于 2018-11-17 16:02
看这个问题跟我现在遇见的有点像,最新的Hal库 在底层都用了  uwtick, 如果不使能 systcik 就会一直死在HAL ...

我把can的官方库,这么一改回环模式成功了!
[mw_shl_code=applescript,true]  /* Get timeout */
    tickstart = HAL_GetTick();   
    tickstart=0;
    /* Check End of transmission flag */
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
                                delay_ms(1);
                                tickstart++;
      //  if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
                                if((Timeout == 0) || (tickstart > Timeout))
                                {
          hcan->State = HAL_CAN_STATE_TIMEOUT;
         
          /* Process unlocked */
          __HAL_UNLOCK(hcan);
         
          return HAL_TIMEOUT;
        }
      }
    }
[/mw_shl_code]
但是把例程中的接收中断一开,一发就进入了HardFault_Handler()中断中!
哥,这个是什么原因知道吗?开中断就挂
Polychromatic
4楼-- · 2019-07-21 14:03
 精彩回答 2  元偷偷看……

一周热门 更多>