你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
mmuuss586 发布时间:2020-3-12 16:30
阅读主题, 点击返回1楼
收藏 3 评论72 发布时间:2020-3-12 16:30
72个回答
mmuuss586 回答时间:2020-3-12 16:45:36
按照公式计算,我们用的是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;
}
mmuuss586 回答时间:2020-3-12 16:46:03
首先是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);
}
mmuuss586 回答时间:2020-3-12 16:46:27
//启动测试函数主要为测试单片机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]);
    }
}
mmuuss586 回答时间:2020-3-12 16:46:54
中断服务函数中首先用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);
  }
}
mmuuss586 回答时间:2020-3-12 16:47:11
在main函数中,只要是对CAN通信的中断使能,只能之后前面写的中断服务函数才能正常起作用
实验结果:
程序编译成功后,下载到板卡,两块板卡其中一块可以将main.c的while中的User_CAN1_TxMessage(TxData, 8);函数屏蔽掉,专门用来接收数据,另一个则每隔1秒发送一次数据,打开两个串口通信助手,就可以看到如下信息;
mmuuss586 回答时间:2020-3-12 16:48:46
1.png

2.png
mmuuss586 回答时间:2020-3-12 16:49:13
jeffhe1 回答时间:2020-3-13 08:41:03
學習中,謝謝
Kevin201707 回答时间:2020-3-13 10:33:41
收藏 ,多谢!
mmuuss586 回答时间:2020-3-13 12:04:18

感谢支持

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版