[STM32F0]

使用stm32f072c8做了一个基本的CAN通讯程序

[复制链接]
1251|12
手机看帖
扫描二维码
随时随地手机跟帖
hemporer|  楼主 | 2020-5-20 16:51 | 显示全部楼层 |阅读模式
本帖最后由 hemporer 于 2020-5-21 09:24 编辑

CAN通讯波特率为100K,数据位为8位
USART1的波特率为57600,N,8, 1
通过TJA1040连接到PEAK-004022
stm32f072c8每秒给PC发送一个CAN数据
PC每秒给stm32f072c8发送一个CAN数据,stm32f072c8收到CAN数据,再通过USART1发送给PC

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>© Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */


  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */



  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

                uint32_t              temp;
                uint8_t gUartData[2];
                uint8_t gUartData1[2];
                CAN_TxHeaderTypeDef gTxMessage1;
                CAN_FilterTypeDef gRxFilter;
                CAN_RxHeaderTypeDef gRxMessage1;
                uint32_t              TxMailbox;
//                uint32_t              RxMailbox = 0;
                uint8_t gTX_BUF[8]={0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0};
                uint8_t gRX_BUF[8]={0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22};

                gUartData[0] = 0x55;
                gUartData[1] = 0xAA;
                gUartData1[0] = 0x11;
                gUartData1[1] = 0x22;

                gTxMessage1.DLC = 8;
                gTxMessage1.StdId = 0x018;
                gTxMessage1.ExtId = 0x00002018;
                gTxMessage1.IDE = CAN_ID_EXT;
                gTxMessage1.RTR = CAN_RTR_DATA;
                gTxMessage1.TransmitGlobalTime = DISABLE;

                gRxMessage1.DLC = 8;
                gRxMessage1.StdId = 0x018;
                gRxMessage1.ExtId = 0x00031256;
                gRxMessage1.IDE = CAN_ID_EXT;
                gRxMessage1.RTR = CAN_RTR_DATA;
                gRxMessage1.Timestamp = 0x01;
                gRxMessage1.FilterMatchIndex = 0x01;


                gRxFilter.FilterIdHigh=0xFFFF;
                gRxFilter.FilterIdLow=0x0000;
                gRxFilter.FilterScale=CAN_FILTERSCALE_16BIT;        // CAN_FILTERSCALE_32BIT
                gRxFilter.FilterMaskIdHigh=0xFFFF;
                gRxFilter.FilterMaskIdLow=0x0000;
                gRxFilter.FilterMode=CAN_FILTERMODE_IDMASK;
                gRxFilter.FilterFIFOAssignment=CAN_RX_FIFO0;
                gRxFilter.FilterBank=13;
                gRxFilter.FilterActivation=ENABLE;

                HAL_CAN_ConfigFilter(&hcan,&gRxFilter);

                HAL_CAN_Start(&hcan);
//                HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
                HAL_Delay(1000);
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_15, GPIO_PIN_SET);

                while(1)
                {
                        if(hcan.State == HAL_CAN_STATE_RESET)
                        {
                                gUartData[0] = 0x00;
                        }
                        else if(hcan.State == HAL_CAN_STATE_READY)
                        {
                                gUartData[0] = 0x01;
                        }
                        else if(hcan.State == HAL_CAN_STATE_LISTENING)
                        {
                                gUartData[0] = 0x02;
                        }
                        else if(hcan.State == HAL_CAN_STATE_SLEEP_PENDING)
                        {
                                gUartData[0] = 0x03;
                        }
                        else if(hcan.State == HAL_CAN_STATE_SLEEP_ACTIVE)
                        {
                                gUartData[0] = 0x04;
                        }
                        else if(hcan.State == HAL_CAN_STATE_ERROR)
                        {
                                gUartData[0] = 0x05;
                        }

                        HAL_UART_Transmit(&huart1, gUartData, 2, 2);
                        if(HAL_CAN_AddTxMessage(&hcan,&gTxMessage1,gTX_BUF,&TxMailbox) != HAL_OK)
                        {
                                gUartData1[0] = 0x00;
                                HAL_UART_Transmit(&huart1, gUartData1, 1, 2);
                        }
                        if(HAL_CAN_GetRxMessage(&hcan,CAN_RX_FIFO0,&gRxMessage1,gRX_BUF) != HAL_OK)
                        {
                                gUartData1[0] = 0x11;
                                temp = HAL_CAN_GetRxFifoFillLevel(&hcan,CAN_RX_FIFO0);
                                gUartData1[0] = temp;
                                temp = HAL_CAN_GetRxFifoFillLevel(&hcan,CAN_RX_FIFO1);
                                gUartData1[1] = temp;
                                HAL_UART_Transmit(&huart1, gUartData1, 2, 2);
                        }
                        else
                        {
                                HAL_UART_Transmit(&huart1, gRX_BUF, 8, 2);
                        }

                        HAL_Delay(1000);
                }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief CAN Initialization Function
  * @param None
  * @retval None
  */
