CAN-STM32F429 测试程序

bsp_can.c

#include "bsp_can.h"

static void CAN_GPIO_Config(void)
{
    /* GPIO Init Struct */
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Enable CAN GPIO clock */
    RCC_AHB1PeriphClockCmd(CAN_TX_GPIO_CLK | CAN_RX_GPIO_CLK, ENABLE);

    /* Connect CAN pins to AF9 */
    GPIO_PinAFConfig(CAN_TX_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
    GPIO_PinAFConfig(CAN_RX_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT);

    /* Configure CAN TX pins */
    GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(CAN_TX_GPIO_PORT, &GPIO_InitStructure);

    /* Configure CAN RX  pins */
    GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    /* Init GPIO */
    GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);
}

static void CAN_NVIC_Config(void)
{
    /* CAN NVIC Struct */
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /*NVIC Set*/
    NVIC_InitStructure.NVIC_IRQChannel = CAN_RX_IRQ;                   /* 中断通道 */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;          /* 抢占优先级0 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	               /* 子优先级为0 */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    /* 中断使能 */
    /* Init NVIC */
    NVIC_Init(&NVIC_InitStructure);
}

static void CAN_Mode_Config(void)
{
    /* CAN Init Struct */
    CAN_InitTypeDef        CAN_InitStructure;
    /* Enable CAN clock */
    RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

    CAN_InitStructure.CAN_TTCM = DISABLE;            /* MCR-TTCM  关闭时间触发通信模式使能 */
    CAN_InitStructure.CAN_ABOM = ENABLE;             /* MCR-ABOM  使能自动离线管理 */
    CAN_InitStructure.CAN_AWUM = ENABLE;             /* MCR-AWUM  使能自动唤醒模式 */
    CAN_InitStructure.CAN_NART = DISABLE;            /* MCR-NART  禁止报文自动重   */
    CAN_InitStructure.CAN_RFLM = DISABLE;            /* MCR-RFLM  接收FIFO 锁定模式 */
    CAN_InitStructure.CAN_TXFP = DISABLE;            /* MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符 */
    CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;  /* 回环工作模式 */
    CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;         /* BTR-SJW 重新同步跳跃宽度 2个时间单元 */

    /* ss=1 bs1=5 bs2=3 位时间宽度为(1+5+3) 波特率即为时钟周期tq*(1+5+3)  */
    CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;        /* BTR-TS1 时间段1 占用了5个时间单元 */
    CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;        /* BTR-TS1 时间段2 占用了3个时间单元 */

    /* CAN Baudrate = 1 MBps (1MBps已为stm32的CAN最高速率) (CAN 时钟频率为 APB1 = 45 MHz) */
    CAN_InitStructure.CAN_Prescaler = 5;            /* BTR-BRP 波特率分频器  定义了时间单元的时间长度 45/(1+5+3)/5=1 Mbps */
    /* CAN Init */
    CAN_Init(CANx, &CAN_InitStructure);
}

static void CAN_Filter_Config(void)
{
    uint32_t filter_id = 0;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;

    /*CAN筛选器初始化*/
    CAN_FilterInitStructure.CAN_FilterNumber = 13;                                             /* 筛选器组 F4 0-13 */
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;	                           /* 工作在掩码模式 */
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;                           /* 筛选器位宽为单个32位。 */
    /* 使能筛选器,按照标志的内容进行比对筛选,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO。 */
    filter_id = ((uint32_t)TEST_ID << 3) | CAN_ID_EXT | CAN_RTR_DATA;

    CAN_FilterInitStructure.CAN_FilterIdHigh = (filter_id & 0xFFFF0000) >> 16;                 /* 要筛选的ID高位 */
    CAN_FilterInitStructure.CAN_FilterIdLow = filter_id & 0xFFFF;                              /* 要筛选的ID低位 */
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = ((u32)0x1230 << 3) >> 16;                   /* 筛选出的 ID 为0x123x x表示不用关心 */
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = ((u32)0x1230 << 3) & 0xFFFF;                 /* 筛选出的 ID 为0x123x */
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO1 ;                      /* 筛选器被关联到FIFO1 */
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;                                     /* 使能筛选器 */

    CAN_FilterInit(&CAN_FilterInitStructure);
    /*CAN通信中断使能*/
    CAN_ITConfig(CANx, CAN_IT_FMP1, ENABLE);
}

