2017-03-05 27 views
0

私はSTM32F469ディスカバリーボードを使用していますが、CAN機能を使用しようとしています。STM32F4 - TXは毎回成功しますが、CAN RXは最初のコールでしか成功しません。

このボードでは、CAN1をタッチスクリーンと同時に使用することはできません。したがって、CAN2を使用する必要がありますが、CAN2を有効にするにはCAN1を有効にする必要があります。次のように

設定/コールバックのための私のコードは次のとおりです。

/* CAN1 Values */ 
#define CAN1_CLK_ENABLE()    __HAL_RCC_CAN1_CLK_ENABLE() 
#define CAN1_GPIO_CLK_ENABLE()   __HAL_RCC_GPIOB_CLK_ENABLE() 
#define CAN1_FORCE_RESET()    __HAL_RCC_CAN1_FORCE_RESET() 
#define CAN1_RELEASE_RESET()   __HAL_RCC_CAN1_RELEASE_RESET() 
#define CAN1_TX_PIN     GPIO_PIN_9 
#define CAN1_TX_GPIO_PORT    GPIOB 
#define CAN1_TX_AF      GPIO_AF9_CAN1 
#define CAN1_RX_PIN     GPIO_PIN_8 
#define CAN1_RX_GPIO_PORT    GPIOB 
#define CAN1_RX_AF      GPIO_AF9_CAN1 
#define CAN1_RX_IRQn     CAN1_RX0_IRQn 
#define CAN1_RX_IRQHandler    CAN1_RX0_IRQHandler 

/* CAN2 Values */ 
#define CAN2_CLK_ENABLE()    __HAL_RCC_CAN2_CLK_ENABLE() 
#define CAN2_GPIO_CLK_ENABLE()   __HAL_RCC_GPIOB_CLK_ENABLE() 
#define CAN2_FORCE_RESET()    __HAL_RCC_CAN2_FORCE_RESET() 
#define CAN2_RELEASE_RESET()   __HAL_RCC_CAN2_RELEASE_RESET() 
#define CAN2_TX_PIN     GPIO_PIN_13 
#define CAN2_TX_GPIO_PORT    GPIOB 
#define CAN2_TX_AF      GPIO_AF9_CAN2 
#define CAN2_RX_PIN     GPIO_PIN_5 
#define CAN2_RX_GPIO_PORT    GPIOB 
#define CAN2_RX_AF      GPIO_AF9_CAN2 
#define CAN2_RX_IRQn     CAN2_RX0_IRQn 
#define CAN2_RX_IRQHandler    CAN2_RX0_IRQHandler 

CAN_HandleTypeDef CanHandle1; 
CAN_HandleTypeDef CanHandle2; 

static uint8_t Message_Data[8]; 

