本帖最后由 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芯片上,单板回环模式,双板正常收发模式都试过,不行!!!求解 !!!
找到原因了! 好坑啊!是我的启动文件有问题!
都是startup_stm32f103xb.s启动文件,我先前的里面没有定义USB_LP_CAN1_RX0_IRQHandler;所以一发生CAN 接收中断就挂了;后来我重新下载了个,也是同样V4.2.0版本的;启动文件定义了这个,就成功了;
还是谢谢哥帮忙!
我把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()中断中!
哥,这个是什么原因知道吗?开中断就挂
一周热门 更多>