打印
[STM32F1]

STM32_CAN 回环TEST的案例

[复制链接]
2119|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Diyer2015|  楼主 | 2018-9-3 15:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32_CAN 回环TEST的案例
沙发
Diyer2015|  楼主 | 2018-9-3 15:22 | 只看该作者
/**
  ******************************************************************************
  * @file    main.c
  * @author  fire
  * @version V1.0
  * @date    2013-xx-xx
  * @brief   can回环测试
  */

#include "stm32f10x.h"
#include "./usart/bsp_debug_usart.h"
#include "./led/bsp_led.h"   
#include "./key/bsp_key.h"  
#include "./can/bsp_can.h"


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


/// 不精确的延时
static void can_delay(__IO u32 nCount)
{
        for(; nCount != 0; nCount--);
}

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{       
        LED_GPIO_Config();
       
  /*初始化USART1*/
  Debug_USART_Config();
       
        /*初始化按键*/
        Key_GPIO_Config();

        /*初始化can,在中断接收CAN数据包*/
        CAN_Config();
       

  printf("\r\n 工控板 CAN通讯回环实验例程\r\n");
        printf("\r\n 实验步骤:\r\n");
        printf("\r\n 1.使用回环模式,不需要连接外部芯片\r\n");
        printf("\r\n 2.按下开发板的KEY1键,会使用CAN向外发送0-7的数据包,包的扩展ID为0x1314 (由于回环模式,是自己发送给自己)\r\n");
        printf("\r\n 3.若开发板的CAN接收到扩展ID为0x1314的数据包,会把数据以打印到串口。 \r\n");
        printf("\r\n 4.本例中的can波特率为1MBps,为stm32的can最高速率。 \r\n");

  while(1)
        {
                /*按一次按键发送一次数据*/
                if(        Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON)
                {

                        CAN_SetMsg(&TxMessage);
                       
                        CAN_Transmit(CANx, &TxMessage);
                       
                        can_delay(10000);//等待发送完毕,可使用CAN_TransmitStatus查看状态
                       
                        LED1_ON;
                       
                        printf("\r\n已使用CAN发送数据包!\r\n");                        
                        printf("\r\n发送的报文内容为:\r\n");
                        printf("\r\n 扩展ID号ExtId:0x%x \r\n",TxMessage.ExtId);
                        CAN_DEBUG_ARRAY(TxMessage.Data,8);


                }
                if(flag==1)
                {               
                        LED2_ON;
                        printf("\r\nCAN接收到数据:\r\n");       

                        CAN_DEBUG_ARRAY(RxMessage.Data,8);
                       
                        flag=0;
                }
       
       
        }
}

使用特权

评论回复
板凳
Diyer2015|  楼主 | 2018-9-3 15:23 | 只看该作者
/*
* 函数名:CAN_GPIO_Config
* 描述  :CAN的GPIO 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

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

    //重映射引脚
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);

    /* Configure CAN TX pins */
    GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                         // 复用推挽输出
    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_IPU;                     // 上拉输入
    GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);


}

使用特权

评论回复
地板
Diyer2015|  楼主 | 2018-9-3 15:23 | 只看该作者
/*
* 函数名:CAN_NVIC_Config
* 描述  :CAN的NVIC 配置,第1优先级组,0,0优先级
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /*中断设置*/
    NVIC_InitStructure.NVIC_IRQChannel = CAN_RX_IRQ;           //CAN1 RX0中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                   //抢占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                           //子优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
