STM32F4Discovery:接收CAN消息

时间:2012-07-30 17:51:24

标签: arm stm can-bus

我对如何在STM32F4Discovery上接收CAN消息感到迷茫。我在Silent_Loopback模式下使用它,这意味着所有发送的消息都应该到达CAN控制器本身。我发送消息时会收到Transmit_OK状态,但FIFO邮箱中没有任何内容。我已跳过CAN过滤器配置,以便接收所有消息,而不是过滤掉任何消息。我做错了什么?

/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

void Delay(__IO uint32_t nCount) {
    while(nCount--) {
    }
}

void RCC_Configuration(void) {
    /* ENABLE CLOCKS         */
    /* GPIOB clock enable    */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    /* USART3 clock enable   */
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    /* CAN1 clock enable     */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /* CAN2 clock enable     */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
}

void GPIO_Configuration(void) {
    GPIO_InitTypeDef GPIO_InitStructureUSART;
    GPIO_InitTypeDef GPIO_InitStructureCAN_RX;
    GPIO_InitTypeDef GPIO_InitStructureCAN_TX;

    /* GPIO USART Configuration */
    GPIO_InitStructureUSART.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructureUSART.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructureUSART.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructureUSART.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructureUSART.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructureUSART);

    /* Connect USART to AF */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //USART_TX = PB10
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3); //USART_RX = PB11

    /* GPIO CAN_RX Configuration */
    GPIO_InitStructureCAN_RX.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructureCAN_RX.GPIO_Mode = GPIO_Mode_AF;
    //GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
    //GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
    //GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructureCAN_RX);

    /* GPIO CAN_TX Configuration */
    GPIO_InitStructureCAN_TX.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructureCAN_TX.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructureCAN_TX);

    /* Connect CAN_RX & CAN_TX to AF9 */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); //CAN_RX = PB12
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); //CAN_TX = PB13
}

void USART_Configuration(void) {
    USART_InitTypeDef USART_InitStructure;

    /* USART3 configuration */
    /* 256000 baud, window 8 data bits, one stop bit, no parity, no hardware flow control, rx/tx enabled */
    USART_InitStructure.USART_BaudRate = 256000;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART3, &USART_InitStructure);

    USART_Cmd(USART3, ENABLE);
}

void CAN_Configuration(void) {
    CAN_InitTypeDef CAN_InitStructure;

    /* CAN2 reset */
    CAN_DeInit(CAN2);

    /* CAN2 configuration */
    CAN_InitStructure.CAN_TTCM = DISABLE; // Time-triggered communication mode = DISABLED
    CAN_InitStructure.CAN_ABOM = DISABLE; // Automatic bus-off management mode = DISABLED
    CAN_InitStructure.CAN_AWUM = DISABLE; // Automatic wake-up mode = DISABLED
    CAN_InitStructure.CAN_NART = DISABLE; // Non-automatic retransmission mode = DISABLED
    CAN_InitStructure.CAN_RFLM = DISABLE; // Receive FIFO locked mode = DISABLED
    CAN_InitStructure.CAN_TXFP = DISABLE; // Transmit FIFO priority = DISABLED
    CAN_InitStructure.CAN_Mode = CAN_Mode_Silent_LoopBack; // Normal CAN mode
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // Synchronization jump width = 1
    CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq; //14
    CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;  //6
    CAN_InitStructure.CAN_Prescaler = 4;      // Baudrate 500 kbps
    //CAN_InitStructure.CAN_Prescaler = 16;   // Baudrate 125 kbps
    if (CAN_Init(CAN2, &CAN_InitStructure)) { // Initialize CAN
        STM_EVAL_LEDInit(LED6); // Initialize and
        STM_EVAL_LEDOn(LED6);   // Turn ON blue LED if CAN initialization is successful
    }
}

void CAN_FilterConfiguration(void) {
    CAN_FilterInitTypeDef CAN_FilterInitStructure;

    /* CAN2 filter configuration */
    CAN_FilterInitStructure.CAN_FilterNumber = 0; // Filter number = 0 (0<=x<=13)
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0300 << 5; //0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x03FF << 5;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
}