void CAN_Config(void)
{
    CAN_GPIO_Config();    /* GPIO Init */
    CAN_NVIC_Config();    /* NVIC Init */
    CAN_Mode_Config();    /* CAN Init */
    CAN_Filter_Config();  /* Filter Init */
}

void CAN_SetMsg(CanTxMsg *TxMessage)
{
    uint8_t ubCounter = 0;

    TxMessage->StdId = 0x00;
    TxMessage->ExtId = 0x1231;                   /* 使用的扩展ID */
    TxMessage->IDE = CAN_ID_EXT;                 /* 扩展模式 */
    TxMessage->RTR = CAN_RTR_DATA;               /* 发送的是数据 */
    TxMessage->DLC = 8;                          /* 数据长度为8字节 */

    /*设置要发送的数据0-7*/
    for (ubCounter = 0; ubCounter < 8; ubCounter++)
    {
        TxMessage->Data[ubCounter] = ubCounter;
    }
}

extern __IO uint32_t flag ;      /* 用于标志是否接收到数据,在中断函数中赋值 */
extern CanRxMsg RxMessage;       /* 接收缓冲区 */

void CAN_RX_IRQHandler(void)
{
    /* 从邮箱中读出报文 */
    CAN_Receive(CANx, CAN_FIFO1, &RxMessage);

    if((RxMessage.IDE == CAN_ID_EXT) && (RxMessage.DLC == 8) )
    {
        flag = 1;
    }
    else
    {
        flag = 0;
    }
}
/************************** end of file ************************************/

bsp_can.h

#ifndef __BSP_CAN_H
#define __BSP_CAN_H

#include "stm32f4xx.h"
#include <stdio.h>

#define CANx                        CAN1
#define CAN_CLK                     RCC_APB1Periph_CAN1
#define CAN_RX_IRQ                  CAN1_RX1_IRQn
#define CAN_RX_IRQHandler           CAN1_RX1_IRQHandler

#define CAN_RX_PIN                  GPIO_Pin_8
#define CAN_TX_PIN                  GPIO_Pin_9
#define CAN_TX_GPIO_PORT            GPIOB
#define CAN_RX_GPIO_PORT            GPIOB
#define CAN_TX_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define CAN_RX_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define CAN_AF_PORT                 GPIO_AF_CAN1
#define CAN_RX_SOURCE               GPIO_PinSource8
#define CAN_TX_SOURCE               GPIO_PinSource9

#define TEST_ID 0x1234

void CAN_Config(void);
void CAN_SetMsg(CanTxMsg *TxMessage);

#endif /* __BSP_CAN_H */

/************************** end of file ************************************/

main.c

#include "stm32f4xx.h"
#include "bsp_can.h"

volatile uint32_t flag = 0;          /* 用于标志是否接收到数据,在中断函数中赋值 */
CanTxMsg TxMessage;              /* 发送缓冲区 */
CanRxMsg RxMessage;              /* 接收缓冲区 */

int main(int argc, char *argv[])
{
    Debug_USART_Config();
    CAN_Config();
    printf("can loopback test project\r\n");

    CAN_SetMsg(&TxMessage);
    CAN_Transmit(CANx, &TxMessage);
    printf("sendid %x \r\n", TxMessage.ExtId);
    printf("send data:\r\n");
    for (char i = 0; i < 8; i++)
    {
        printf("%x ", TxMessage.Data[i]);
    }
    printf("\r\n");
    if(flag == 1)
    {
        printf("received id = %x\r\n", RxMessage.ExtId);
        printf("received data :\r\n");
        for (char i = 0; i < 8; i++)
        {
            printf("%x ", RxMessage.Data[i]);
        }
        printf("\r\n");
    }
}

/********************************************* end of file **********************/

 测试平台:野火F429开发

输出结果

can loopback test project
sendid 1231
send data:
0 1 2 3 4 5 6 7
received id = 1231
received data :
0 1 2 3 4 5 6 7
 

发布了124 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/tyustli/article/details/103645664