static void CAN1_Config(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStruct; 
    CAN_FilterConfTypeDef CAN_FilterInitStructure; 

    static CanTxMsgTypeDef  TxMessage; 
    static CanRxMsgTypeDef  RxMessage; 

    /* CAN1 Periph clock enable */ 
    CAN1_CLK_ENABLE(); 
    CAN1_GPIO_CLK_ENABLE(); 

    /* CAN1 TX GPIO pin configuration */ 
    GPIO_InitStruct.Pin = CAN1_TX_PIN; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST; 
    GPIO_InitStruct.Pull = GPIO_PULLUP; 
    GPIO_InitStruct.Alternate = CAN1_TX_AF; 

    HAL_GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStruct); 

    /* CAN1 RX GPIO pin configuration */ 
    GPIO_InitStruct.Pin = CAN1_RX_PIN; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST; 
    GPIO_InitStruct.Pull = GPIO_PULLUP; 
    GPIO_InitStruct.Alternate = CAN1_RX_AF; 

    HAL_GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStruct); 

    /* NVIC configuration for CAN1 Reception complete interrupt */ 
    HAL_NVIC_SetPriority(CAN1_RX_IRQn, 1, 0); 
    HAL_NVIC_EnableIRQ(CAN1_RX_IRQn); 

    CanHandle1.Instance = CAN1; 
    CanHandle1.pTxMsg = &TxMessage; 
    CanHandle1.pRxMsg = &RxMessage; 

    /* CAN peripheral init */ 
    CanHandle1.Init.TTCM = DISABLE; 
    CanHandle1.Init.ABOM = DISABLE; 
    CanHandle1.Init.AWUM = DISABLE; 
    CanHandle1.Init.NART = DISABLE; 
    CanHandle1.Init.RFLM = DISABLE; 
    CanHandle1.Init.TXFP = DISABLE; 
    CanHandle1.Init.Mode = CAN_MODE_LOOPBACK; 
    CanHandle1.Init.SJW = CAN_SJW_1TQ; 
    CanHandle1.Init.BS1 = CAN_BS1_6TQ; 
    CanHandle1.Init.BS2 = CAN_BS2_8TQ; 
    CanHandle1.Init.Prescaler = 2; 

    HAL_CAN_Init(&CanHandle1); 

    /* CAN filter init */ 
    CAN_FilterInitStructure.FilterNumber = 0; 
    CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK; 
    CAN_FilterInitStructure.FilterScale=CAN_FILTERSCALE_32BIT; 
    CAN_FilterInitStructure.FilterIdHigh = 0x0000; 
    CAN_FilterInitStructure.FilterIdLow = 0x0000; 
    CAN_FilterInitStructure.FilterMaskIdHigh = 0x0000; 
    CAN_FilterInitStructure.FilterMaskIdLow = 0x0000; 
    CAN_FilterInitStructure.FilterFIFOAssignment = 0; 
    CAN_FilterInitStructure.FilterActivation = ENABLE; 
    CAN_FilterInitStructure.BankNumber = 0; 

    HAL_CAN_ConfigFilter(&CanHandle1, &CAN_FilterInitStructure); 

    /* Configure transmission */ 
    CanHandle1.pTxMsg->StdId = 0x7DF; 
    CanHandle1.pTxMsg->ExtId = 0x7DF; 
    CanHandle1.pTxMsg->RTR = CAN_RTR_DATA; 
    CanHandle1.pTxMsg->IDE = CAN_ID_STD; 
    CanHandle1.pTxMsg->DLC = 8; 
}  

static void CAN2_Config(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStruct; 
    CAN_FilterConfTypeDef CAN_FilterInitStructure; 

    static CanTxMsgTypeDef  TxMessage; 
    static CanRxMsgTypeDef  RxMessage; 

    /* CAN2 Periph clock enable */ 
    CAN2_CLK_ENABLE(); 
    CAN2_GPIO_CLK_ENABLE(); 

    /* CAN2 TX GPIO pin configuration */ 
    GPIO_InitStruct.Pin = CAN2_TX_PIN; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST; 
    GPIO_InitStruct.Pull = GPIO_PULLUP; 
    GPIO_InitStruct.Alternate = CAN2_TX_AF; 

    HAL_GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStruct); 

    /* CAN2 RX GPIO pin configuration */ 
    GPIO_InitStruct.Pin = CAN2_RX_PIN; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST; 
    GPIO_InitStruct.Pull = GPIO_PULLUP; 
    GPIO_InitStruct.Alternate = CAN2_RX_AF; 

    HAL_GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStruct); 

    /* NVIC configuration for CAN2 Reception complete interrupt */ 
    HAL_NVIC_SetPriority(CAN2_RX_IRQn, 1, 0); 
    HAL_NVIC_EnableIRQ(CAN2_RX_IRQn); 

    CanHandle2.Instance = CAN2; 
    CanHandle2.pTxMsg = &TxMessage; 
    CanHandle2.pRxMsg = &RxMessage; 

    /* CAN peripheral init */ 
    CanHandle2.Init.TTCM = DISABLE; 
    CanHandle2.Init.ABOM = DISABLE; 
    CanHandle2.Init.AWUM = DISABLE; 
    CanHandle2.Init.NART = DISABLE; 
    CanHandle2.Init.RFLM = DISABLE; 
    CanHandle2.Init.TXFP = DISABLE; 
    CanHandle2.Init.Mode = CAN_MODE_LOOPBACK; 
    CanHandle2.Init.SJW = CAN_SJW_1TQ; 
    CanHandle2.Init.BS1 = CAN_BS1_6TQ; 
    CanHandle2.Init.BS2 = CAN_BS2_8TQ; 
    CanHandle2.Init.Prescaler = 2; 

    HAL_CAN_Init(&CanHandle2); 

    /* CAN filter init */ 
    CAN_FilterInitStructure.FilterNumber = 0; //14 enables CAN1; 
    CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK; 
    CAN_FilterInitStructure.FilterScale=CAN_FILTERSCALE_32BIT; 
    CAN_FilterInitStructure.FilterIdHigh = 0x0000; 
    CAN_FilterInitStructure.FilterIdLow = 0x0000; 
    CAN_FilterInitStructure.FilterMaskIdHigh = 0x0000; 
    CAN_FilterInitStructure.FilterMaskIdLow = 0x0000; 
    CAN_FilterInitStructure.FilterFIFOAssignment = 0; 
    CAN_FilterInitStructure.FilterActivation = ENABLE; 
    CAN_FilterInitStructure.BankNumber = 0; //14 enables CAN1 

    HAL_CAN_ConfigFilter(&CanHandle2, &CAN_FilterInitStructure); 

    /* Configure transmission */ 
    CanHandle2.pTxMsg->StdId = 0x7DF; 
    CanHandle2.pTxMsg->ExtId = 0x7DF; 
    CanHandle2.pTxMsg->RTR = CAN_RTR_DATA; 
    CanHandle2.pTxMsg->IDE = CAN_ID_STD; 
    CanHandle2.pTxMsg->DLC = 8; 
} 

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle) 
{ 
    EwBspYellowLedOn(); 

    Message_Data[0] = CanHandle->pRxMsg->Data[0]; 
    Message_Data[1] = CanHandle->pRxMsg->Data[1]; 
    Message_Data[2] = CanHandle->pRxMsg->Data[2]; 
    Message_Data[3] = CanHandle->pRxMsg->Data[3]; 
    Message_Data[4] = CanHandle->pRxMsg->Data[4]; 
    Message_Data[5] = CanHandle->pRxMsg->Data[5]; 
    Message_Data[6] = CanHandle->pRxMsg->Data[6]; 
    Message_Data[7] = CanHandle->pRxMsg->Data[7]; 

    if (HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK) 
    { 
    EwBspRedLedOn(); 
    } 
} 

