STM32F10xx CAN BUS相关库文件"stm32f10x_can.c"内的库函数解析

一、背景:
        还是继续CAN通信,要节省开发时间,使用库函数可大大降低开发周期,并且还能确保寄存器的配置几
    乎是万无一失,所以,在此就STM32F10xx的CAN操作库函数的使用做个简析。
        STM32有库函数这件事,对软件开发人员来说是极其利好的,对库函数有褒有贬,说不好的,无非就是
    库函数会占用一些额外Ram,并且不利于新手对于这款单片机更深层次的理解等等。我倒觉得,不应当有这
    些顾虑,首先,库函数那都是由一些非常牛,并且对该型MCU极其了解的厂方工作人员编写,不去说万无一
    失,但也是绝对按照标准来的好东西;其次,开发最重要的既是时间,先利用库函数实现快速开发,如若需
    要深层次定制或者更改,再来对其进行研究,这样就可以节省时间去完成别人还未做过的事情,然后自己努
    力去变成一个为别人提供库函数的人 :) ;至于新手,若需要知道如何正确使用库函数,必然会去研究手册
    上那些东西。所以,推荐有库函数则优先使用库函数。貌似跑题了 - -!  继续,开始正文。

二、正文:
    1、void CAN_DeInit(CAN_TypeDef* CANx)
       // 操作APB1外设复位寄存器。对CAN进行复位操作。
       // 在STM32F10xx中,CAN的时钟由APB1分频提供。

    2、uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
       // 根据CAN_InitStruct结构体(详见以下),对CAN进行初始化操作。
       typedef struct
       {
           // CAN_Mode(Loop back mode)
           /* 0: 禁止环回模式。
            * 1:允许环回模式。
            */
           uint8_t CAN_Mode;

           // 以下4个参数,决定了CAN的波特率(具体如何配置,网上有计算工具)
           uint16_t CAN_Prescaler;
           uint8_t CAN_SJW;
           uint8_t CAN_BS1;
           uint8_t CAN_BS2;

           // TTCM(Time Triggered communication mode)
           /* 在该模式下,CAN硬件的内部定时器被激活,并且被用于产生(发送与接收邮箱的)时间戳,
            * 分别存储在CAN_RDTxR/CAN_TDTxR寄存器中。内部定时器在每个CAN位时间(见22.7.7节)累加。
            * 内部定时器在接收和发送的帧起始位的采样点位置被采样,并生成时间戳。
            */
           FunctionalState CAN_TTCM;

           // ABOM(Automatic Bus-off managerment)
           /* 0:软件对CAN_MCR寄存器的INRQ位置"1"随后清"0"后,一旦硬件检测到128次11位连续的隐形位,
            *   则退出离线状态。
            * 1:硬件检测到128次11位连续的隐形位,则自动退出离线状态。
            */
           FunctionalState CAN_ABOM;

           // AWUM (Automatic wakeup mode)
           /* 0:由软件清除CAN_MCR的"SLEEP"位后,唤醒睡眠模式。
            * 1:检测到报文,由硬件自动唤醒,且自动清零"SLEEP""SLAK"
            */
           FunctionalState CAN_AWUM;

           // NART(No Automatic retransmission)
           /* 0:按照CAN标准,CAN硬件在发送报文失败后会一直重新发送直至发送成功。
            * 1:CAN报文只发送一次。不管发送结果如何。
            */
           FunctionalState CAN_NART;                                         

           // RFLM (Receive FIFO Locked mode)
           /* 0:接收溢出后,FIFO未被锁定,即报文会被新报文覆盖。
            * 1:接收溢出后,FIFO被锁定,即新报文会被丢弃。
            */
           FunctionalState CAN_RFLM;

           // TXFP(Transmit FIFO priority)
           /* 0:优先级由报文的标识符来决定。
            * 1:优先级由发送请求的顺序来决定。
            */
           FunctionalState CAN_TXFP;

           // FunctionalState-----------------------------------------------------|
       } CAN_InitTypeDef;                                                         |
                                                                                  |
       typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;<------------|        

    3、void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)
       // 将所有的CAN设置均设置为初始值。

    4、void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
       // 根据结构体CAN_FilterInitStruct(详见如下)对CAN滤波进行初始化操作。
       typedef struct
       {
           // CANFxR1 高16位
           uint16_t CAN_FilterIdHigh;
           // CANFxR1 低16位
           uint16_t CAN_FilterIdLow;
           // CANFxR2 高16位
           uint16_t CAN_FilterMaskIdHigh;
           // CANFxR2 低16位
           uint16_t CAN_FilterMaskIdLow;

           // 对应哪一个过滤器
           uint8_t CAN_FilterNumber;

           // 对应的CAN_FilterNumber过滤器模式选择(FM1R)
           /* 过滤器组(14组)的2个32位寄存器工作在标识符屏蔽位模式。
            * 过滤器组(14组)的2个32位寄存器工作在标识符列表模式。
            */
           uint8_t CAN_FilterMode;

           // 对应的CAN_FilterNumber过滤器位宽设置(CAN_FS1R)
           /* CAN_FilterScale_16bit: 两个16位过滤器
            * CAN_FilterScale_32bit: 单个32位过滤器
            */
           uint8_t CAN_FilterScale;

           // 报文被过滤后,存放的哪个FIFO中。(CAN_FFA1R)
           // 每个FIFO可以存放3条报文。
           /* CAN_Filter_FIFO0: 过滤器被关联到了FIFO0
            * CAN_Filter_FIFO1: 过滤器被关联到了FIFO1
            */
           uint16_t CAN_FilterFIFOAssignment;

           // 是否使能对应的CAN_FilterNumber滤波器
           FunctionalState CAN_FilterActivation;
       } CAN_FilterInitTypeDef;

    5、void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
        /* 调试冻结,即在调试时,CAN有两种工作模式
         *   -->照常工作
         *   -->冻结其收发,但仍可对FIFO进行读写。
         * 操作寄存器为"CAN_MCR"的"DBF"位(Debug Freeze)。
         */

    6、void CAN_SlaveStartBank(uint8_t CAN_BankNumber)
       /* 内部对CAN过滤器主控制器(CAN_FMR)进行操作。
        * 功能为规定第二组CAN2的过滤器组
        * 由于只有互联型产品才有CAN2,所有该函数只用在互联型产品中。
        */

    7、void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState)
        /* 是否使用时间触发模式。NewState为Enable或者Disable。
         * 如果使用时间触发模式,则时间戳值自动填充在发送的每条CAN信息的6,7字节中。
         */

    8、uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
       /* 该函数会自动选择空的邮箱进行发送。返回值为邮箱号。
        * 若所有邮箱均不为空,则返回值为"CAN_TxStatus_NoMailBox"。
        * CAN发送信息函数。根据结构体TxMessage(定义如下)来发送CAN信息。
        */
       typedef struct
       {
           uint32_t StdId; // 标准帧标识符
           uint32_t ExtId; // 扩展帧标识符
           uint8_t IDE;    // 标准帧还是扩展帧
           uint8_t RTR;    // 数据帧还是远程帧
           uint8_t DLC;    // 数据字节长度(0~8)
           uint8_t Data[8];// 数据
       } CanTxMsg;

    9、uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
       // 检查对应邮箱号的状态:发送成功/失败/挂起。
       // 对应操作的寄存器为发送寄存器"CAN_TSR"

    10、void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
        // 取消对应发送邮箱号的发送请求。

    11、void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
        // 从FIFO0或者FIFO1接收CAN信息。并保存在结构体RxMessage中(详见如下)。
        // 该库函数在读完CAN信息后,会执行释放FIFO的动作
        typedef struct
        {
            uint32_t StdId;  // 标准帧标识符
            uint32_t ExtId;  // 扩展帧标识符
            uint8_t IDE;     // 标准帧还是扩展帧
            uint8_t RTR;     // 数据帧还是远程帧
            uint8_t DLC;     // 数据字节长度(0~8)
            uint8_t Data[8]; // 数据
            uint8_t FMI;     // 一个16位的值,表明该条信息由哪个滤波器给过滤的
        } CanRxMsg;

    12、void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
        // 释放接收FIFO,CAN_FIFO0 或者 CAN_FIFO1。

    13、uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
        // 检测对应的FIFO内报文条数。
        // 对应寄存器为"CAN_RF0R","CAN_RF1R"。

    14、uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode)
        /* 选择CAN的工作模式。
         *   --> CAN_OperatingMode_Initialization         *   --> CAN_OperatingMode_Normal         *   --> CAN_OperatingMode_Sleep
         * 返回值为CAN_ModeStatus_Success/CAN_ModeStatus_Failed
         */

    15、uint8_t CAN_Sleep(CAN_TypeDef* CANx)
        /* CAN进入休眠模式。
         * 返回值为CAN_Sleep_Ok/CAN_Sleep_Faild
         */

    16、uint8_t CAN_WakeUp(CAN_TypeDef* CANx)
        /* 唤醒对应的CAN。
         * 返回值的值为CAN_WakeUp_Ok/CAN_WakeUp_Failed
         */

    17、uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx)
        // 读取CAN上次错误的错误状态。
        /* CAN_ERRORCODE_NoErr            没有错误
         * CAN_ERRORCODE_StuffErr         位填充错误
         * CAN_ERRORCODE_FormErr          格式错误
         * CAN_ERRORCODE_ACKErr           确认错误
         * CAN_ERRORCODE_BitRecessiveErr  隐性位错误
         * CAN_ERRORCODE_BitDominantErr   显性位错误
         * CAN_ERRORCODE_CRCErr           CRC错误
         * CAN_ERRORCODE_SoftwareSetErr   软件自行设置的错误
         */
        /* 注意:这个函数在CAN_IT_LEC中断后需要立马读出保存,
         * 否则清零后,该值一并被清零。
         */

    18、uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx)
        // 返回CAN接收错误寄存器的值。

    19、uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx)
        // 返回CAN发送错误寄存器的值。

    //------------------------------------------------------------------------------
        /*
         * CAN_IT对应的每一位的代表一个中断FLAG {
         *     CAN_IT_TME  : 发送邮箱空中断
         *     CAN_IT_FMP0 : FIFO0消息挂号中断
         *     CAN_IT_FF0  : FIFO0消息满中断
         *     CAN_IT_FOV0 : FIFO0消息溢出中断
         *     CAN_IT_FMP1 : FIFO1消息挂号中断
         *     CAN_IT_FF1  : FIFO1消息满中断
         *     CAN_IT_FOV1 : FIFO1消息溢出中断
         *     CAN_IT_EWG  : 错误警告中断
         *     CAN_IT_EPV  : 错误被动中断
         *     CAN_IT_BOF  : 离线中断
         *     CAN_IT_LEC  : 上次错误号中断
         *     CAN_IT_ERR  : 错误中断使能
         *     CAN_IT_WKU  : 唤醒中断使能
         *     CAN_IT_SLK  : 睡眠中断使能
         * }
         */

    20、void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)
        /* 使能CAN相关中断,NewState为Enable或者Disable。
         * CAN_IT为以上所有FLAG进行"或"操作以后的值。
         */

    21、ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT)
        /* 传入CAN_IT的具体某一位FLAG,获取其是否处于中断状态,用在中断内。
         * 返回值是 SET (有中断)/ RESET(没有中断)
         */
    22、static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit)
        /* 为"21"函数"static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t
         * It_Bit)"的子函数。
         */

    23、void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT)
        // 清除对应中断的标志。
    //------------------------------------------------------------------------------

    24、FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
        /* 此函数乍看一下与函数"CAN_GetITStatus"的功能一致,均是检测中断状态。其实不然。
         * 函数"CAN_GetITStatus"是检测当前的中断状态。
         * 此函数是检查中断清零后,新的中断状态。
         */
        /* 检测各类CAN状态flag是否被set或者reset。
         * CAN_FLAG_EWG   : 错误警告中断
         * CAN_FLAG_EPV   : 错误被动中断
         * CAN_FLAG_BOF   : 离线中断
         * CAN_FLAG_RQCP0 : 邮箱0请求完成
         * CAN_FLAG_RQCP1 : 邮箱1请求完成
         * CAN_FLAG_RQCP2 : 邮箱2请求完成
         * CAN_FLAG_FMP1  : FIFO1消息挂号中断
         * CAN_FLAG_FF1   : FIFO1消息满中断
         * CAN_FLAG_FOV1  : FIFO1消息溢出中断
         * CAN_FLAG_FMP0  : FIFO0消息挂号中断
         * CAN_FLAG_FF0   : FIFO0消息满中断
         * CAN_FLAG_FOV0  : FIFO0消息溢出中断
         * CAN_FLAG_WKU   : 唤醒中断使能
         * CAN_FLAG_SLAK  : 睡眠中断使能
         * CAN_FLAG_LEC   : 上次错误号中断
         */

    25、void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
        // 清除各类CAN状态flag。

