OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6084|回复: 4

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

[复制链接]

18

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2015-10-24
在线时间
38 小时
发表于 2018-11-17 15:01:03 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 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!\r\n");
    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!\r\n");
    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\r\n",CAN1_Handler.pRxMsg->StdId);
    printf("ide:%d\r\n",CAN1_Handler.pRxMsg->IDE);
    printf("rtr:%d\r\n",CAN1_Handler.pRxMsg->RTR);
    printf("len:%d\r\n",CAN1_Handler.pRxMsg->DLC);
    for(i=0;i<8;i++)
    printf("rxbuf[%d]:%d\r\n",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\r\n");
            return 1;
        }
        printf("CAN Send OK\r\n");
    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!\r\n");
    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芯片上,单板回环模式,双板正常收发模式都试过,不行!!!求解 !!!

最佳答案

查看完整内容[请看2#楼]

看这个问题跟我现在遇见的有点像,最新的Hal库 在底层都用了 uwtick, 如果不使能 systcik 就会一直死在HAL_Delay(XXXX); 没有具体调试也只能猜测是这个问题
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2017-2-14
在线时间
90 小时
发表于 2018-11-17 15:01:04 | 显示全部楼层
看这个问题跟我现在遇见的有点像,最新的Hal库 在底层都用了  uwtick, 如果不使能 systcik 就会一直死在HAL_Delay(XXXX);  没有具体调试也只能猜测是这个问题
回复

使用道具 举报

18

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2015-10-24
在线时间
38 小时
 楼主| 发表于 2018-11-17 16:55:24 | 显示全部楼层
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()中断中!
哥,这个是什么原因知道吗?开中断就挂
回复

使用道具 举报

9

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2017-2-14
在线时间
90 小时
发表于 2018-11-17 19:50:04 | 显示全部楼层
db520136 发表于 2018-11-17 16:55
我把can的官方库,这么一改回环模式成功了!
[mw_shl_code=applescript,true]  /* Get timeout */
     ...

HardFault_Handler 通常都是 定义的数组读写超了、定义的中断却没有 定义中断函数,定义了指针但是没有malloc(空指针0x00000000),硬件寄存器操作错误。没有实际调试程序,不好分辨,你可以在线调试看看程序 是不是没有定义回掉函数,或者定义的指针。
回复

使用道具 举报

18

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2015-10-24
在线时间
38 小时
 楼主| 发表于 2018-11-19 08:44:24 | 显示全部楼层
Polychromatic 发表于 2018-11-17 19:50
HardFault_Handler 通常都是 定义的数组读写超了、定义的中断却没有 定义中断函数,定义了指针但是没 ...

找到原因了! 好坑啊!是我的启动文件有问题!
都是startup_stm32f103xb.s启动文件,我先前的里面没有定义USB_LP_CAN1_RX0_IRQHandler;所以一发生CAN 接收中断就挂了;后来我重新下载了个,也是同样V4.2.0版本的;启动文件定义了这个,就成功了;
还是谢谢哥帮忙!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 23:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表