void CAN_TxMessage(void) {
    CanTxMsg TxMessage;

    /* CAN message to send */
    TxMessage.StdId = 0x321;
    TxMessage.ExtId = 0x01;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 8;
    TxMessage.Data[0] = 0x04;
    TxMessage.Data[1] = 0x01;
    TxMessage.Data[2] = 0x00;
    TxMessage.Data[3] = 0x00;
    TxMessage.Data[4] = 0x00;
    TxMessage.Data[5] = 0x00;
    TxMessage.Data[6] = 0x00;
    TxMessage.Data[7] = 0x00;

    //while (1) {
        CAN_TransmitStatus(CAN2, 0);
        CAN_Transmit(CAN2, &TxMessage);
        if(CAN_TransmitStatus(CAN2, 0)){
            STM_EVAL_LEDInit(LED4); // Initialize and
            STM_EVAL_LEDOn(LED4);   // turn ON green LED if transmit was successful
        }
    //}
}

void CAN_OBDII_RequestCurrentData(int PIDNumber) {
    CanTxMsg TxMessage;

    TxMessage.StdId = 0x7DF; // PID request identifier
    TxMessage.ExtId = 0x7DF;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 8;
    TxMessage.Data[0] = 0x02; // Number of additional bytes = 2
    TxMessage.Data[1] = 0x01; // Show current data = 1
    TxMessage.Data[2] = PIDNumber; // PID code number
    TxMessage.Data[3] = 0x00;
    TxMessage.Data[4] = 0x00;
    TxMessage.Data[5] = 0x00;
    TxMessage.Data[6] = 0x00;
    TxMessage.Data[7] = 0x00;

    CAN_Transmit(CAN2, &TxMessage); // Transmit OBDII PID request via CAN2/mailbox0
}

void CAN_RxMessage(void) {
    CanRxMsg RxMessage;
    int d0=0;
    while(1) {
        CAN_Receive(CAN2,CAN_FIFO0,&RxMessage);

        d0 = RxMessage.Data[0];
        d0 = RxMessage.Data[1];
        d0 = RxMessage.Data[2];
        d0 = RxMessage.Data[3];
        d0 = RxMessage.Data[4];
        d0 = RxMessage.Data[5];
        d0 = RxMessage.Data[6];
        d0 = RxMessage.Data[7];
    }
}

int main(void)
{
    /* Initialize Clocks */
    RCC_Configuration();

    /* Initialize GPIO */
    GPIO_Configuration();

    /* Initialize USART */
    USART_Configuration();

    /* Initialize CAN */
    CAN_Configuration();

    /* Initialize CAN Reception Filter */
    //CAN_FilterConfiguration();

    /* Transfer CAN message */
    CAN_TxMessage();

    /* Receive CAN message */
    CAN_RxMessage();

3 个答案:

答案 0 :(得分:0)

您必须配置过滤器以接受所有邮件(如果您没有任何过滤器,则不接受任何邮件)。但在您的示例中,您使用的是CAN2,因此FilterNumber必须为14或更高。

#define CAN_FIFO_ID                0
#define CAN_FIFO                   CAN_FIFO0
#define CAN_FIFO_IN                CAN_IT_FMP0

/**
* @brief Default filter - accept all to CAN_FIFO
*/
void CAN_SetFilter()
{
    /* Default filter - accept all to CAN_FIFO*/
    CAN_FilterInitTypeDef CAN_FilterInitStructure;
    CAN_FilterInitStructure.CAN_FilterNumber = 14; // 0..13 for CAN1, 14..27 for CAN2
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO_ID;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
}

答案 1 :(得分:0)

分配给CAN1和CAN2的滤波器数量在CAN_FMR寄存器中定义,默认情况下,该寄存器设置为14,这是CAN2滤波器的起点。

这可以设置为28,这意味着没有过滤器到CAN2和所有28到CAN1或如果设置为0,所有28个过滤器都分配给CAN2。

答案 2 :(得分:0)

通常,在遮罩模式下(如果您具有有效的过滤器编号),任何遮罩= 0将使所有内容通过。