5
Diyer2015|  楼主 | 2018-9-3 15:24 | 只看该作者
/*
* 函数名:CAN_Mode_Config
* 描述  :CAN的模式 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_Mode_Config(void)
{
    CAN_InitTypeDef        CAN_InitStructure;
    /************************CAN通信参数设置**********************************/
    /* Enable CAN clock */
    RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

    /*CAN寄存器初始化*/
    CAN_DeInit(CANx);
    CAN_StructInit(&CAN_InitStructure);

    /*CAN单元初始化*/
    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  禁止报文自动重传          DISABLE-自动重传
    CAN_InitStructure.CAN_RFLM=DISABLE;                           //MCR-RFLM  接收FIFO 锁定模式  DISABLE-溢出时新报文会覆盖原有报文
    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+3+5)  */
    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 = 36 MHz) */
    CAN_InitStructure.CAN_Prescaler =4;                   ////BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+5+3)/4=1 Mbps
    CAN_Init(CANx, &CAN_InitStructure);
}

使用特权

评论回复
6
Diyer2015|  楼主 | 2018-9-3 15:24 | 只看该作者
/*
* 函数名:CAN_Filter_Config
* 描述  :CAN的过滤器 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*/
static void CAN_Filter_Config(void)
{
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;

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

    CAN_FilterInitStructure.CAN_FilterIdHigh= ((((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000)>>16;                //要筛选的ID高位
    CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要筛选的ID低位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFFFF;                        //筛选器高16位每位必须匹配
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFFF;                        //筛选器低16位每位必须匹配
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;                                //筛选器被关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                        //使能筛选器
    CAN_FilterInit(&CAN_FilterInitStructure);
    /*CAN通信中断使能*/
    CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

使用特权

评论回复
7
Diyer2015|  楼主 | 2018-9-3 15:25 | 只看该作者
/**
  * @brief  初始化 Rx Message数据结构体
  * @param  RxMessage: 指向要初始化的数据结构体
  * @retval None
  */
void Init_RxMes(CanRxMsg *RxMessage)
{
    uint8_t ubCounter = 0;

    /*把接收结构体清零*/
    RxMessage->StdId = 0x00;
    RxMessage->ExtId = 0x00;
    RxMessage->IDE = CAN_ID_STD;
    RxMessage->DLC = 0;
    RxMessage->FMI = 0;
    for (ubCounter = 0; ubCounter < 8; ubCounter++)
    {
        RxMessage->Data[ubCounter] = 0x00;
    }
}

使用特权

评论回复
8
Diyer2015|  楼主 | 2018-9-3 15:26 | 只看该作者
/*
* 函数名:CAN_SetMsg
* 描述  :CAN通信报文内容设置,设置一个数据内容为0-7的数据包
* 输入  :发送报文结构体
* 输出  : 无
* 调用  :外部调用
*/
void CAN_SetMsg(CanTxMsg *TxMessage)
{
    uint8_t ubCounter = 0;

    //TxMessage.StdId=0x00;
    TxMessage->ExtId=0x1314;                                         //使用的扩展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;
    }
}

使用特权

评论回复
9
stm32jy| | 2018-9-3 20:19 | 只看该作者
火哥的例子哦,我以前也是参考火哥的,挺详细的

使用特权

评论回复
10
junpeng324| | 2018-9-3 21:13 | 只看该作者
can的正常模式可以用吗?

使用特权

评论回复
11
junpeng324| | 2018-9-3 21:14 | 只看该作者
can的正常模式可以用吗?

使用特权

评论回复
12
junpeng324| | 2018-9-3 21:14 | 只看该作者
设备通讯该如何设置

使用特权

评论回复
13
八层楼| | 2018-9-4 08:59 | 只看该作者
我的回环也可以 但是正常模式就不可以 不知道为什么

使用特权

评论回复
14
heimaojingzhang| | 2018-9-4 09:29 | 只看该作者
非常感谢楼主分享 有正常模式的案例吗

使用特权

评论回复
15
keaibukelian| | 2018-9-4 09:53 | 只看该作者
非常感谢楼主分享 楼主的主控芯片是什么型号滴

使用特权

评论回复
16
xuanhuanzi| | 2018-9-4 21:09 | 只看该作者
楼主你能不能用插入代码的方式发代码啊。。。看的费劲

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

63

主题

1615

帖子

13

粉丝