打印
[MM32软件]

MM32 L0 CAN驱动

[复制链接]
769|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
stm32jy|  楼主 | 2020-4-19 20:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
初始化CAN外设
u8 CAN_Init(CAN_TypeDef* CANx, CAN_Basic_InitTypeDef* pInitStruct)
{
    u8 InitStatus = CANINITFAILED;

    CANx->BTR0 = ((u32)(pInitStruct->SJW) << 6) | ((u32)(pInitStruct->BRP));
    CANx->BTR1 = ((u32)(pInitStruct->SAM) << 7) | ((u32)(pInitStruct->TESG2) << 4) | ((u32)(pInitStruct->TESG1));

    if (pInitStruct->GTS == ENABLE) {
        CANx->CMR |= (uint32_t)CAN_SleepMode;
        InitStatus = CANINITFAILED;
    }
    else {
        CANx->CMR &= ~(uint32_t)CAN_SleepMode;
        InitStatus = CANINITOK;
    }

    (pInitStruct->GTS == ENABLE) ? (CANx->CMR |= (u32)CAN_SleepMode) : (CANx->CMR &= ~(u32)CAN_SleepMode);

    CANx->CDR |=
        ((pInitStruct->CBP) << 6) | ((pInitStruct->RXINTEN) << 5) | ((pInitStruct->CLOSE_OPEN_CLK) << 3) | (pInitStruct->CDCLK);

    return InitStatus;
}


使用特权

评论回复
沙发
stm32jy|  楼主 | 2020-4-19 20:20 | 只看该作者
初始化CAN结构体
void CAN_StructInit(CAN_Basic_InitTypeDef* pInitStruct)
{
    // Reset CAN_Basic init structure parameters values

    // initialize the BRP member(where can be set with (0..63))
    pInitStruct->BRP = 0x0;
    // initialize the SJW member(where can be set with (0..3))
    pInitStruct->SJW = 0x0;
    // Initialize the TESG1 member(where can be set with (0..15))
    pInitStruct->TESG1 = 0x0;
    // Initialize the TESG2 member(where can be set with(0..7))
    pInitStruct->TESG2 = 0x0;
    // Initialize the SAM member(where can be set (SET or RESET))
    pInitStruct->SAM = RESET;
    // Initialize the GTS member to Sleep Mode(where can be set (ENABLE or
    // DISABLE))
    pInitStruct->GTS = DISABLE;
    // Initialize the external pin CLKOUT frequence
    pInitStruct->CDCLK = 0x0;
    // Initialize the external clk is open or close
    pInitStruct->CLOSE_OPEN_CLK = 0x0;
    // Initialize the TX1 pin work as rx interrupt output
    pInitStruct->RXINTEN = 0x0;
    // Initialize the CBP of CDR register
    pInitStruct->CBP = 0x0;
}


使用特权

评论回复
板凳
stm32jy|  楼主 | 2020-4-19 20:21 | 只看该作者
CAN 邮箱发送函数
u8 CAN_Transmit(CAN_TypeDef* CANx, CanBasicTxMsg* BasicTxMessage)
{
    CANx->TXID0 = (BasicTxMessage->IDH);
    CANx->TXID1 = (BasicTxMessage->IDL << 5) | (BasicTxMessage->RTR << 4) | (BasicTxMessage->DLC);
    if ((FunctionalState)(BasicTxMessage->RTR) != ENABLE) {
        CANx->TXDR0 = BasicTxMessage->Data[0];
        CANx->TXDR1 = BasicTxMessage->Data[1];
        CANx->TXDR2 = BasicTxMessage->Data[2];
        CANx->TXDR3 = BasicTxMessage->Data[3];
        CANx->TXDR4 = BasicTxMessage->Data[4];
        CANx->TXDR5 = BasicTxMessage->Data[5];
        CANx->TXDR6 = BasicTxMessage->Data[6];
        CANx->TXDR7 = BasicTxMessage->Data[7];
    }

    CANx->CMR = CAN_CMR_TR;

    return (CANx->SR & 0x01);
}