static void MX_CAN_Init(void)
{

  /* USER CODE BEGIN CAN_Init 0 */

  /* USER CODE END CAN_Init 0 */

  /* USER CODE BEGIN CAN_Init 1 */

  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN;
  hcan.Init.Prescaler = 8;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_5TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
  hcan.Init.TimeTriggeredMode = ENABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */

  /* USER CODE END CAN_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 57600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC13 PC14 PC15 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PB5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(char *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


  

使用特权

评论回复
yklstudent| | 2020-5-20 17:21 | 显示全部楼层
嗯 感谢分享

使用特权

评论回复
八层楼| | 2020-6-5 16:50 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
观海| | 2020-6-5 16:50 | 显示全部楼层
楼主调试过了吗

使用特权

评论回复
guanjiaer| | 2020-6-5 16:51 | 显示全部楼层
我曾经尝试过 但是最后放弃了

使用特权

评论回复
heimaojingzhang| | 2020-6-5 16:51 | 显示全部楼层
代码非常好 值得借鉴

使用特权

评论回复
keaibukelian| | 2020-6-5 16:51 | 显示全部楼层
能分享一下工程文件吗

使用特权

评论回复
hemporer|  楼主 | 2020-7-8 16:09 | 显示全部楼层
CAN通讯速率设置为1Mbit/s  
参考代码调试好如下

/*
* CAN_interface.c
*
*  Created on: Jun 18, 2020
*      Author:
*/

/* Includes ------------------------------------------------------------------*/
#include "defines.h"
#include "CAN_interface.h"

#if defined(PROCESSOR_TYPE_C8)

/* Module global macros ------------------------------------------------------*/

/* Module global typedefs ----------------------------------------------------*/

/* Module global variables ---------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef         hcan;
CanTxMsgTypeDef     TxMessage;
CanRxMsgTypeDef     RxMessage;

/**
  * @brief CAN Initialization Function
  * @param None
  * @detail : 1MBit/s, Extended Id, receive data from 2 ID(0x10000001 0x10010001)
  */
void CAN_Init(void)
{
        CAN_FilterConfTypeDef  CAN_FilerConf;

        hcan.Instance = CAN;
        hcan.Init.Prescaler = 2;
        hcan.Init.Mode = CAN_MODE_NORMAL;
        hcan.Init.SJW = CAN_SJW_1TQ;
        hcan.Init.BS1 = CAN_BS1_2TQ;
        hcan.Init.BS2 = CAN_BS2_1TQ;
        hcan.Init.TTCM = DISABLE;
        hcan.Init.ABOM = DISABLE;
        hcan.Init.AWUM = DISABLE;
        hcan.Init.NART = DISABLE;
        hcan.Init.RFLM = DISABLE;
        hcan.Init.TXFP = DISABLE;

        hcan.pTxMsg = &TxMessage;
        hcan.pRxMsg = &RxMessage;
        if (HAL_CAN_Init(&hcan) != HAL_OK)
        {
                Error_Handler();
        }

    CAN_FilerConf.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN_FilerConf.FilterMode = CAN_FILTERMODE_IDLIST;        // only receive data from 2 ID(0x10000001 0x10010001)
    CAN_FilerConf.FilterIdHigh = (0x10000001 << 3) >> 16;
    CAN_FilerConf.FilterIdLow = ((0x10000001 << 3) & 0xFFFF) | CAN_ID_EXT;
    CAN_FilerConf.FilterMaskIdHigh = (0x10010001 << 3) >> 16;
    CAN_FilerConf.FilterMaskIdLow = ((0x10010001 << 3) & 0xFFFF) | CAN_ID_EXT;
    CAN_FilerConf.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    CAN_FilerConf.BankNumber = 0;
    CAN_FilerConf.FilterActivation = ENABLE;
    CAN_FilerConf.FilterNumber = 0;

        if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilerConf) != HAL_OK)
        {
                Error_Handler();
        }

        /* CAN_Data_Init */
        TxMessage.StdId = 0X12;
        TxMessage.ExtId = 0x12345678;
        TxMessage.IDE = CAN_ID_EXT;
        TxMessage.RTR = CAN_RTR_DATA;
        TxMessage.DLC = 8;

        RxMessage.StdId = 0X12;
        RxMessage.ExtId = 0x12345678;
        RxMessage.IDE = CAN_ID_EXT;
        RxMessage.RTR = CAN_RTR_DATA;
        RxMessage.DLC = 8;
}

