首页 > 代码库 > STM32F10xx CAN BUS相关库文件"stm32f10x_can.c"内的库函数解析

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

一、背景:        还是继续CAN通信,要节省开发时间,使用库函数可大大降低开发周期,并且还能确保寄存器的配置几    乎是万无一失,所以,在此就STM32F10xx的CAN操作库函数的使用做个简析。        STM32有库函数这件事,对软件开发人员来说是极其利好的,对库函数有褒有贬,说不好的,无非就是    库函数会占用一些额外Ram,并且不利于新手对于这款单片机更深层次的理解等等。我倒觉得,不应当有这    些顾虑,首先,库函数那都是由一些非常牛,并且对该型MCU极其了解的厂方工作人员编写,不去说万无一    失,但也是绝对按照标准来的好东西;其次,开发最重要的既是时间,先利用库函数实现快速开发,如若需    要深层次定制或者更改,再来对其进行研究,这样就可以节省时间去完成别人还未做过的事情,然后自己努    力去变成一个为别人提供库函数的人 :) ;至于新手,若需要知道如何正确使用库函数,必然会去研究手册    上那些东西。所以,推荐有库函数则优先使用库函数。貌似跑题了 - -!  继续,开始正文。二、正文:    1void 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;<------------|                   3void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)       // 将所有的CAN设置均设置为初始值。        4void 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;        5void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)        /* 调试冻结,即在调试时,CAN有两种工作模式         *   -->照常工作         *   -->冻结其收发,但仍可对FIFO进行读写。         * 操作寄存器为"CAN_MCR"的"DBF"位(Debug Freeze)。         */        6void CAN_SlaveStartBank(uint8_t CAN_BankNumber)        /* 内部对CAN过滤器主控制器(CAN_FMR)进行操作。        * 功能为规定第二组CAN2的过滤器组        * 由于只有互联型产品才有CAN2,所有该函数只用在互联型产品中。        */        7void 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"        10void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)        // 取消对应发送邮箱号的发送请求。        11void 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;        12void 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 : 睡眠中断使能 * } */ 20void 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(没有中断) */ 22static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) /* 为"21"函数"static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t * It_Bit)"的子函数。 */ 23void 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 : 上次错误号中断 */ 25void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) // 清除各类CAN状态flag。 至此,记录完毕。记录时间:2016年9月13日记录地点:深圳WZ

 

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