嵌入式单片机实战开发:STM32F103 CAN总线功能开发与物联技术

CAN模块测试

1、功能描述

        bxCAN是基本扩展CAN(Basic Extended CAN)的缩写,它支持CAN协议2.0A和2.0B。它的设计目标是以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。

2、主要特性

  1. 支持CAN协议2.0A和2.0B主动模式
  2. 波特率最高可达1兆位/秒
  3. 支持时间触发通信功能

发送

  1. 3个发送邮箱
  2. 发送报文的优先级特性可软件配置
  3. 记录发送SOF时刻的时间

接收

  1. 3级深度的2个FIFO
  2. 14个位宽可变的过滤器组-由整个CAN共享
  3. 标识符列表
  4. FIFO溢出处理方式可配置
  5. 记录接收 SOF时刻的时间

可支持时间触发通信模式

  1. 禁止自动重传模式
  2. 16位自由运行定时器
  3. 定时器分辨率可配置
  4. 可在最后2个数据字节发送时间

管理

  1. 中断可屏蔽
  2. 邮箱占用单独1块地址空间,便于提高软件效率

发送邮箱

  1. 共有3个发送邮箱供软件来发送报文。发送调度器根据优先级决定哪个邮箱的报文先被发送。

接收过滤器

  1. 共有14个位宽可变/可配置的标识符过滤器组,软件通过对它们编程,从而在引脚收到的报文中选择它需要的报文,而把其他报文丢弃掉。

接收FIFO

  1. 共有2个接收FIFO,每个FIFO都可以存放3个完整的报文。它们完全由硬件来管理

3、工作模式

  1. 软件代码

 

#include"stm32f10x_lib.h"

#define GPIO_CAN                   GPIOB

#define GPIO_Pin_CAN_RX            GPIO_Pin_8

#define GPIO_Pin_CAN_TX            GPIO_Pin_9

#define GPIO_Remap_CAN             GPIO_Remap1_CAN

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

/******************************************************************

* 函数名称:TestStatus CAN_Polling_Configuration(void)

* 功能描述:采用查询的方式来测试CAN总线

* 入口参数:无

* 出口参数: TestStatus

                                                     测试的状态码,若发送与接收的数据一致返回1

                                                                                        否则,返回0

******************************************************************/

TestStatus CAN_Polling_Configuration(void)

{

        GPIO_InitTypeDef      GPIO_InitStructure;

        CAN_InitTypeDef               CAN_InitStructure;

        CAN_FilterInitTypeDef       CAN_FilterInitStructure;

        CanTxMsg TxMessage;

        CanRxMsg RxMessage;

        u8 TransmitMailbox = 0;

        u32 i;

        /********************** *************************************

                                         CAN 总线的引脚配置

        ************************************************************/

   /* Configure CAN pin: RX */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

    GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

    /* Configure CAN pin: TX */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_Remap_CAN , ENABLE);

  

        /********************** *************************************

                                         CAN 总线的配置

        ************************************************************/

          /* CAN register init */

    CAN_DeInit();

    CAN_StructInit(&CAN_InitStructure);

        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;  //接收FIFO锁定模式

        CAN_InitStructure.CAN_TXFP = DISABLE;  //发送FIFO优先级

        CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;       //回环模式,自发自收

        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;       //同步跳跃1个时间单元

        CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;        //时间段1为8个时间单元

        CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;        //时间段2为7个时间单元

        CAN_InitStructure.CAN_Prescaler = 5;            //分频值

        CAN_Init(&CAN_InitStructure);

        /********************** *************************************

                                         CAN 总线的过滤设置

        ************************************************************/

        CAN_FilterInitStructure.CAN_FilterNumber = 0; //指定初始化的过滤器编号为0     (0~13)

        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//标识符屏蔽位模式

        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;//1个32位的过滤器

        CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; //设定过滤器的标识符(32位为其高段,16位为第一个)范围是0x0000~0xffff

        CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;  //设定过滤器的标识符(32位为其低段,16位为第二个)范围是0x0000~0xffff

        CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//设定过滤器屏蔽标识符或者过滤标识符

        CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//设定过滤器屏蔽标识符或者过滤标识符

        CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;       //过滤器FIFO指向过滤器0

    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;      //使能过滤器

        CAN_FilterInit(&CAN_FilterInitStructure);

        /********************** *************************************

                                         CAN 总线的发送设置

        ************************************************************/

        TxMessage.StdId = 0x11;     //标准标识符   

//      TxMessage.ExtId =            //扩展标识符

        TxMessage.IDE = CAN_ID_STD; //使用标准标识符

    TxMessage.RTR = CAN_RTR_DATA;  //数据帧

        TxMessage.DLC = 2;                     //设定传输消息的帧长度为2

        TxMessage.Data[0] = 0xCA;    //数据1

        TxMessage.Data[1] = 0xFE;    //数据2

        TransmitMailbox = CAN_Transmit(&TxMessage);

        i=0;

        while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF))

        {

                i++;

        }

        i=0;

        while((CAN_MessagePending(CAN_FIFO0) < 1) && (i != 0xFF))

        {

                i++;

        }

        /********************** *************************************

                                         CAN 总线的接收设置

        ************************************************************/

        RxMessage.StdId = 0x00;            //设定标准标识符             

        RxMessage.IDE = CAN_ID_STD; //使用标准标识符

    RxMessage.DLC = 0;                   //用来设定待传输的帧长度

        RxMessage.Data[0]=0x00;           //数据1

    RxMessage.Data[1]=0x00;            //数据2

        CAN_Receive(CAN_FIFO0,&RxMessage);

       

  if (RxMessage.StdId!=0x11)    //发送和接收不一致,返回FAILED

  {

    return FAILED;

  }

  if (RxMessage.IDE!=CAN_ID_STD) //发送和接收不一致,返回FAILED

  {

    return FAILED;

  }

  if (RxMessage.DLC!=2)   //发送和接收不一致,返回FAILED

  {

    return FAILED;

  }

  if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE) //发送和接收不一致,返回FAILED

  {

    return FAILED;

  }

  return PASSED; /* Test Passed */       //否则返回PASSED

}

源码下载:

作者:物联技术666

物联沃分享整理
物联沃-IOTWORD物联网 » 嵌入式单片机实战开发:STM32F103 CAN总线功能开发与物联技术

发表评论