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

📄 stm8s_can.c

📁 STM8s
💻 C
📖 第 1 页 / 共 4 页
字号:
/**
  ******************************************************************************
  * @file stm8s_can.c
  * @brief This file contains all the functions for the CAN peripheral.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.1
  * @date 06/05/2009
  ******************************************************************************
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
  * @image html logo.bmp
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm8s_can.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define CAN_IDLIST_IDMASK_MASK ((u8) 0x55)
#define CAN_IDMASK_IDLIST_MASK ((u8) 0xAA)
#define CAN_MODE_MASK ((u8) 0x03)
#define CAN_ACKNOWLEDGE_TIMEOUT ((u16)0xFFFF)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
vu32 _Id;
vu8 _IDE;
vu8 _RTR;
vu8 _DLC;
vu8 _Data[8];
vu8 _FMI;
/* Private function prototypes -----------------------------------------------*/
static ITStatus CheckITStatus(u8 CAN_Reg, u8 It_Bit);

/* Private functions ---------------------------------------------------------*/
/**
  * @addtogroup CAN_Public_Functions
  * @{
  */

/**
  * @brief Deinitializes the CAN peripheral registers to their default reset values.
  * @par Parameters:
  * None
  * @retval None
  */
void CAN_DeInit(void)
{
    /* Request initialisation */
    CAN->MCR = CAN_MCR_INRQ;
    CAN->PSR = CAN_Page_Config;
    CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
    CAN->Page.Config.ESR = CAN_ESR_RESET_VALUE;
    CAN->Page.Config.EIER = CAN_EIER_RESET_VALUE;
    CAN->Page.Config.BTR1 = CAN_BTR1_RESET_VALUE;
    CAN->Page.Config.BTR2 = CAN_BTR2_RESET_VALUE;
    CAN->Page.Config.FMR1 = CAN_FMR1_RESET_VALUE;
    CAN->Page.Config.FMR2 = CAN_FMR2_RESET_VALUE;
    CAN->Page.Config.FCR1 = CAN_FCR_RESET_VALUE;
    CAN->Page.Config.FCR2 = CAN_FCR_RESET_VALUE;
    CAN->Page.Config.FCR3 = CAN_FCR_RESET_VALUE;
    CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
    CAN->PSR = CAN_Page_RxFifo;
    CAN->Page.RxFIFO.MDLCR = CAN_MDLC_RESET_VALUE;
    CAN->PSR = CAN_Page_TxMailBox0;
    CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
    CAN->PSR = CAN_Page_TxMailBox1;
    CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
    CAN->PSR = CAN_Page_TxMailBox2;
    CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;

    CAN->MCR = CAN_MCR_RESET_VALUE;
    CAN->MSR = (u8)(~CAN_MSR_RESET_VALUE);/* rc_w1 */
    CAN->TSR = (u8)(~CAN_TSR_RESET_VALUE);/* rc_w1 */
    CAN->RFR = (u8)(~CAN_RFR_RESET_VALUE);/* rc_w1 */
    CAN->IER = CAN_IER_RESET_VALUE;
    CAN->DGR = CAN_DGR_RESET_VALUE;
    CAN->PSR = CAN_PSR_RESET_VALUE;
}
/**
  * @brief Initializes the CAN peripheral according to the specified parameters.
  * @param[in] CAN_MasterCtrl : Master control option, can be one or a combinaison of @ref CAN_MasterCtrl_TypeDef.
  * @param[in] CAN_Mode : CAN mode , can be one of @ref CAN_Mode_TypeDef.
  * @param[in] CAN_SynJumpWidth : CAN Synchronisation Jump Width , can be one of @ref CAN_SynJumpWidth_TypeDef.
  * @param[in] CAN_BitSeg1 : CAN bit segment 1 , can be one of @ref CAN_BitSeg1_TypeDef.
  * @param[in] CAN_BitSeg2 : CAN bit segment 2 , can be one of @ref CAN_BitSeg2_TypeDef.
  * @param[in] CAN_ClockSource : CAN clock source , can be one of @ref CAN_ClockSource_TypeDef.
  * @param[in] CAN_Prescaler : CAN Baud Rate Prescaler , can be a value from 0x01 to 0xFF.
  * @retval Indicates if initialization is succeed. it can be one of @ref CAN_InitStatus_TypeDef enumeration.
  */

CAN_InitStatus_TypeDef CAN_Init(CAN_MasterCtrl_TypeDef CAN_MasterCtrl,
                                CAN_Mode_TypeDef CAN_Mode,
                                CAN_SynJumpWidth_TypeDef CAN_SynJumpWidth,
                                CAN_BitSeg1_TypeDef CAN_BitSeg1,
                                CAN_BitSeg2_TypeDef CAN_BitSeg2,
                                CAN_ClockSource_TypeDef CAN_ClockSource,
                                u8 CAN_Prescaler)
{
    CAN_InitStatus_TypeDef InitStatus =  CAN_InitStatus_Failed;
    u16 timeout = CAN_ACKNOWLEDGE_TIMEOUT;
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();


    /* Check the parameters */
    assert_param(IS_CAN_MASTERCTRL_OK(CAN_MasterCtrl));
    assert_param(IS_CAN_MODE_OK(CAN_Mode));
    assert_param(IS_CAN_SYNJUMPWIDTH_OK(CAN_SynJumpWidth));
    assert_param(IS_CAN_BITSEG1_OK(CAN_BitSeg1));
    assert_param(IS_CAN_BITSEG2_OK(CAN_BitSeg2));
    assert_param(IS_CAN_CLOCKSOURCE_OK(CAN_ClockSource));
    assert_param(IS_CAN_PRESCALER_OK(CAN_Prescaler));

    /* Request initialisation */
    CAN->MCR = CAN_MCR_INRQ;
    /* Wait the acknowledge */
    while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK))
    {
        timeout--;
    }

    /* Check acknowledged */
    if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
    {

        InitStatus =  CAN_InitStatus_Failed;

    }
    else
    {
        /* Set the time triggered communication mode  &  Set the automatic bus-off management  &   Set the automatic wake-up mode
        &     Set the no automatic retransmission & Set the receive FIFO locked mode & Set the transmit FIFO priority */
        CAN->MCR |= (u8)CAN_MasterCtrl;

        /* Set the bit timing register */
        CAN->DGR |= (u8)CAN_Mode ;
        CAN->PSR = CAN_Page_Config;
        CAN->Page.Config.BTR1 = (u8)(CAN_SynJumpWidth | (CAN_Prescaler - 1));
        CAN->Page.Config.BTR2 = (u8)(CAN_BitSeg1 | CAN_BitSeg2 | CAN_ClockSource);

        /* Request leave initialisation */
        CAN->MCR &= (u8)(~CAN_MCR_INRQ);
        /* Wait the acknowledge */
        timeout = 0xFFFF;
        while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
        {
            timeout--;
        }
        /* Check acknowledged */
        if ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
        {
            InitStatus = CAN_InitStatus_Failed;
        }
        else
        {
            InitStatus = CAN_InitStatus_Success;
        }
    }
    /*Restore Last Page*/
    CAN_SelectPage(can_page);

    /* Return the status of initialization */
    return (CAN_InitStatus_TypeDef)InitStatus;
}

/**
  * @brief Initializes the CAN peripheral Filter according to the specified parameters.
  * @param[in] CAN_FilterNumber : CAN Filter number , can be one of @ref CAN_FilterNumber_TypeDef
  * @param[in] CAN_FilterActivation : CAN Filter Activation state , can be one of @ref FunctionalState
  * @param[in] CAN_FilterMode : CAN Filter Mode , can be one of @ref CAN_FilterMode_TypeDef
  * @param[in] CAN_FilterScale : CAN Filter Scale , can be one of @ref CAN_FilterScale_TypeDef
  * @param[in] CAN_FilterID1 : CAN Filter ID 1 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID2 : CAN Filter ID 2 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID3 : CAN Filter ID 3 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterID4 : CAN Filter ID 4 , can be a value from 0x00 to 0xFF
  * @param[in] CAN_FilterIDMask1 : CAN Filter ID 1/ Mask 1  , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask2 : CAN Filter ID 2/ Mask 2 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask3 : CAN Filter ID 3/ Mask 3 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @param[in] CAN_FilterIDMask4 : CAN Filter ID 4/ Mask 4 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
  * @retval None
  */
void CAN_FilterInit(CAN_FilterNumber_TypeDef CAN_FilterNumber,
                    FunctionalState CAN_FilterActivation,
                    CAN_FilterMode_TypeDef CAN_FilterMode,
                    CAN_FilterScale_TypeDef CAN_FilterScale,
                    u8 CAN_FilterID1,
                    u8 CAN_FilterID2,
                    u8 CAN_FilterID3,
                    u8 CAN_FilterID4,
                    u8 CAN_FilterIDMask1,
                    u8 CAN_FilterIDMask2,
                    u8 CAN_FilterIDMask3,
                    u8 CAN_FilterIDMask4)
{
    u8 fact = 0;
    u8 fsc  = 0;
    u8 fmhl = 0;

    CAN_Page_TypeDef can_page_filter = CAN_Page_Filter01;
    CAN_Page_TypeDef can_page = CAN_GetSelectedPage();

    /* Check the parameters */
    assert_param(IS_CAN_FILTER_NUMBER_OK(CAN_FilterNumber));
    assert_param(IS_FUNCTIONALSTATE_OK(CAN_FilterActivation));
    assert_param(IS_CAN_FILTER_MODE_OK(CAN_FilterMode));
    assert_param(IS_CAN_FILTER_SCALE_OK(CAN_FilterScale));


    if (CAN_FilterNumber == CAN_FilterNumber_0)
    {
        fact = 0x01;
        fsc  = 0x00;
        fmhl = 0x03;

        can_page_filter = CAN_Page_Filter01;
    }
    else if (CAN_FilterNumber == CAN_FilterNumber_1)
    {
        fact = 0x10;
        fsc  = 0x04;
        fmhl = 0x0C;

        can_page_filter = CAN_Page_Filter01;
    }
    else if (CAN_FilterNumber == CAN_FilterNumber_2)
    {
        fact = 0x01;
        fsc  = 0x00;
        fmhl = 0x30;

        can_page_filter = CAN_Page_Filter23;
    }
    else if (CAN_FilterNumber == CAN_FilterNumber_3)
    {
        fact = 0x10;
        fsc  = 0x04;
        fmhl = 0xC0;

        can_page_filter = CAN_Page_Filter23;
    }
    else if (CAN_FilterNumber == CAN_FilterNumber_4)
    {
        fact = 0x01;
        fsc  = 0x00;
        fmhl = 0x03;

        can_page_filter = CAN_Page_Filter45;
    }
    else /*if (CAN_FilterNumber == CAN_FilterNumber_5)*/
    {
        fact = 0x10;
        fsc  = 0x04;
        fmhl = 0x0C;

        can_page_filter = CAN_Page_Filter45;
    }


    CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);

    CAN->PSR = CAN_Page_Config;
    /*---------------------------------------------------------*/
    /*Configuration of Filter Scale                            */
    /*---------------------------------------------------------*/

    if (can_page_filter == CAN_Page_Filter01) /* FCR1 */
    {
        /* Filter Deactivation  & Reset the Filter Scale */
        CAN->Page.Config.FCR1 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
        /* Set the new Filter Scale */
        CAN->Page.Config.FCR1 |= (u8)(CAN_FilterScale << fsc);
    }
    else if (can_page_filter == CAN_Page_Filter23) /* FCR2*/
    {
        /* Filter Deactivation  & Reset the Filter Scale */
        CAN->Page.Config.FCR2 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));

        /* Set the new Filter Scale */
        CAN->Page.Config.FCR2 |= (u8)(CAN_FilterScale << fsc);

    }
    else /*if(can_page_filter == CAN_Page_Filter45)*/ /* FCR3*/
    {
        /* Filter Deactivation  & Reset the Filter Scale */
        CAN->Page.Config.FCR3 &= (u8)~( fact | ((CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));

        /* Set the new Filter Scale */
        CAN->Page.Config.FCR3 |= (u8)(CAN_FilterScale << fsc);
    }

    /*---------------------------------------------------------*/
    /*Configuration of Filter Mode                             */
    /*---------------------------------------------------------*/
    if (can_page_filter != CAN_Page_Filter45) /* FMR1*/
    {
        /* Filter Mode */
        if (CAN_FilterMode == CAN_FilterMode_IdMask)
        {
            /*Id/Mask mode for the filter*/
            CAN->Page.Config.FMR1 &= (u8)~(fmhl);
        }
        else if ( CAN_FilterMode == CAN_FilterMode_IdList)
        {
            /*Identifier list mode for the filter*/
            CAN->Page.Config.FMR1 |= (u8)(fmhl);
        }
        else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
        {
            /*Identifier list mode is first  for the filter*/
            CAN->Page.Config.FMR1 |= (u8)(fmhl & CAN_IDLIST_IDMASK_MASK);
        }
        else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
        {
            /*Id Mask mode is first  for the filter*/
            CAN->Page.Config.FMR1 |= (u8)(fmhl & CAN_IDMASK_IDLIST_MASK);
        }


    }
    else /* FMR2 */
    {

        /* Filter Mode */
        if (CAN_FilterMode == CAN_FilterMode_IdMask)
        {
            /*Id/Mask mode for the filter*/
            CAN->Page.Config.FMR2 &= (u8)~(fmhl);
        }
        else if ( CAN_FilterMode == CAN_FilterMode_IdList)
        {
            /*Identifier list mode for the filter*/
            CAN->Page.Config.FMR2 |= (u8)(fmhl);
        }
        else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
        {
            /*Identifier list mode is first  for the filter*/
            CAN->Page.Config.FMR2 |= (u8)(fmhl & CAN_IDLIST_IDMASK_MASK);
        }
        else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
        {
            /*Id Mask mode is first  for the filter*/
            CAN->Page.Config.FMR2 |= (u8)(fmhl & CAN_IDMASK_IDLIST_MASK);
        }
    }
    /*---------------------------------------------------------*/
    /*Configuration of Filter IDs                              */
    /*---------------------------------------------------------*/
    CAN->PSR = (u8)can_page_filter;
    if (fsc != 0)
    {
        /* Filter Scale */
        if (CAN_FilterScale == CAN_FilterScale_8Bit)
        {
            CAN->Page.Filter.FR09 = CAN_FilterID1;
            CAN->Page.Filter.FR10 = CAN_FilterIDMask1;
            CAN->Page.Filter.FR11 = CAN_FilterID2;
            CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
            CAN->Page.Filter.FR13 = CAN_FilterID3;
            CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
            CAN->Page.Filter.FR15 = CAN_FilterID4;
            CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
        }
        else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
        {

⌨️ 快捷键说明

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