
昨天翻译了USB部分,但是鉴于我有一段翻译实在不知道怎么组织,所以不放上来了,等我什么时候想到了就再放上来 今天首先学习了CAN部分的芯片手册。这是与can有关的结构体及注释: typedef struct { CAN_TypeDef *Instance; /*!< Register base address */---这是寄存器的基本地址 CAN_InitTypeDef Init; /*!< CAN required parameters */这是初始化相应的参数 CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */----类似于UART的--TX CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure */类似于UART的--RX HAL_LockTypeDef Lock; /*!< CAN locking object */ __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */ __IO HAL_CAN_ErrorTypeDef ErrorCode; /*!< CAN Error code */ }CAN_HandleTypeDef; CAN∴寄存器地址 typedef struct { __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ uint32_t RESERVED2; /*!< Reserved, 0x208 */ __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ uint32_t RESERVED3; /*!< Reserved, 0x210 */ __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ uint32_t RESERVED4; /*!< Reserved, 0x218 */ __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ }CAN_TypeDef; typedef struct { __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ __IO uint32_t TDLR; /*!< CAN mailbox data low register */ __IO uint32_t TDHR; /*!< CAN mailbox data high register */ }CAN_TxMailBox_TypeDef; /** * @brief Controller Area Network FIFOMailBox */ typedef struct { __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ }CAN_FIFOMailBox_TypeDef; /** * @brief Controller Area Network FilterRegister */ typedef struct { __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ }CAN_FilterRegister_TypeDef; typedef struct { uint32_t Prescaler; /*!< Specifies the length of a time quantum. This parameter must be a number between Min_Data = 1 and Max_Data = 1024. */ uint32_t Mode; /*!< Specifies the CAN operating mode. This parameter can be a value of @ref CAN_operating_mode */ uint32_t SJW; /*!< Specifies the maximum number of time quanta the CAN hardware is allowed to lengthen or shorten a bit to perform resynchronization. This parameter can be a value of @ref CAN_synchronisation_jump_width */ uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1. This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */ uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2. This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ uint32_t TTCM; /*!< Enable or disable the time triggered communication mode. This parameter can be set to ENABLE or DISABLE. */ uint32_t ABOM; /*!< Enable or disable the automatic bus-off management. This parameter can be set to ENABLE or DISABLE. */ uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode. This parameter can be set to ENABLE or DISABLE. */ uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode. This parameter can be set to ENABLE or DISABLE. */ uint32_t RFLM; /*!< Enable or disable the Receive FIFO Locked mode. This parameter can be set to ENABLE or DISABLE. */ uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority. This parameter can be set to ENABLE or DISABLE. */ }CAN_InitTypeDef; typedef struct { uint32_t StdId; /*!< Specifies the standard identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */ uint32_t ExtId; /*!< Specifies the extended identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted. This parameter can be a value of @ref CAN_identifier_type */ uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted. This parameter can be a value of @ref CAN_remote_transmission_request */ uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted. This parameter must be a number between Min_Data = 0 and Max_Data = 8. */ uint32_t Data[8]; /*!< Contains the data to be transmitted. This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */ }CanTxMsgTypeDef; typedef struct { uint32_t StdId; /*!< Specifies the standard identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */ uint32_t ExtId; /*!< Specifies the extended identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received. This parameter can be a value of @ref CAN_identifier_type */ uint32_t RTR; /*!< Specifies the type of frame for the received message. This parameter can be a value of @ref CAN_remote_transmission_request */ uint32_t DLC; /*!< Specifies the length of the frame that will be received. This parameter must be a number between Min_Data = 0 and Max_Data = 8. */ uint32_t Data[8]; /*!< Contains the data to be received. This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */ uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */ uint32_t FIFONumber; /*!< Specifies the receive FIFO number. This parameter can be CAN_FIFO0 or CAN_FIFO1 */ }CanRxMsgTypeDef; 还有CAN异步跳转的数据宽度 #define CAN_SJW_1TQ ((uint32_t)0x00000000) /*!< 1 time quantum */ #define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */ #define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */ #define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */ typedef struct { uint32_t StdId; /*!< Specifies the standard identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */ uint32_t ExtId; /*!< Specifies the extended identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received. This parameter can be a value of @ref CAN_identifier_type */ uint32_t RTR; /*!< Specifies the type of frame for the received message. This parameter can be a value of @ref CAN_remote_transmission_request */ uint32_t DLC; /*!< Specifies the length of the frame that will be received. This parameter must be a number between Min_Data = 0 and Max_Data = 8. */ uint32_t Data[8]; /*!< Contains the data to be received. This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */ uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */ uint32_t FIFONumber; /*!< Specifies the receive FIFO number. This parameter can be CAN_FIFO0 or CAN_FIFO1 */ }CanRxMsgTypeDef; 这是CAN有关接收数据的参数 还有其他的数据结构定义,不过先回来看我的INIT函数 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan) { uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */ uint32_t tickstart = 0; /* Check CAN handle */ if(hcan == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP)); assert_param(IS_CAN_MODE(hcan->Init.Mode)); assert_param(IS_CAN_SJW(hcan->Init.SJW)); assert_param(IS_CAN_BS1(hcan->Init.BS1)); assert_param(IS_CAN_BS2(hcan->Init.BS2)); assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler)); if(hcan->State == HAL_CAN_STATE_RESET) { /* Init the low level hardware */ HAL_CAN_MspInit(hcan); } /* Initialize the CAN state*/ hcan->State = HAL_CAN_STATE_BUSY; /* Exit from sleep mode */ hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP); /* Request initialisation */ hcan->Instance->MCR |= CAN_MCR_INRQ ; /* Get tickstart */ tickstart = HAL_GetTick(); /* Wait the acknowledge */ while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { if((HAL_GetTick() - tickstart) > HAL_CAN_DEFAULT_TIMEOUT) { hcan->State= HAL_CAN_STATE_TIMEOUT; return HAL_TIMEOUT; } } /* Check acknowledge */ if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { /* Set the time triggered communication mode */ if (hcan->Init.TTCM == ENABLE) { hcan->Instance->MCR |= CAN_MCR_TTCM; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM; } /* Set the automatic bus-off management */ if (hcan->Init.ABOM == ENABLE) { hcan->Instance->MCR |= CAN_MCR_ABOM; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM; } /* Set the automatic wake-up mode */ if (hcan->Init.AWUM == ENABLE) { hcan->Instance->MCR |= CAN_MCR_AWUM; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM; } /* Set the no automatic retransmission */ if (hcan->Init.NART == ENABLE) { hcan->Instance->MCR |= CAN_MCR_NART; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART; } /* Set the receive FIFO locked mode */ if (hcan->Init.RFLM == ENABLE) { hcan->Instance->MCR |= CAN_MCR_RFLM; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM; } /* Set the transmit FIFO priority */ if (hcan->Init.TXFP == ENABLE) { hcan->Instance->MCR |= CAN_MCR_TXFP; } else { hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP; } /* Set the bit timing register */ hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \ ((uint32_t)hcan->Init.SJW) | \ ((uint32_t)hcan->Init.BS1) | \ ((uint32_t)hcan->Init.BS2) | \ ((uint32_t)hcan->Init.Prescaler - 1); /* Request leave initialisation */ hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ; /* Get timeout */ tickstart = HAL_GetTick(); /* Wait the acknowledge */ while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { if((HAL_GetTick() - tickstart) > HAL_CAN_DEFAULT_TIMEOUT) { hcan->State= HAL_CAN_STATE_TIMEOUT; return HAL_TIMEOUT; } } /* Check acknowledged */ if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { status = CAN_INITSTATUS_SUCCESS; } } if(status == CAN_INITSTATUS_SUCCESS) { /* Set CAN error code to none */ hcan->ErrorCode = HAL_CAN_ERROR_NONE; /* Initialize the CAN state */ hcan->State = HAL_CAN_STATE_READY; /* Return function status */ return HAL_OK; } else { /* Initialize the CAN state */ hcan->State = HAL_CAN_STATE_ERROR; /* Return function status */ return HAL_ERROR; } } |
CAN工业上用的多点吧,记得有一次看见万东的高频机使用了 can,还特地学习了下CAN的原理 |
谢谢分享。学习了
![]() |
我也在弄CAN。打算移植CANOPEN协议做主站 |
坚持就是胜利系列~ |
谢谢分享。 |
谢谢分享。 |
![]() |
![]() |
楼主辛苦了! |
不明觉厉,顶 |
工业上CAN多,还有其他一些,个人汽车 |
没怎么看懂。。。。![]() |
不懂帮顶! |
不明觉厉。。。。。。。。。。。 |