使用特权

评论回复
地板
stm32jy|  楼主 | 2020-4-19 20:22 | 只看该作者
CAN接收函数
void CAN_Receive(CAN_TypeDef* CANx, CanBasicRxMsg* BasicRxMessage)
{
    u16 tempid;

    BasicRxMessage->RTR = (u8)((CANx->RXID1) >> 4) & 0x1;
    BasicRxMessage->DLC = (u8)((CANx->RXID1) & 0xf);
    tempid              = (u16)(((CANx->RXID1) & 0xe0) >> 5);
    tempid |= (u16)(CANx->RXID0 << 3);
    BasicRxMessage->ID      = tempid;
    BasicRxMessage->Data[0] = CAN1->RXDR0;
    BasicRxMessage->Data[1] = CAN1->RXDR1;
    BasicRxMessage->Data[2] = CAN1->RXDR2;
    BasicRxMessage->Data[3] = CAN1->RXDR3;
    BasicRxMessage->Data[4] = CAN1->RXDR4;
    BasicRxMessage->Data[5] = CAN1->RXDR5;
    BasicRxMessage->Data[6] = CAN1->RXDR6;
    BasicRxMessage->Data[7] = CAN1->RXDR7;
    CAN_FIFORelease(CANx);
}


使用特权

评论回复
5
stm32jy|  楼主 | 2020-4-19 20:23 | 只看该作者
CAN休眠和唤醒函数:
u8 CAN_Sleep(CAN_TypeDef* CANx)
{
    CANx->CMR |= CAN_SleepMode;
    // At this step, sleep mode status
    return (u8)((CANx->CMR & 0x10) == CAN_SleepMode) ? CANSLEEPOK : CANSLEEPFAILED;
}

////////////////////////////////////////////////////////////////////////////////
u8 CAN_WakeUp(CAN_TypeDef* CANx)
{
    // Wake up request
    CANx->CMR &= ~CAN_SleepMode;
    return (u8)((CANx->CMR & 0x01) == 0) ? CANWAKEUPOK : CANWAKEUPFAILED;
}


使用特权

评论回复
6
stm32jy|  楼主 | 2020-4-19 20:25 | 只看该作者
CAN Peli模式初始化;
void CAN_Peli_Init(CAN_Peli_InitTypeDef* pInitStruct)
{
    CAN1_PELI->BTR0 = ((u32)pInitStruct->SJW << 6) | ((u32)pInitStruct->BRP);
    CAN1_PELI->BTR1 = ((u32)pInitStruct->SAM << 7) | ((u32)pInitStruct->TESG2 << 4) | ((u32)pInitStruct->TESG1);
    if (pInitStruct->LOM == ENABLE)
        CAN1_PELI->MOD |= (u32)CAN_ListenOnlyMode;
    else
        CAN1_PELI->MOD &= ~(u32)CAN_ListenOnlyMode;
    if (pInitStruct->STM == ENABLE)
        CAN1_PELI->MOD |= (u32)CAN_SeftTestMode;
    else
        CAN1_PELI->MOD &= ~(u32)CAN_SeftTestMode;
    if (pInitStruct->SM == ENABLE)
        CAN1_PELI->MOD |= (u32)CAN_SleepMode;
    else
        CAN1_PELI->MOD &= ~(u32)CAN_SleepMode;
    CAN1_PELI->EWLR = (u32)pInitStruct->EWLR;
}


使用特权

