STM32F4发现和CAN编程

时间:2015-06-03 17:18:41

标签: c arm stm32 stm32f4discovery can-bus

我正在尝试开始学习编程,我正在尝试使用此代码:https://github.com/espruino/Espruino/blob/master/targetlibs/stm32f4/lib/stm32f4xx_can.c 我正在使用Atollic TruStudio Lite。

我用Discovery做了基本的LED闪烁代码,但除此之外。我不知道如何做到这一点。

我不知道如何通过STM32模拟CAN消息(以及其他内容)。

我是一个初学者,所以请不要扯掉我的喉咙。

由于

1 个答案:

答案 0 :(得分:1)

这是您可以尝试的CAN环回的示例。它是一个CAN环回测试。您可以从STM网站下载stm32f4示例。这是针对STM32439评估板,但它应该用于发现。 (两者都是STM32F4芯片)。

#define USE_CAN1
/* Uncomment the line below if you will use the CAN 2 peripheral */
/* #define USE_CAN2 */

#ifdef  USE_CAN1
  #define CANx              CAN1
  #define CAN_CLK           RCC_APB1Periph_CAN1      

#else /* USE_CAN2 */
  #define CANx              CAN2
  #define CAN_CLK           (RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2)   
#endif  /* USE_CAN1 */

typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

__IO uint32_t ret = 0; /* for return of the interrupt handling */
volatile TestStatus TestRx;

TestStatus CAN_Polling(void);

int main(void) {
    /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s)
       before to branch to application main. 
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */   

    /* CANx Periph clock enable */
    RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

    /* Initialize LEDs mounted on EVAL board */
    STM_EVAL_LEDInit(LED1);
    STM_EVAL_LEDInit(LED2);

    /* CAN transmit at 125Kb/s and receive by polling in loopback mode */
    TestRx = CAN_Polling();

    if (TestRx !=  FAILED) { /* OK */
        /* Turn on LED1 */
        STM_EVAL_LEDOn(LED1);
    } else { /* KO */
        /* Turn on LED2 */
        STM_EVAL_LEDOn(LED2);
    }

    /* Infinite loop */
    while (1) { }
}

/**
 * @brief  Configures the CAN, transmit and receive by polling
 * @param  None
 * @retval PASSED if the reception is well done, FAILED in other case
 */
TestStatus CAN_Polling(void) {
    CAN_InitTypeDef        CAN_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    CanTxMsg TxMessage;
    CanRxMsg RxMessage;
    uint32_t uwCounter = 0;
    uint8_t TransmitMailbox = 0;

    /* CAN register init */
    CAN_DeInit(CANx);

    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

    /* CAN Baudrate = 175kbps (CAN clocked at 42 MHz) */
    CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = 16;
    CAN_Init(CANx, &CAN_InitStructure);

    /* CAN filter init */
#ifdef  USE_CAN1
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
#else /* USE_CAN2 */
    CAN_FilterInitStructure.CAN_FilterNumber = 14;
#endif  /* USE_CAN1 */
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;  
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;

    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    /* transmit */
    TxMessage.StdId = 0x11;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 2;
    TxMessage.Data[0] = 0xCA;
    TxMessage.Data[1] = 0xFE;

    TransmitMailbox = CAN_Transmit(CANx, &TxMessage);
    uwCounter = 0;
    while((CAN_TransmitStatus(CANx, TransmitMailbox)  !=  CANTXOK) && (uwCounter  !=  0xFFFF)) {
        uwCounter++;
    }

    uwCounter = 0;
    while((CAN_MessagePending(CANx, CAN_FIFO0) < 1) && (uwCounter  !=  0xFFFF)) {
        uwCounter++;
    }

    /* receive */
    RxMessage.StdId = 0x00;
    RxMessage.IDE = CAN_ID_STD;
    RxMessage.DLC = 0;
    RxMessage.Data[0] = 0x00;
    RxMessage.Data[1] = 0x00;
    CAN_Receive(CANx, CAN_FIFO0, &RxMessage);

    if (RxMessage.StdId != 0x11) {
        return FAILED;  
    }

    if (RxMessage.IDE != CAN_ID_STD) {
        return FAILED;
    }

    if (RxMessage.DLC != 2) {
        return FAILED;  
    }

    if ((RxMessage.Data[0]<<8|RxMessage.Data[1]) != 0xCAFE) {
        return FAILED;
    }

    return PASSED; /* Test Passed */
}