CAN_Transmit_Message(void) 
{ 
    CanHandle2.pTxMsg->StdId = 0x7DF; 
    CanHandle2.pTxMsg->ExtId = 0x7DF; 
    CanHandle2.pTxMsg->Data[0] = 0x02; 
    CanHandle2.pTxMsg->Data[1] = 0x01; 
    CanHandle2.pTxMsg->Data[2] = 0x0D; 
    CanHandle2.pTxMsg->Data[3] = 0x55; 
    CanHandle2.pTxMsg->Data[4] = 0x55; 
    CanHandle2.pTxMsg->Data[5] = 0x55; 
    CanHandle2.pTxMsg->Data[6] = 0x55; 
    CanHandle2.pTxMsg->Data[7] = 0x55; 

    if (HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK) 
    { 
    EwBspOrangeLedOn(); 
    } 

    HAL_Delay(10); 
} 

私は、CAN1、CAN2と割り込みを設定するには、私の主な機能には、以下を実行します。

/* Configure interrupt for CAN transmission */ 
CAN1_Config(); 
CAN2_Config(); 
HAL_CAN_Receive_IT(&CanHandle2, CAN_FIFO0); 

そして私CAN_Transmit_Message()を実行します。

メッセージが正常に送信された(オレンジ色のLEDが点灯しない)ことを確認すると、受信割り込みハンドラが実行され(黄色LEDが点灯)、メッセージが正常に受信されます(赤色LEDは点灯しません) )。

しかし、メッセージの2回目の送信(別のコールCAN_Transmit_Message())では、送信は再び成功しますが、受信は失敗します(赤色LEDが点灯します)。

私はこのコードをCAN_Networkingサンプルコードの構造に従って作成しましたが、最初のメッセージが正常に受信された後に、2番目のメッセージのHAL_CAN_Receive_IT関数で失敗した理由がわかりません。

注:

  1. HAL_CAN_Transmit_IT/HAL_CAN_Receive_IT
  2. HAL_CAN_Transmit/HAL_CAN_Receive

それは1と言う:stm32f4xx_HAL_CANライブラリファイルを読んだ後、私は、送信/受信の2種類があります気づきました。私はそれを取るこのことは、この送信/受信がまだ実行されている間に別の割り込みがトリガされることを意味しますか?

私のケースでは、送信を送信した後に応答データを受信したことを確認したいので、機能2を使用する必要がありますか?私。適切なタイムアウトを指定してHAL_CAN_Transmitを呼び出すと、HAL_CAN_Receiveを呼び出した後、再び適切なタイムアウトが発生します。

答えて

0

応答を得るたびにHAL_CAN_Receive_ITを呼び出しますか?

ワンショットです。受信を継続するには、割り込みハンドラで再度呼び出します。

関連する問題