评论回复
7
stm32jy|  楼主 | 2020-4-19 20:25 | 只看该作者
CAN Peli 滤波初始化
void CAN_Peli_FilterInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
{
    (CAN_Peli_FilterInitStruct->AFM == CAN_FilterMode_Singal) ? (CAN1_PELI->MOD |= (u32)CAN_FilterMode_Singal)
    : (CAN1_PELI->MOD &= (u32)CAN_FilterMode_Double);

    CAN1_PELI->FF    = CAN_Peli_FilterInitStruct->CAN_FilterId0;
    CAN1_PELI->ID0   = CAN_Peli_FilterInitStruct->CAN_FilterId1;
    CAN1_PELI->ID1   = CAN_Peli_FilterInitStruct->CAN_FilterId2;
    CAN1_PELI->DATA0 = CAN_Peli_FilterInitStruct->CAN_FilterId3;

    CAN1_PELI->DATA1 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId0;
    CAN1_PELI->DATA2 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId1;
    CAN1_PELI->DATA3 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId2;
    CAN1_PELI->DATA4 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId3;
}


使用特权

评论回复
8
stm32jy|  楼主 | 2020-4-19 20:26 | 只看该作者
CAN Peli 滤波结构体初始化
void CAN_Peli_FilterStructInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
{
    CAN_Peli_FilterInitStruct->CAN_FilterId0 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterId1 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterId2 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterId3 = 0;

    CAN_Peli_FilterInitStruct->CAN_FilterMaskId0 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterMaskId1 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterMaskId2 = 0;
    CAN_Peli_FilterInitStruct->CAN_FilterMaskId3 = 0;
}


使用特权

评论回复
9
stm32jy|  楼主 | 2020-4-19 20:27 | 只看该作者
CAN Peli模式传输数据
void CAN_Peli_Transmit(CanPeliTxMsg* PeliTxMessage)
{
    CAN1_PELI->FF = (PeliTxMessage->FF << 7) | (PeliTxMessage->RTR << 6) | (PeliTxMessage->DLC);
    if (((FunctionalState)PeliTxMessage->FF) != ENABLE) {
        CAN1_PELI->ID0 = (PeliTxMessage->IDHH);
        // CAN1_PELI->ID1 = ((PeliTxMessage->IDHL)<<5);
        CAN1_PELI->ID1 = (PeliTxMessage->IDHL & 0xE0);
        if ((FunctionalState)(PeliTxMessage->RTR) != ENABLE) {
            CAN1_PELI->DATA0 = PeliTxMessage->Data[0];
            CAN1_PELI->DATA1 = PeliTxMessage->Data[1];
            CAN1_PELI->DATA2 = PeliTxMessage->Data[2];
            CAN1_PELI->DATA3 = PeliTxMessage->Data[3];
            CAN1_PELI->DATA4 = PeliTxMessage->Data[4];
            CAN1_PELI->DATA5 = PeliTxMessage->Data[5];
            CAN1_PELI->DATA6 = PeliTxMessage->Data[6];
            CAN1_PELI->DATA7 = PeliTxMessage->Data[7];
        }
    }
    else {
        CAN1_PELI->ID0   = PeliTxMessage->IDHH;
        CAN1_PELI->ID1   = PeliTxMessage->IDHL;
        CAN1_PELI->DATA0 = PeliTxMessage->IDLH;
        CAN1_PELI->DATA1 = PeliTxMessage->IDLL;
        if ((FunctionalState)(PeliTxMessage->RTR) != ENABLE) {
            CAN1_PELI->DATA2 = PeliTxMessage->Data[0];
            CAN1_PELI->DATA3 = PeliTxMessage->Data[1];
            CAN1_PELI->DATA4 = PeliTxMessage->Data[2];
            CAN1_PELI->DATA5 = PeliTxMessage->Data[3];
            CAN1_PELI->DATA6 = PeliTxMessage->Data[4];
            CAN1_PELI->DATA7 = PeliTxMessage->Data[5];
            CAN1_PELI->DATA8 = PeliTxMessage->Data[6];
            CAN1_PELI->DATA9 = PeliTxMessage->Data[7];
        }
    }

    (CAN1_PELI->MOD & CAN_MOD_STM) ? (CAN1->CMR = CAN_CMR_GTS | CAN_CMR_AT) : (CAN1->CMR = CAN_CMR_TR | CAN_CMR_AT);
}


使用特权

评论回复
10
stm32jy|  楼主 | 2020-4-19 20:29 | 只看该作者
CAN Peli 模式接收函数