至此,记录完毕。

记录时间:2016年9月13日
记录地点:深圳WZ 
时间: 2024-10-07 06:31:23

STM32F10xx CAN BUS相关库文件"stm32f10x_can.c"内的库函数解析的相关文章

在Ubuntu宿主机上查看ARM交叉编译好的可执行程序和库文件的相关依赖关系,类似于PC上的ldd命令

在电脑上安装的Linux系统中,有一个ldd命令,可以查看对应的可执行文件或库文件依赖哪些库,但可执行文件或库文件要求与操作系统的编译器类型相同,即电脑是X86的GCC编译器,那么无法通过ldd命令查看ARM交叉编译器编译出来的可执行文件或库文件. 如果想在Ubuntu等Linux宿主机上查看ARM交叉编译好的可执行程序和库文件的相关依赖关系,可以通过以下命令: [email protected]:$ arm-linux-readelf  -a  busybox |grep "Shared&qu

整理Linux下gcc编译中关于头文件与库文件搜索路径相关问题

分类: MakeFile/Make/GCC/LD2010-11-20 23:15 535人阅读 评论(0) 收藏 举报 转者的话: 本文详细介绍了gcc 编译时 搜索头文件的路径以及方式, 编译时寻找lib库的方式, 以及运行时加载库的寻找方式!!!非常之经典啊!以后有新的知识都汇总到这里来了! 在交叉编译的时候我们需要用到其他的库,在config时候可以通过“-I”来指定头文件目录,但是每次都需要设置的话难免有些麻烦,找到一个简单的方法. 看下文的红色部分. 有大量的环境变量可供设置以影响 G

