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

游名: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扩展软件包
关注我们
st-img 微信公众号
st-img 手机版