[MM32软件] MM32 L0 CAN驱动

[复制链接]
 楼主| stm32jy 发表于 2020-4-19 20:20 | 显示全部楼层 |阅读模式
初始化CAN外设
  1. u8 CAN_Init(CAN_TypeDef* CANx, CAN_Basic_InitTypeDef* pInitStruct)
  2. {
  3.     u8 InitStatus = CANINITFAILED;

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

  6.     if (pInitStruct->GTS == ENABLE) {
  7.         CANx->CMR |= (uint32_t)CAN_SleepMode;
  8.         InitStatus = CANINITFAILED;
  9.     }
  10.     else {
  11.         CANx->CMR &= ~(uint32_t)CAN_SleepMode;
  12.         InitStatus = CANINITOK;
  13.     }

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

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

  17.     return InitStatus;
  18. }


 楼主| stm32jy 发表于 2020-4-19 20:20 | 显示全部楼层
初始化CAN结构体
  1. void CAN_StructInit(CAN_Basic_InitTypeDef* pInitStruct)
  2. {
  3.     // Reset CAN_Basic init structure parameters values

  4.     // initialize the BRP member(where can be set with (0..63))
  5.     pInitStruct->BRP = 0x0;
  6.     // initialize the SJW member(where can be set with (0..3))
  7.     pInitStruct->SJW = 0x0;
  8.     // Initialize the TESG1 member(where can be set with (0..15))
  9.     pInitStruct->TESG1 = 0x0;
  10.     // Initialize the TESG2 member(where can be set with(0..7))
  11.     pInitStruct->TESG2 = 0x0;
  12.     // Initialize the SAM member(where can be set (SET or RESET))
  13.     pInitStruct->SAM = RESET;
  14.     // Initialize the GTS member to Sleep Mode(where can be set (ENABLE or
  15.     // DISABLE))
  16.     pInitStruct->GTS = DISABLE;
  17.     // Initialize the external pin CLKOUT frequence
  18.     pInitStruct->CDCLK = 0x0;
  19.     // Initialize the external clk is open or close
  20.     pInitStruct->CLOSE_OPEN_CLK = 0x0;
  21.     // Initialize the TX1 pin work as rx interrupt output
  22.     pInitStruct->RXINTEN = 0x0;
  23.     // Initialize the CBP of CDR register
  24.     pInitStruct->CBP = 0x0;
  25. }


 楼主| stm32jy 发表于 2020-4-19 20:21 | 显示全部楼层
CAN 邮箱发送函数
  1. u8 CAN_Transmit(CAN_TypeDef* CANx, CanBasicTxMsg* BasicTxMessage)
  2. {
  3.     CANx->TXID0 = (BasicTxMessage->IDH);
  4.     CANx->TXID1 = (BasicTxMessage->IDL << 5) | (BasicTxMessage->RTR << 4) | (BasicTxMessage->DLC);
  5.     if ((FunctionalState)(BasicTxMessage->RTR) != ENABLE) {
  6.         CANx->TXDR0 = BasicTxMessage->Data[0];
  7.         CANx->TXDR1 = BasicTxMessage->Data[1];
  8.         CANx->TXDR2 = BasicTxMessage->Data[2];
  9.         CANx->TXDR3 = BasicTxMessage->Data[3];
  10.         CANx->TXDR4 = BasicTxMessage->Data[4];
  11.         CANx->TXDR5 = BasicTxMessage->Data[5];
  12.         CANx->TXDR6 = BasicTxMessage->Data[6];
  13.         CANx->TXDR7 = BasicTxMessage->Data[7];
  14.     }

  15.     CANx->CMR = CAN_CMR_TR;

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


 楼主| stm32jy 发表于 2020-4-19 20:22 | 显示全部楼层
CAN接收函数
  1. void CAN_Receive(CAN_TypeDef* CANx, CanBasicRxMsg* BasicRxMessage)
  2. {
  3.     u16 tempid;

  4.     BasicRxMessage->RTR = (u8)((CANx->RXID1) >> 4) & 0x1;
  5.     BasicRxMessage->DLC = (u8)((CANx->RXID1) & 0xf);
  6.     tempid              = (u16)(((CANx->RXID1) & 0xe0) >> 5);
  7.     tempid |= (u16)(CANx->RXID0 << 3);
  8.     BasicRxMessage->ID      = tempid;
  9.     BasicRxMessage->Data[0] = CAN1->RXDR0;
  10.     BasicRxMessage->Data[1] = CAN1->RXDR1;
  11.     BasicRxMessage->Data[2] = CAN1->RXDR2;
  12.     BasicRxMessage->Data[3] = CAN1->RXDR3;
  13.     BasicRxMessage->Data[4] = CAN1->RXDR4;
  14.     BasicRxMessage->Data[5] = CAN1->RXDR5;
  15.     BasicRxMessage->Data[6] = CAN1->RXDR6;
  16.     BasicRxMessage->Data[7] = CAN1->RXDR7;
  17.     CAN_FIFORelease(CANx);
  18. }


 楼主| stm32jy 发表于 2020-4-19 20:23 | 显示全部楼层
CAN休眠和唤醒函数:
  1. u8 CAN_Sleep(CAN_TypeDef* CANx)
  2. {
  3.     CANx->CMR |= CAN_SleepMode;
  4.     // At this step, sleep mode status
  5.     return (u8)((CANx->CMR & 0x10) == CAN_SleepMode) ? CANSLEEPOK : CANSLEEPFAILED;
  6. }

  7. ////////////////////////////////////////////////////////////////////////////////
  8. u8 CAN_WakeUp(CAN_TypeDef* CANx)
  9. {
  10.     // Wake up request
  11.     CANx->CMR &= ~CAN_SleepMode;
  12.     return (u8)((CANx->CMR & 0x01) == 0) ? CANWAKEUPOK : CANWAKEUPFAILED;
  13. }


 楼主| stm32jy 发表于 2020-4-19 20:25 | 显示全部楼层
CAN Peli模式初始化;
  1. void CAN_Peli_Init(CAN_Peli_InitTypeDef* pInitStruct)
  2. {
  3.     CAN1_PELI->BTR0 = ((u32)pInitStruct->SJW << 6) | ((u32)pInitStruct->BRP);
  4.     CAN1_PELI->BTR1 = ((u32)pInitStruct->SAM << 7) | ((u32)pInitStruct->TESG2 << 4) | ((u32)pInitStruct->TESG1);
  5.     if (pInitStruct->LOM == ENABLE)
  6.         CAN1_PELI->MOD |= (u32)CAN_ListenOnlyMode;
  7.     else
  8.         CAN1_PELI->MOD &= ~(u32)CAN_ListenOnlyMode;
  9.     if (pInitStruct->STM == ENABLE)
  10.         CAN1_PELI->MOD |= (u32)CAN_SeftTestMode;
  11.     else
  12.         CAN1_PELI->MOD &= ~(u32)CAN_SeftTestMode;
  13.     if (pInitStruct->SM == ENABLE)
  14.         CAN1_PELI->MOD |= (u32)CAN_SleepMode;
  15.     else
  16.         CAN1_PELI->MOD &= ~(u32)CAN_SleepMode;
  17.     CAN1_PELI->EWLR = (u32)pInitStruct->EWLR;
  18. }


 楼主| stm32jy 发表于 2020-4-19 20:25 | 显示全部楼层
CAN Peli 滤波初始化
  1. void CAN_Peli_FilterInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
  2. {
  3.     (CAN_Peli_FilterInitStruct->AFM == CAN_FilterMode_Singal) ? (CAN1_PELI->MOD |= (u32)CAN_FilterMode_Singal)
  4.     : (CAN1_PELI->MOD &= (u32)CAN_FilterMode_Double);

  5.     CAN1_PELI->FF    = CAN_Peli_FilterInitStruct->CAN_FilterId0;
  6.     CAN1_PELI->ID0   = CAN_Peli_FilterInitStruct->CAN_FilterId1;
  7.     CAN1_PELI->ID1   = CAN_Peli_FilterInitStruct->CAN_FilterId2;
  8.     CAN1_PELI->DATA0 = CAN_Peli_FilterInitStruct->CAN_FilterId3;

  9.     CAN1_PELI->DATA1 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId0;
  10.     CAN1_PELI->DATA2 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId1;
  11.     CAN1_PELI->DATA3 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId2;
  12.     CAN1_PELI->DATA4 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId3;
  13. }


 楼主| stm32jy 发表于 2020-4-19 20:26 | 显示全部楼层
CAN Peli 滤波结构体初始化
  1. void CAN_Peli_FilterStructInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
  2. {
  3.     CAN_Peli_FilterInitStruct->CAN_FilterId0 = 0;
  4.     CAN_Peli_FilterInitStruct->CAN_FilterId1 = 0;
  5.     CAN_Peli_FilterInitStruct->CAN_FilterId2 = 0;
  6.     CAN_Peli_FilterInitStruct->CAN_FilterId3 = 0;

  7.     CAN_Peli_FilterInitStruct->CAN_FilterMaskId0 = 0;
  8.     CAN_Peli_FilterInitStruct->CAN_FilterMaskId1 = 0;
  9.     CAN_Peli_FilterInitStruct->CAN_FilterMaskId2 = 0;
  10.     CAN_Peli_FilterInitStruct->CAN_FilterMaskId3 = 0;
  11. }


 楼主| stm32jy 发表于 2020-4-19 20:27 | 显示全部楼层
CAN Peli模式传输数据
  1. void CAN_Peli_Transmit(CanPeliTxMsg* PeliTxMessage)
  2. {
  3.     CAN1_PELI->FF = (PeliTxMessage->FF << 7) | (PeliTxMessage->RTR << 6) | (PeliTxMessage->DLC);
  4.     if (((FunctionalState)PeliTxMessage->FF) != ENABLE) {
  5.         CAN1_PELI->ID0 = (PeliTxMessage->IDHH);
  6.         // CAN1_PELI->ID1 = ((PeliTxMessage->IDHL)<<5);
  7.         CAN1_PELI->ID1 = (PeliTxMessage->IDHL & 0xE0);
  8.         if ((FunctionalState)(PeliTxMessage->RTR) != ENABLE) {
  9.             CAN1_PELI->DATA0 = PeliTxMessage->Data[0];
  10.             CAN1_PELI->DATA1 = PeliTxMessage->Data[1];
  11.             CAN1_PELI->DATA2 = PeliTxMessage->Data[2];
  12.             CAN1_PELI->DATA3 = PeliTxMessage->Data[3];
  13.             CAN1_PELI->DATA4 = PeliTxMessage->Data[4];
  14.             CAN1_PELI->DATA5 = PeliTxMessage->Data[5];
  15.             CAN1_PELI->DATA6 = PeliTxMessage->Data[6];
  16.             CAN1_PELI->DATA7 = PeliTxMessage->Data[7];
  17.         }
  18.     }
  19.     else {
  20.         CAN1_PELI->ID0   = PeliTxMessage->IDHH;
  21.         CAN1_PELI->ID1   = PeliTxMessage->IDHL;
  22.         CAN1_PELI->DATA0 = PeliTxMessage->IDLH;
  23.         CAN1_PELI->DATA1 = PeliTxMessage->IDLL;
  24.         if ((FunctionalState)(PeliTxMessage->RTR) != ENABLE) {
  25.             CAN1_PELI->DATA2 = PeliTxMessage->Data[0];
  26.             CAN1_PELI->DATA3 = PeliTxMessage->Data[1];
  27.             CAN1_PELI->DATA4 = PeliTxMessage->Data[2];
  28.             CAN1_PELI->DATA5 = PeliTxMessage->Data[3];
  29.             CAN1_PELI->DATA6 = PeliTxMessage->Data[4];
  30.             CAN1_PELI->DATA7 = PeliTxMessage->Data[5];
  31.             CAN1_PELI->DATA8 = PeliTxMessage->Data[6];
  32.             CAN1_PELI->DATA9 = PeliTxMessage->Data[7];
  33.         }
  34.     }

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


 楼主| stm32jy 发表于 2020-4-19 20:29 | 显示全部楼层
CAN Peli 模式接收函数

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

  7.     if (((FunctionalState)PeliRxMessage->FF) != ENABLE) {
  8.         tempid = (u32)(CAN1_PELI->ID1 >> 5);
  9.         tempid |= (u32)(CAN1_PELI->ID0 << 3);
  10.         PeliRxMessage->ID      = tempid;
  11.         PeliRxMessage->Data[0] = CAN1_PELI->DATA0;
  12.         PeliRxMessage->Data[1] = CAN1_PELI->DATA1;
  13.         PeliRxMessage->Data[2] = CAN1_PELI->DATA2;
  14.         PeliRxMessage->Data[3] = CAN1_PELI->DATA3;
  15.         PeliRxMessage->Data[4] = CAN1_PELI->DATA4;
  16.         PeliRxMessage->Data[5] = CAN1_PELI->DATA5;
  17.         PeliRxMessage->Data[6] = CAN1_PELI->DATA6;
  18.         PeliRxMessage->Data[7] = CAN1_PELI->DATA7;
  19.     }
  20.     else {
  21.         tempid = (u32)((CAN1_PELI->DATA1 & 0xf8) >> 3);
  22.         tempid |= (u32)(CAN1_PELI->DATA0 << 5);
  23.         tempid |= (u32)(CAN1_PELI->ID1 << 13);
  24.         tempid |= (u32)(CAN1_PELI->ID0 << 21);
  25.         PeliRxMessage->ID      = tempid;
  26.         PeliRxMessage->Data[0] = CAN1_PELI->DATA2;
  27.         PeliRxMessage->Data[1] = CAN1_PELI->DATA3;
  28.         PeliRxMessage->Data[2] = CAN1_PELI->DATA4;
  29.         PeliRxMessage->Data[3] = CAN1_PELI->DATA5;
  30.         PeliRxMessage->Data[4] = CAN1_PELI->DATA6;
  31.         PeliRxMessage->Data[5] = CAN1_PELI->DATA7;
  32.         PeliRxMessage->Data[6] = CAN1_PELI->DATA8;
  33.         PeliRxMessage->Data[7] = CAN1_PELI->DATA9;
  34.     }
  35.     CAN_FIFORelease(CAN1);
  36. }


 楼主| stm32jy 发表于 2020-4-19 20:30 | 显示全部楼层
自动初始化CAN波特率
  1. void CAN_AutoCfg_BaudParam(CAN_Peli_InitTypeDef* pInitStruct, u32 SrcClk, u32 baud)
  2. {
  3.     u32 i, value = baud, record = 1;
  4.     u32 remain = 0, sumPrescaler = 0;
  5.     while ((baud == 0) || (SrcClk == 0))
  6.         ;
  7.     sumPrescaler = SrcClk / baud;
  8.     sumPrescaler = sumPrescaler / 2;
  9.     for (i = 25; i > 3; i--) {
  10.         remain = sumPrescaler - ((sumPrescaler / i) * i);
  11.         if (remain == 0) {
  12.             record = i;
  13.             break;
  14.         }
  15.         else {
  16.             if (remain < value) {
  17.                 value  = remain;
  18.                 record = i;
  19.             }
  20.         }
  21.     }
  22.     pInitStruct->SJW   = 0;
  23.     pInitStruct->BRP   = (sumPrescaler / record) - 1;
  24.     pInitStruct->TESG2 = (record - 3) / 3;
  25.     pInitStruct->TESG1 = (record - 3) - pInitStruct->TESG2;
  26. }


caizhiwei 发表于 2020-4-23 12:48 | 显示全部楼层
有完整的工程吗?贴一份呗,谢了
coslight 发表于 2020-4-23 13:21 | 显示全部楼层
请问楼主,这个测试遇到问题,请指点一下
caizhiwei 发表于 2020-4-26 12:46 | 显示全部楼层
你这是把历程复制了一遍~
复制出来啥都没说,有问题嘛还是?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

1118

帖子

4

粉丝
快速回复 返回顶部 返回列表