第一百六十一节,封装库--JavaScript,完整封装库文件

封装库--JavaScript,完整封装库文件 /** *feng_zhuang_ku_1.0版本,js封装库,2016/12/29日:林贵秀 **/ /** 前台调用 * 每次调用$()创建库对象,使其每次调用都是独立的对象 * $()创建库对象,有一个可选参数,参数有两种方式,1是传入的this,2是传入的字符串 * 可选参数说明: * 传入的this,this,就是当前对象本身 * * 传入的字符串,代表获取元素选择器 * 参数是元素选择器(id值.class值.标签名称)其中一样的字符串

linux下把log4cxx封装成so动态库文件(一)

这是一个经常遇到的问题,在软件开发过程中,需要将某些功能封装成一个独立的模块,这样维护升级也很方便.现在我们就要把开源日志库log4cxx封装成so动态加载库文件. 在上一篇文章<log4cxx日志库RedHat下安装>中,我们已经将log4cxx安装在home/mac/log4cxx/log4cxx下了,那么接下来的操作我们就继续在这个路径下进行. 还是先tree一下/home/mac/log4cxx这个目录吧 log4cxx ---apr ---apr-util ---log4cxx 那再

orcad常用库文件

ORCAD CAPTURE元件库介绍 AMPLIFIER.OLB amplifier 共182个零件,存放模拟放大器IC,如CA3280,TL027C,EL4093等. ARITHMETIC.OLB arithmetic 共182个零件,存放逻辑运算IC,如TC4032B,74LS85等. ATOD.OLB 共618个零件,存放A/D转换IC,如ADC0804,TC7109等. BUS DRIVERTRANSCEIVER.OLB 共632个零件,存放汇流排驱动IC,如74LS244,74LS37

修改OpenSSL默认编译出的动态库文件名称

在 Windows 平台上调用动态链接库 dll 文件时,有两种方式:a) 隐式的加载时链接:使用 *.lib (导入库)文件,在 IDE 的链接器相关设置中加入导入库 lib 文件的名称,或在程序中加入预编译指令 #pragma comment (lib,”*.lib”).b) 显式的运行时链接.不使用 *.lib (导入库)文件,使用 Load Library(),GetProcAddress() 函数来加载动态库中的函数.要注意的是在导入库 lib 文件内部包含了其对应 dll 文件的名称

四轴飞行器1.2.3 STM32F407时钟配置和升级标准库文件

原创文章,欢迎转载,转载请注明出处 这个星期进度比较慢哈,只有周末和晚上下班回来才能做,事件不连续,琐碎的事情又比较多,挺烦的,有多琐碎呢?           1.本人有点小强迫症哈,虽然RTT将文件夹已经分类的很好了,但是在一个项目跟目录下这样放着看起来还是很不舒服的哈,于是强迫症范了,要整理下它.按照以前做项目的习惯,将程序分为四个层次,硬件层,驱动层,系统层和应用层,我们就整理下,对三个文件夹,其中硬件层和驱动层放在BSP文件夹里面,BSP文件里面再分硬件和驱动的文件夹,同时添加一个库文

Linux 介绍了相关的文件夹

学习Linux,先了解Linux标准的文件夹结构是非常重要的,学习的一个很好的铺垫之后的行动.去罗列大而全的所有文件夹. 本文主要说明.笔者本人接触,须要了解的一些文件文件夹,当然本文也会不断的更新或更改. 也希望有幸能够阅读到本文.而且愿意指正本人文中不当或歧义的读者,给出你们宝贵的意见或建议. Linux文件夹类似一个树,最顶层是其根文件夹. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFob2tpbmc=/font/5a6L5L2T/fon

linux 内核头文件及内核库文件

与用户空间应用不同的是,内核不能调用标准C库或其它任何不属于内核的库.主要原因是,速度及大小的限制. 标准C库对内核而言实在是太大了. 许多常用的的 libc 函数已经在内核中实现了.内核中的库文件是在内核的根目录下 lib 目录下存放. 如常用的字符串操作函数是在 lib/string.c 中定义的,调用时主需要将头文件 <linux/string.h>包含进即可. 关于内核的头文件,内核是不能包含内核之外的头文件的,如同内核不能调用内核之外的库一样. 1)基本的头文件放在内核的 inclu