/**
  * @brief CAN process Function
  * @param None
  * @retval None
  */
void CAN_Process(void)
{
        if(GetChargerMode() < CHARGER_STATE_PRECHARGE)
        {
                gpio_can_standby_set();                        //        disable CAN communication
                return;                        //        battery is not connected, no CAN communication
        }

        if(hcan.State == HAL_CAN_STATE_ERROR)
        {
                CAN_Init();
        }

        uint8_t i;
        static uint32_t time_send_data_backup = 0;                    //  initialize CAN send data time backup

        if(TimeLeft_ms(&time_send_data_backup, 1000))
        {
                HAL_CAN_Transmit_IT(&hcan);                                                        //        heart data
                time_send_data_backup = 0;                               //  set detection time backup high to zero
        }

        if(HAL_CAN_Receive(&hcan, CAN_FIFO0, 2) == HAL_OK)
        {
                for(i=0; i<8; i++)
                {
                        TxMessage.Data = RxMessage.Data;
                }

                CAN_DataProcess();
        }
}

/**
  * @brief CAN data process Function, simple change current of CC phase
  * @param None
  * @example receive data of 0x5A 5B 12 34 00 03 E8 31
  *                 stand for 1000mA(3E8)
  *                 receive data of 0x5A 5B 12 34 00 07 D0 1D
  *                 stand for 2000mA(7D0)
  */
void CAN_DataProcess(void)
{
        uint8_t i,checksum;
        uint16_t CC_current;

        checksum = 0;
        for(i=2; i<7; i++)
        {
                checksum += RxMessage.Data;
        }
        if(checksum == RxMessage.Data[7])        //        data correct
        {
                if(GetChargerMode() == CHARGER_STATE_CHARGE_PHASE_1)        //        CC phase
                {
                        CC_current = RxMessage.Data[5] << 8;
                        CC_current += RxMessage.Data[6];
                        if(CC_current > dP.chargePhase1.I_Adjust)
                        {
                                CC_current = dP.chargePhase1.I_Adjust;
                        }
                        if(CC_current < 500)
                        {
                                CC_current = 500;
                        }
                        SetRegulationParameter(dP.chargePhase1.V_Adjust, CC_current, SET);    //  set regulation parameters with value from device parameters
                }
        }
}

#endif


使用特权

评论回复
kunge98321| | 2020-7-9 14:29 | 显示全部楼层
代码非常好 值得借鉴....

使用特权

评论回复
zhoujunfeng| | 2020-7-9 14:40 | 显示全部楼层
学习

使用特权

评论回复
lihuami| | 2020-7-10 22:45 | 显示全部楼层
CAN通讯使用隔离了吗?        

使用特权

评论回复
hemporer|  楼主 | 2020-7-14 09:42 | 显示全部楼层
lihuami 发表于 2020-7-10 22:45
CAN通讯使用隔离了吗?

使用tja1040收发器,做基本隔离

使用特权

评论回复
zxywq| | 2020-7-15 15:21 | 显示全部楼层
好东西,顶一下

使用特权

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

本版积分规则

10

主题

144

帖子

1

粉丝