楼主: mmuuss586

[原创] 游名:Stm32F3+CA-IS3050 隔离CAN设计参考原理图/PCB图/教程/源...

  [复制链接]
  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:45:32 | 显示全部楼层
    分享到:
    按照公式计算,我们用的是1Mbps的波特率在通信,hcan.Init.Mode用来设置单片机工作模式(普通模式(CAN_MODE_NORMAL)和回环模式(CAN_MODE_LOOPBACK)等)。我们这里设置普通模式
    然后添加如下几个功能函数:
    void CAN_Filter_Init(CAN_FilterTypeDef * pFilter,
                                                                                                            uint32_t IdHigh,
                                                                                                            uint32_t IdLow,
                                                                                                            uint32_t MaskIdHigh,
                                                                                                            uint32_t MaskIdLow,
                                                                                                            uint32_t FIFOAssignment,
                                                                                                            uint32_t Bank,
                                                                                                            uint32_t Mode,
                                                                                                            uint32_t Scale,
                                                                                                            uint32_t Activation,
                                                                                                            uint32_t SlaveStartFilterBank)
    {
        pFilter->FilterIdHigh         = 0;           //32 位 ID
        pFilter->FilterIdLow          = 0;
        pFilter->FilterMaskIdHigh     = 0;             //32 位 MASK
        pFilter->FilterMaskIdLow      = 0;
        pFilter->FilterFIFOAssignment = CAN_FILTER_FIFO0;   // FIFO0
        pFilter->FilterBank           = 0;
        pFilter->FilterMode           = CAN_FILTERMODE_IDMASK;
        pFilter->FilterScale          = CAN_FILTERSCALE_32BIT;  //32 位
        pFilter->FilterActivation     = ENABLE;          // //激活过滤器 0
        pFilter->SlaveStartFilterBank = 0;
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:45:58 | 显示全部楼层
    首先是CAN过滤器的配置函数,
    /***********************CAN通信发送函数***************************/
    void CAN_TxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef * pTxHeader, uint8_t aData[], uint8_t DLC)
    {
        uint32_t Tx_MailBox;
        pTxHeader->DLC    =    DLC;
        while(HAL_CAN_AddTxMessage(hcan, pTxHeader, aData, &Tx_MailBox) != HAL_OK)
        {
            printf("TxMsg Failed!!");
                                    HAL_Delay(100);
        }
        printf("\nSend Tx Message Success!!Tx_Mail:%d", Tx_MailBox);

    }

    void User_CAN1_TxMessage(uint8_t aTxData[], uint8_t DLC)
    {
            CAN_TxMessage(&hcan, &hCAN1_TxHeader, aTxData, DLC);
    }

    /*********************** CAN启动测试函数****************************/
    void CAN_Configuration(CAN_TxHeaderTypeDef    * pTxHeader,
                                                                            CAN_FilterTypeDef     * pFilter,
                                                                            uint32_t                StdId,
                                                                            uint32_t                ExtId,
                                                                            uint32_t                IDE,
                                                                            uint32_t                RTR,
                                                                            uint32_t                DLC,
                                                                            uint32_t                IdHigh,
                                                                            uint32_t                IdLow,
                                                                            uint32_t                MaskIdHigh,
                                                                            uint32_t                MaskIdLow,
                                                                            uint32_t           FIFOAssignment,
                                                                            uint32_t                Bank,
                                                                            uint32_t                Mode,
                                                                            uint32_t                Scale,
                                                                            uint32_t                Activation,
                                                                            uint32_t         SlaveStartFilterBank)
    {
        CAN_TxHeader_Init(pTxHeader, StdId, ExtId, IDE, RTR, DLC);
       
        CAN_Filter_Init(pFilter, IdHigh, IdLow, MaskIdHigh, MaskIdLow, FIFOAssignment, Bank, Mode, Scale, Activation, SlaveStartFilterBank);
        HAL_CAN_ConfigFilter(&hcan, pFilter);
       
        while(HAL_CAN_Start(&hcan) != HAL_OK )
        {
            printf("\nCAN_Start Failed!!");
                                    HAL_Delay(100);
        }
        printf("\nCAN_Start Success!!");

        HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:46:23 | 显示全部楼层
    //启动测试函数主要为测试单片机CAN功能是否能正常启动,启动成功与否通过串口发送出来,方便我们观测,所以需要包含usart.h文件;
    配置完成后,在stm32f3xx_it.c文件中添加CAN接收中断函数,
    void CAN_RX1_IRQHandler()
    {
            HAL_CAN_RxFifo0MsgPendingCallback(&hcan);
    }
    void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    {
        uint8_t aRxData[8], i;
        if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &hCAN1_RxHeader, aRxData) == HAL_OK)
        {
            printf("\nGet Rx Message Success!!\nData:");
            for(i=0; i<8; i++)
                printf("%x ", aRxData[i]);
        }
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:46:50 | 显示全部楼层
    中断服务函数中首先用if确定是否接收到数据,若没有接收到数据直接退出,接收到则使用串口将对应数据打印;由于我们在main函数中的发送数据为16进制数据,打印也用16进制数据打印,更便于观察;
    最后为main.c文件内容
    int main(void)
    {
    uint8_t TxData[8] = {0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89};
      HAL_Init();
      SystemClock_Config();
      MX_GPIO_Init();
      MX_CAN_Init();
      MX_USART1_UART_Init();
    __HAL_CAN_ENABLE_IT(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING); //CAN中断使能函数
      User_CAN_Configuration();
      while (1)
      {
            User_CAN1_TxMessage(TxData, 8);
            HAL_Delay(1000);
      }
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:47:09 | 显示全部楼层
    在main函数中,只要是对CAN通信的中断使能,只能之后前面写的中断服务函数才能正常起作用
    实验结果:
    程序编译成功后,下载到板卡,两块板卡其中一块可以将main.c的while中的User_CAN1_TxMessage(TxData, 8);函数屏蔽掉,专门用来接收数据,另一个则每隔1秒发送一次数据,打开两个串口通信助手,就可以看到如下信息;
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-3-12 16:48:24 | 显示全部楼层
    1.png

    2.png
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-3-28 22:11 , Processed in 0.209148 second(s), 33 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.