void CAN_Peli_Receive(CanPeliRxMsg* PeliRxMessage)
{
    u32 tempid;
    PeliRxMessage->FF  = (CAN1_PELI->FF) >> 7;
    PeliRxMessage->RTR = ((CAN1_PELI->FF) >> 6) & 0x1;
    PeliRxMessage->DLC = (CAN1_PELI->FF) & 0xf;

    if (((FunctionalState)PeliRxMessage->FF) != ENABLE) {
        tempid = (u32)(CAN1_PELI->ID1 >> 5);
        tempid |= (u32)(CAN1_PELI->ID0 << 3);
        PeliRxMessage->ID      = tempid;
        PeliRxMessage->Data[0] = CAN1_PELI->DATA0;
        PeliRxMessage->Data[1] = CAN1_PELI->DATA1;
        PeliRxMessage->Data[2] = CAN1_PELI->DATA2;
        PeliRxMessage->Data[3] = CAN1_PELI->DATA3;
        PeliRxMessage->Data[4] = CAN1_PELI->DATA4;
        PeliRxMessage->Data[5] = CAN1_PELI->DATA5;
        PeliRxMessage->Data[6] = CAN1_PELI->DATA6;
        PeliRxMessage->Data[7] = CAN1_PELI->DATA7;
    }
    else {
        tempid = (u32)((CAN1_PELI->DATA1 & 0xf8) >> 3);
        tempid |= (u32)(CAN1_PELI->DATA0 << 5);
        tempid |= (u32)(CAN1_PELI->ID1 << 13);
        tempid |= (u32)(CAN1_PELI->ID0 << 21);
        PeliRxMessage->ID      = tempid;
        PeliRxMessage->Data[0] = CAN1_PELI->DATA2;
        PeliRxMessage->Data[1] = CAN1_PELI->DATA3;
        PeliRxMessage->Data[2] = CAN1_PELI->DATA4;
        PeliRxMessage->Data[3] = CAN1_PELI->DATA5;
        PeliRxMessage->Data[4] = CAN1_PELI->DATA6;
        PeliRxMessage->Data[5] = CAN1_PELI->DATA7;
        PeliRxMessage->Data[6] = CAN1_PELI->DATA8;
        PeliRxMessage->Data[7] = CAN1_PELI->DATA9;
    }
    CAN_FIFORelease(CAN1);
}


使用特权

评论回复
11
stm32jy|  楼主 | 2020-4-19 20:30 | 只看该作者
自动初始化CAN波特率
void CAN_AutoCfg_BaudParam(CAN_Peli_InitTypeDef* pInitStruct, u32 SrcClk, u32 baud)
{
    u32 i, value = baud, record = 1;
    u32 remain = 0, sumPrescaler = 0;
    while ((baud == 0) || (SrcClk == 0))
        ;
    sumPrescaler = SrcClk / baud;
    sumPrescaler = sumPrescaler / 2;
    for (i = 25; i > 3; i--) {
        remain = sumPrescaler - ((sumPrescaler / i) * i);
        if (remain == 0) {
            record = i;
            break;
        }
        else {
            if (remain < value) {
                value  = remain;
                record = i;
            }
        }
    }
    pInitStruct->SJW   = 0;
    pInitStruct->BRP   = (sumPrescaler / record) - 1;
    pInitStruct->TESG2 = (record - 3) / 3;
    pInitStruct->TESG1 = (record - 3) - pInitStruct->TESG2;
}


使用特权

评论回复
12
caizhiwei| | 2020-4-23 12:48 | 只看该作者
有完整的工程吗?贴一份呗,谢了

使用特权

评论回复
13
coslight| | 2020-4-23 13:21 | 只看该作者
请问楼主,这个测试遇到问题,请指点一下

使用特权

评论回复
14
caizhiwei| | 2020-4-26 12:46 | 只看该作者
你这是把历程复制了一遍~
复制出来啥都没说,有问题嘛还是?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

1118

帖子

4

粉丝