⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stm8s_can.c

📁 STM8s
💻 C
📖 第 1 页 / 共 4 页
字号:


/**
  * @brief Returns the number of pending messages.
  * @retval Number of pending messages.
  */
CAN_NbrPendingMessage_TypeDef CAN_MessagePending(void)
{
    CAN_NbrPendingMessage_TypeDef msgpending = CAN_NbrPendingMessage_0;
    msgpending = (u8)(CAN->RFR & CAN_RFR_FMP01);
    return (CAN_NbrPendingMessage_TypeDef)msgpending;
}

/**
  * @brief  Receives a message which contains CAN Id, IDE, RTR
  * DLC, datas and FMI number.
  * In order to get these data, use CAN_GetReceivedId(), CAN_GetReceivedIDE(), CAN_GetReceivedRTR(),
  * CAN_GetReceivedDLC(), CAN_GetReceivedFMI() and CAN_GetReceivedData() functions.
  * @par Parameters:
  * None
  * @retval None
  */
void CAN_Receive(void)
{
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

    /* select Fifo page*/
    CAN->PSR = CAN_Page_RxFifo;

    /* Get the Id */
    _IDE = (u8)(CAN->Page.RxFIFO.MIDR1 & CAN_Id_Extended);
    if (_IDE != CAN_Id_Standard)
    {
        _Id = (u32)CAN_EXTID_SIZE & ((CAN->Page.RxFIFO.MIDR4) | ((u32)((u32)CAN->Page.RxFIFO.MIDR3) << 8) | ((u32)((u32)CAN->Page.RxFIFO.MIDR2) << 16) | ((u32)((u32)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 24) );
    }
    else
    {
        _Id = (u16)CAN_STDID_SIZE & ((u16)((u16)(CAN->Page.RxFIFO.MIDR1 & 0x1F) << 6) | ((CAN->Page.RxFIFO.MIDR2 >> 2)&0x3F) );
    }

    _RTR = (u8)(0x20 & CAN->Page.RxFIFO.MIDR1);

    /* Get the DLC */
    _DLC = (u8)(CAN->Page.RxFIFO.MDLCR & 0x0F);

    /* Get the FMI */
    _FMI = CAN->Page.RxFIFO.MFMI;

    /* Get the data field */
    _Data[0] = CAN->Page.RxFIFO.MDAR1;
    _Data[1] = CAN->Page.RxFIFO.MDAR2;
    _Data[2] = CAN->Page.RxFIFO.MDAR3;
    _Data[3] = CAN->Page.RxFIFO.MDAR4;
    _Data[4] = CAN->Page.RxFIFO.MDAR5;
    _Data[5] = CAN->Page.RxFIFO.MDAR6;
    _Data[6] = CAN->Page.RxFIFO.MDAR7;
    _Data[7] = CAN->Page.RxFIFO.MDAR8;

    /* Release the FIFO */
    CAN_FIFORelease();
    /*Restore Last Page*/
    CAN_SelectPage(can_page);
}


/**
  * @brief Gets the  CAN Id of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message Id.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
u32 CAN_GetReceivedId(void)
{
    return (_Id);
}

/**
  * @brief Gets the  CAN IDE of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message IDE.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
CAN_Id_TypeDef CAN_GetReceivedIDE(void)
{
    return (_IDE);
}

/**
  * @brief Gets the  CAN RTR of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message RTR.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
CAN_RTR_TypeDef CAN_GetReceivedRTR(void)
{
    return (_RTR);
}

/**
  * @brief Gets the  CAN DLC of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message DLC.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
u8 CAN_GetReceivedDLC(void)
{
    return (_DLC);
}

/**
  * @brief Gets the  CAN Data of the received message.
  * @param[in] CAN_DataIndexe : number of the received Data, it can
  *  be an integer between 0 to 7.
  * @retval the received CAN message ith Data.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
u8 CAN_GetReceivedData(u8 CAN_DataIndex)
{
    assert_param(IS_CAN_DLC_OK(CAN_DataIndex));
    return (_Data[CAN_DataIndex]);
}

/**
  * @brief Gets the  CAN FMI of the received message.
  * @par Parameters:
  * None
  * @retval the received CAN message FMI.
  * @par Required preconditions:
  * This function is used to get data loaded by CAN_Receive function.
  * Before using this function, CAN_Receive function must be called.
  */
u8 CAN_GetReceivedFMI(void)
{
    return (_FMI);
}
/**
  * @brief Returns the Received time stamp.
  * @par Parameters:
  * None
  * @retval u16 the received  time stamp.
  */
u16 CAN_GetMessageTimeStamp(void)
{
    u16 time;
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

    /*switch to the specific page */
    CAN->PSR = CAN_Page_RxFifo;
    /* Get the Received Time stamp */
    time = CAN->Page.RxFIFO.MTSRL;
    time |= (u16)(((u16)CAN->Page.RxFIFO.MTSRH)<<8);

    /*Restore Last Page*/
    CAN_SelectPage(can_page);

    return (u16)(time);
}


/**
  * @brief Enters the Sleep low power mode.
  * @par Parameters:
  * None
  * @retval  CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed in an other case.
  */
CAN_Sleep_TypeDef CAN_Sleep(void)
{

    CAN_Sleep_TypeDef sleepstatus = CAN_Sleep_Failed;

    /* Request Sleep mode */
    CAN->MCR = (u8)(((CAN->MCR) & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);

    /* Sleep mode status */
    if ((CAN->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
    {
        /* Sleep mode not entered */
        sleepstatus =  CAN_Sleep_Ok;
    }

    /* At this step, sleep mode status */
    return (CAN_Sleep_TypeDef) sleepstatus;
}




/**
  * @brief Wakes the CAN up.
  * @par Parameters:
  * None
  * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed in an other  case.
  */
CAN_WakeUp_TypeDef CAN_WakeUp(void)
{
    CAN_WakeUp_TypeDef wakeupstatus = CAN_WakeUp_Failed;

    /* Wake up request */
    CAN->MCR &= (u8)(~CAN_MCR_SLEEP);

    /* Sleep mode status */
    if ((CAN->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
    {
        /* Sleep mode exited */
        wakeupstatus = CAN_WakeUp_Ok;
    }

    /* At this step, sleep mode status */
    return (CAN_WakeUp_TypeDef)wakeupstatus;
}


/**
  * @brief  Select the CAN clock input.
  * @param[in] CAN_ClockSource : CAN clock input, can be one of @ref CAN_ClockSource_TypeDef.
  * @retval None
  */
void CAN_SelectClock(CAN_ClockSource_TypeDef CAN_ClockSource)
{
    u16 timeout =0;
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
    /* Check the parameters */
    assert_param(IS_CAN_CLOCKSOURCE_OK(CAN_ClockSource));
    /* Request initialisation */
    CAN->MCR |= (CAN_MCR_INRQ & ((u8)(~CAN_MCR_SLEEP)));

    CAN->PSR = CAN_Page_Config;
    if (CAN_ClockSource != CAN_ClockSource_Internal)
    {
        CAN->Page.Config.BTR2 |= (u8)CAN_BTR2_CLKS;
    }
    else
    {
        CAN->Page.Config.BTR2 &= (u8)(~CAN_BTR2_CLKS);
    }
    /* Request leave initialisation */
    CAN->MCR &= (u8)(~CAN_MCR_INRQ);
    /* Wait the acknowledge */
    while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
    {
        timeout--;
    }

    /*Restore Last Page*/
    CAN_SelectPage(can_page);
}

/**
  * @brief Select the CAN Operation mode.
  * @param[in] CAN_OperatingMode CAN Operating Mode ,
	* this parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
  * @retval None
  */
CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
{

    u16 timeout = CAN_ACKNOWLEDGE_TIMEOUT;

    assert_param(IS_CAN_OPERATINGMODE_OK(CAN_OperatingMode));

    if (CAN_OperatingMode == CAN_OperatingMode_Initialization)
    {
        /* Request initialisation */
        CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_SLEEP)) | CAN_MCR_INRQ);

        /* Wait the acknowledge */
        while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0))
        {
            timeout--;
        }
        if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK)
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
        }
        else
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
        }

    }
    else  if (CAN_OperatingMode == CAN_OperatingMode_Normal)
    {
        /* Request leave initialisation and sleep mode  and enter Normal mode */
        CAN->MCR &= (u8)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ));

        /* Wait the acknowledge */
        while (((CAN->MSR & CAN_MODE_MASK) != 0) && (timeout!=0))
        {
            timeout--;
        }
        if ((CAN->MSR & CAN_MODE_MASK) != 0)
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
        }
        else
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
        }
    }
    else  if (CAN_OperatingMode == CAN_OperatingMode_Sleep)
    {
        /* Request Sleep mode */
        CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);

        /* Wait the acknowledge */
        while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0))
        {
            timeout--;
        }
        if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK)
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
        }
        else
        {
            return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
        }
    }
    else
    {
        return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
    }

}

/**
  * @brief Gets the  Last Error Code.
  * @par Parameters:
  * None
  * @retval Error Code.
  */
CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(void)
{
    CAN_ErrorCode_TypeDef errcode = CAN_ErrorCode_NoErr;
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

    CAN->PSR = CAN_Page_Config;
    errcode = (u8)((CAN->Page.Config.ESR) & (CAN_ESR_LEC));

    /*Restore Last Page*/
    CAN_SelectPage(can_page);

    return (CAN_ErrorCode_TypeDef)(errcode);
}
/**
  * @brief Clears the CAN's pending flags.
  * @param[in] CAN_FLAG : Flag to be cleared, can be one of the folowing parameters:
  *						CAN_FLAG_RQCP0            Request MailBox0  Flag
  *						CAN_FLAG_RQCP1            Request MailBox1  Flag
  *						CAN_FLAG_RQCP2            Request MailBox2  Flag
  *						CAN_FLAG_FF               FIFO Full  Flag
  *						CAN_FLAG_FOV              FIFO Overrun  Flag
  *						CAN_FLAG_WKU              wake up   Flag
  *						CAN_FLAG_LEC               Last error code Flag
  * @retval None
  */
void CAN_ClearFlag(CAN_Flag_TypeDef CAN_Flag)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -