/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
#include "adc.h"
#include "spi.h"
#include "i2c.h"
#include "24c64.h"
#include "can.h"
#include "delay.h"
#include "eeprom_iic.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint16_t ADC1_Value_DMA[8];
__IO uint32_t flag = 0;
CAN_TxHeaderTypeDef Can_Tx; //CAN发送的消息的消息头
static CAN_RxHeaderTypeDef Can_Rx; //CAN接收的消息的消息头
uint8_t Rxdata[8];//CAN接收缓冲区
uint8_t Txdata[8] = {0};//CAN发送缓冲区
/* 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 ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
CAN_HandleTypeDef hcan;
I2C_HandleTypeDef hi2c1;
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_CAN_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* Private variables **********************************************************/
static uint8_t s_vu8SysSched0Tmr = 0;
static uint8_t s_vu8SysSched1Tmr = 0;
static uint16_t s_vu16SysSched2Tmr = 0;
static uint16_t s_vu16SysSched3Tmr = 0;
static uint16_t s_vu8SysSched4Tmr = 0;
uint8_t ReceBuff[30]={0};
/* Private function **********************************************************/
/**
******************************************************************************
* @brief s_TimVarInit
* @param None
* @return None
* @note task time initialize
******************************************************************************
*/
static void s_TimVarInit(void)
{
/*---task time initialize---*/
s_vu8SysSched0Tmr = 0;
s_vu8SysSched1Tmr = 0;
s_vu16SysSched2Tmr = 0;
s_vu16SysSched3Tmr = 0;
s_vu8SysSched4Tmr = 0;
}
/**
******************************************************************************
* @brief SysTickISR
* @param None
* @return None
* @note
******************************************************************************
*/
void SysTickISR(void)
{
if (s_vu8SysSched0Tmr != 0xFF)
{
s_vu8SysSched0Tmr++;
}
if (s_vu8SysSched1Tmr != 0xFF)
{
s_vu8SysSched1Tmr++;
}
if (s_vu16SysSched2Tmr != 0xFFFF)
{
s_vu16SysSched2Tmr++;
}
if (s_vu16SysSched3Tmr != 0xFFFF)
{
s_vu16SysSched3Tmr++;
}
if (s_vu8SysSched4Tmr != 0xFF)
{
s_vu8SysSched4Tmr++;
}
}
/**
******************************************************************************
* @brief s_MainSysVarInit
* @param None
* @return None
* @note task time initialize
******************************************************************************
*/
static void s_MainSysTickCfg(void)
{
/* This example shows how to configure the SysTick to generate a time base equal to
1 ms. The system clock is set to 24 MHz on Value line devices and to 72 MHz on
other devices, the SysTick is clocked by the AHB clock (HCLK).
prm == (N.[ms] * SystemCoreClock / 1000).
*/
if (SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC))
{
/* Capture error */
while (1);
}
}
/* 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_DMA_Init();
MX_ADC1_Init();
MX_CAN_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
/* private *******************************************************************/
s_MainSysTickCfg();
s_TimVarInit();
//static uint8_t Static_Time = 0;
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC1_Value_DMA, 9);
CAN_User_Init(&hcan);
//can_init(CAN_SJW_1TQ, CAN_BS2_8TQ, CAN_BS1_9TQ, 4, CAN_MODE_NORMAL); /* CAN初始化, 环回模式, 波特率500Kbps */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* adc function *****************************************************************/
if(s_vu16SysSched2Tmr >= OS_TIMER_800MS)
{
s_vu16SysSched2Tmr = 0;
probe_adc_value();
}
/* spi function *****************************************************************/
if(s_vu8SysSched1Tmr >= OS_TIMER_250MS)
{
s_vu8SysSched1Tmr = 0;
/* can 发送数据 */
Txdata[0]=0x01;
Txdata[1]=0x02;
Txdata[2]=0x03;
Txdata[3]=0x04;
Txdata[4]=0x05;
Txdata[5]=0x06;
Txdata[6]=0x07;
Txdata[6]=0x08;
sendOrder(0x123,0,CAN_ID_STD,0,8);
//printf("%x\r\n",(SPI2_ReadWriteByte(0x55)));
}
//
// /* led function *****************************************************************/
if(s_vu16SysSched3Tmr >= OS_TIMER_1S)
{
s_vu16SysSched3Tmr = 0;
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
}
/* iic function *****************************************************************/
// if(s_vu16SysSched3Tmr >= OS_TIMER_500MS)
// {
// s_vu16SysSched3Tmr = 0;
// eeprom_iic_test();
// }
}
/* 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 RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 9;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_7;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_8;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_9;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/**
* @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 = CAN1;
hcan.Init.Prescaler = 9;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_4TQ;
hcan.Init.TimeSeg2 = CAN_BS2_3TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
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 I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/**
* @brief SPI2 Initialization Function
* @param None
* @retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_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 = 115200;
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;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
/*Configure GPIO pin : PA15 */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/** 新增 ************/
/* USER CODE BEGIN 4 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
uint8_t data[8];
HAL_StatusTypeDef status;
if (hcan1 == &hcan) {
status = HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &Can_Rx, data);
if (HAL_OK == status){
printf("--->Data Receieve!\r\n");
printf("RxMessage.StdId is %#x\r\n", Can_Rx.StdId);
printf("data[0] is 0x%02x\r\n", data[0]);
printf("data[1] is 0x%02x\r\n", data[1]);
printf("data[2] is 0x%02x\r\n", data[2]);
printf("data[3] is 0x%02x\r\n", data[3]);
printf("<---\r\n");
}
}
}
/* USER CODE END 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 */
__disable_irq();
while (1)
{
}
/* 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(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
#ifndef _CAN_H
#define _CAN_H
#include "main.h"
/******************************************************************************************/
void CAN_User_Init(CAN_HandleTypeDef* hcan );
void sendmessage(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t RTR, uint8_t DLC,float send_data);
void sendOrder(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t RTR, uint8_t DLC);
/************************************************************/
/******************************************************************************************/
/* CAN 引脚 定义 */
#define CAN_RX_GPIO_PORT GPIOA
#define CAN_RX_GPIO_PIN GPIO_PIN_11
#define CAN_RX_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
#define CAN_TX_GPIO_PORT GPIOA
#define CAN_TX_GPIO_PIN GPIO_PIN_12
#define CAN_TX_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
/* 对外接口函数 */
uint8_t can_receive_msg(uint32_t id, uint8_t *buf); /* CAN接收数据, 查询 */
uint8_t can_send_msg(uint32_t id, uint8_t *msg, uint8_t len); /* CAN发送数据 */
uint8_t can_init(uint32_t tsjw, uint32_t tbs2, uint32_t tbs1, uint16_t brp, uint32_t mode);
void CanTest(void);
uint8_t CAN1_SendNormalData(CAN_HandleTypeDef* hcan,uint16_t ID,uint8_t *pData,uint16_t Len);
#endif
#include "can.h"
#include "usart.h"
#include "string.h"
CAN_HandleTypeDef g_canx_handler; /* CANx句柄 */
CAN_TxHeaderTypeDef g_canx_txheader; /* 发送参数句柄 */
CAN_RxHeaderTypeDef g_canx_rxheader; /* 接收参数句柄 */
/************************************************************/
extern CAN_TxHeaderTypeDef Can_Tx;
extern uint8_t Txdata[8];
extern CAN_HandleTypeDef hcan;
void CAN_User_Init(CAN_HandleTypeDef* hcan ) //用户初始化函数
{
CAN_FilterTypeDef sFilterConfig;
HAL_StatusTypeDef HAL_Status;
sFilterConfig.FilterActivation = ENABLE; //激活过滤器
sFilterConfig.FilterBank = 1; //过滤器1
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //设为掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //设为32位
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //接收到的报文放入到FIFO0中
sFilterConfig.FilterIdHigh = 0; //基本ID放入到STID中// 0x000 << 5; //32位下,存储要过滤ID的高16位
sFilterConfig.FilterIdLow = 0;
sFilterConfig.FilterMaskIdHigh =0;
sFilterConfig.FilterMaskIdLow =0;
sFilterConfig.SlaveStartFilterBank = 0;
HAL_Status=HAL_CAN_ConfigFilter(hcan, &sFilterConfig);
HAL_Status=HAL_CAN_Start(hcan); //开启CAN
if(HAL_Status!=HAL_OK)
{
// printf("开启CAN失败\r\n");
}
HAL_Status=HAL_CAN_ActivateNotification(hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
if(HAL_Status!=HAL_OK)
{
//printf("开启挂起中段允许失败\r\n");
}
}
/*
发送命令函数
StdId 标准帧ID
ExtId 扩展帧ID 当标志位 IDE为CAN_ID_STD时 扩展帧无效
IDE 扩展帧标志位 CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
RTR 0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
DLC 数据长度
*/
void sendOrder(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t RTR, uint8_t DLC)
{
uint32_t pTxMailbox = 0;
Can_Tx.StdId = StdId;//标准ID
Can_Tx.ExtId = ExtId;//扩展ID
Can_Tx.IDE = IDE;//CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
Can_Tx.RTR = RTR; //0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
Can_Tx.DLC = DLC; //数据长度
HAL_CAN_AddTxMessage(&hcan,&Can_Tx,Txdata,&pTxMailbox);
}
void sendmessage(uint32_t StdId,uint32_t ExtId,uint8_t IDE,uint8_t RTR, uint8_t DLC,float send_data)
{
uint32_t pTxMailbox = 0;
Can_Tx.StdId = StdId;//标准ID
Can_Tx.ExtId = ExtId;//扩展ID
Can_Tx.IDE = IDE;//CAN_ID_STD为标准ID CAN_ID_EXT为使用扩展ID
Can_Tx.RTR = RTR; //0(CAN_RTR_DATA)为数据帧 1(CAN_RTR_REMOTE)为远程帧
Can_Tx.DLC = DLC; //数据长度
//将浮点数转化成4个字节存在tdata[4]----tdata[7]中
send_data=send_data*100;
Txdata[4] = (int)send_data&0x00ff;
Txdata[3] = (int)send_data>>8;
Txdata[1] = 0x01;
printf("TX ID:0x%X\r\n",Can_Tx.StdId);
printf("TX DATA:%02X%02X%02X%02X%02X%02X%02X%02X\r\n",Txdata[0],Txdata[1],Txdata[2],Txdata[3],Txdata[4],Txdata[5],Txdata[6],Txdata[7]);
HAL_CAN_AddTxMessage(&hcan,&Can_Tx,Txdata,&pTxMailbox);
}
/************************************************************/
/*********************************************************************/
#if 1
/**
* @brief CAN初始化
* @param tsjw : 重新同步跳跃时间单元.范围: 1~3;
* @param tbs2 : 时间段2的时间单元.范围: 1~8;
* @param tbs1 : 时间段1的时间单元.范围: 1~16;
* @param brp : 波特率分频器.范围: 1~1024;
* @note 以上4个参数, 在函数内部会减1, 所以, 任何一个参数都不能等于0
* CAN挂在APB1上面, 其输入时钟频率为 Fpclk1 = PCLK1 = 36Mhz
* tq = brp * tpclk1;
* 波特率 = Fpclk1 / ((tbs1 + tbs2 + 1) * brp);
* 我们设置 can_init(1, 8, 9, 4, 1), 则CAN波特率为:
* 36M / ((8 + 9 + 1) * 4) = 500Kbps
*
* @param mode : CAN_MODE_NORMAL, 普通模式;
CAN_MODE_LOOPBACK,回环模式;
* @retval 0, 初始化成功; 其他, 初始化失败;
*/
uint8_t can_init(uint32_t tsjw, uint32_t tbs2, uint32_t tbs1, uint16_t brp, uint32_t mode)
{
g_canx_handler.Instance = CAN1;
g_canx_handler.Init.Prescaler = brp; /* 分频系数(Fdiv)为brp+1 */
g_canx_handler.Init.Mode = mode; /* 模式设置 */
g_canx_handler.Init.SyncJumpWidth = tsjw; /* 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1TQ~CAN_SJW_4TQ */
g_canx_handler.Init.TimeSeg1 = tbs1; /* tbs1范围CAN_BS1_1TQ~CAN_BS1_16TQ */
g_canx_handler.Init.TimeSeg2 = tbs2; /* tbs2范围CAN_BS2_1TQ~CAN_BS2_8TQ */
g_canx_handler.Init.TimeTriggeredMode = DISABLE; /* 非时间触发通信模式 */
g_canx_handler.Init.AutoBusOff = DISABLE; /* 软件自动离线管理 */
g_canx_handler.Init.AutoWakeUp = DISABLE; /* 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位) */
g_canx_handler.Init.AutoRetransmission = ENABLE; /* 禁止报文自动传送 */
g_canx_handler.Init.ReceiveFifoLocked = DISABLE; /* 报文不锁定,新的覆盖旧的 */
g_canx_handler.Init.TransmitFifoPriority = DISABLE; /* 优先级由报文标识符决定 */
if (HAL_CAN_Init(&g_canx_handler) != HAL_OK)
{
return 1;
}
#if CAN_RX0_INT_ENABLE
/* 使用中断接收 */
__HAL_CAN_ENABLE_IT(&g_canx_handler, CAN_IT_RX_FIFO0_MSG_PENDING); /* FIFO0消息挂号中断允许 */
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); /* 使能CAN中断 */
HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 1, 0); /* 抢占优先级1,子优先级0 */
#endif
CAN_FilterTypeDef sFilterConfig;
/* 配置CAN过滤器 */
sFilterConfig.FilterBank = 0; /* 过滤器0 */
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000; /* 32位ID */
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000; /* 32位MASK */
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; /* 过滤器0关联到FIFO0 */
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; /* 激活滤波器0 */
sFilterConfig.SlaveStartFilterBank = 14;
/* 过滤器配置 */
if (HAL_CAN_ConfigFilter(&g_canx_handler, &sFilterConfig) != HAL_OK)
{
return 2;
}
/* 启动CAN外围设备 */
if (HAL_CAN_Start(&g_canx_handler) != HAL_OK)
{
return 3;
}
return 0;
}
/**
* @brief CAN底层驱动,引脚配置,时钟配置,中断配置
此函数会被HAL_CAN_Init()调用
* @param hcan:CAN句柄
* @retval 无
*/
//void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
//{
// if (CAN1 == hcan->Instance)
// {
// CAN_RX_GPIO_CLK_ENABLE(); /* CAN_RX脚时钟使能 */
// CAN_TX_GPIO_CLK_ENABLE(); /* CAN_TX脚时钟使能 */
// __HAL_RCC_CAN1_CLK_ENABLE(); /* 使能CAN1时钟 */
// GPIO_InitTypeDef gpio_initure;
// gpio_initure.Pin = CAN_TX_GPIO_PIN;
// gpio_initure.Mode = GPIO_MODE_AF_PP;
// gpio_initure.Pull = GPIO_PULLUP;
// gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;
// HAL_GPIO_Init(CAN_TX_GPIO_PORT, &gpio_initure); /* CAN_TX脚 模式设置 */
// gpio_initure.Pin = CAN_RX_GPIO_PIN;
// gpio_initure.Mode = GPIO_MODE_AF_INPUT;
// HAL_GPIO_Init(CAN_RX_GPIO_PORT, &gpio_initure); /* CAN_RX脚 必须设置成输入模式 */
// }
//}
#if CAN_RX0_INT_ENABLE /* 使能RX0中断 */
/**
* @brief CAN RX0 中断服务函数
* @note 处理CAN FIFO0的接收中断
* @param 无
* @retval 无
*/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
uint8_t rxbuf[8];
uint32_t id;
can_receive_msg(id, rxbuf);
printf("id:%d\r\n", g_canx_rxheader.StdId);
printf("ide:%d\r\n", g_canx_rxheader.IDE);
printf("rtr:%d\r\n", g_canx_rxheader.RTR);
printf("len:%d\r\n", g_canx_rxheader.DLC);
printf("rxbuf[0]:%d\r\n", rxbuf[0]);
printf("rxbuf[1]:%d\r\n", rxbuf[1]);
printf("rxbuf[2]:%d\r\n", rxbuf[2]);
printf("rxbuf[3]:%d\r\n", rxbuf[3]);
printf("rxbuf[4]:%d\r\n", rxbuf[4]);
printf("rxbuf[5]:%d\r\n", rxbuf[5]);
printf("rxbuf[6]:%d\r\n", rxbuf[6]);
printf("rxbuf[7]:%d\r\n", rxbuf[7]);
}
#endif
/**
* @brief CAN 发送一组数据
* @note 发送格式固定为: 标准ID, 数据帧
* @param id : 标准ID(11位)
* @retval 发送状态 0, 成功; 1, 失败;
*/
uint8_t can_send_msg(uint32_t id, uint8_t *msg, uint8_t len)
{
uint32_t TxMailbox = CAN_TX_MAILBOX0;
g_canx_txheader.StdId = id; /* 标准标识符 */
// g_canx_txheader.ExtId = id; /* 扩展标识符(29位) */
g_canx_txheader.IDE = CAN_ID_STD; /* 使用标准帧 */
g_canx_txheader.RTR = CAN_RTR_DATA; /* 数据帧 */
g_canx_txheader.DLC = len;
if (HAL_CAN_AddTxMessage(&g_canx_handler, &g_canx_txheader, msg, &TxMailbox) != HAL_OK) /* 发送消息 */
{
return 1;
}
while (HAL_CAN_GetTxMailboxesFreeLevel(&g_canx_handler) != 3); /* 等待发送完成,所有邮箱为空 */
return 0;
}
/**
* @brief CAN 接收数据查询
* @note 接收数据格式固定为: 标准ID, 数据帧
* @param id : 要查询的 标准ID(11位)
* @param buf : 数据缓存区
* @retval 接收结果
* @arg 0 , 无数据被接收到;
* @arg 其他, 接收的数据长度
*/
uint8_t can_receive_msg(uint32_t id, uint8_t *buf)
{
if (HAL_CAN_GetRxFifoFillLevel(&g_canx_handler, CAN_RX_FIFO0) == 0) /* 没有接收到数据 */
{
return 0;
}
if (HAL_CAN_GetRxMessage(&g_canx_handler, CAN_RX_FIFO0, &g_canx_rxheader, buf) != HAL_OK) /* 读取数据 */
{
return 0;
}
if (g_canx_rxheader.StdId!= id || g_canx_rxheader.IDE != CAN_ID_STD || g_canx_rxheader.RTR != CAN_RTR_DATA) /* 接收到的ID不对 / 不是标准帧 / 不是数据帧 */
{
return 0;
}
return g_canx_rxheader.DLC;
}
#endif