增加can id配置保存到flash,can输出数据,as5600接口适配

This commit is contained in:
shen 2026-02-03 17:49:58 +08:00
parent 2a98156ef9
commit c498259444
24 changed files with 2809 additions and 80 deletions

File diff suppressed because one or more lines are too long

52
Core/Inc/dma.h Normal file
View File

@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */

View File

@ -55,6 +55,9 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA1_Channel5_IRQHandler(void);
void CAN1_RX0_IRQHandler(void);
void USART1_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

View File

@ -83,6 +83,9 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
@ -106,6 +109,8 @@ void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */

55
Core/Src/dma.c Normal file
View File

@ -0,0 +1,55 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

View File

@ -92,10 +92,10 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C2 GPIO Configuration
PB10 ------> I2C2_SCL
PB11 ------> I2C2_SDA
PB13 ------> I2C2_SCL
PB14 ------> I2C2_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
@ -122,12 +122,12 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
__HAL_RCC_I2C2_CLK_DISABLE();
/**I2C2 GPIO Configuration
PB10 ------> I2C2_SCL
PB11 ------> I2C2_SDA
PB13 ------> I2C2_SCL
PB14 ------> I2C2_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_14);
/* USER CODE BEGIN I2C2_MspDeInit 1 */

View File

@ -19,13 +19,19 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "dma.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "AS5600.h"
#include "log.h"
#include <stdint.h>
#include "can_node.h"
#include "cmd.h"
#include "flash.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -57,7 +63,15 @@ void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t can_checksum_calculate(uint8_t *data, uint8_t length)
{
uint8_t sum = 0;
for (uint8_t i = 0; i < length; i++)
{
sum += data[i];
}
return sum & 0xff;
}
/* USER CODE END 0 */
/**
@ -68,7 +82,9 @@ int main(void)
{
/* USER CODE BEGIN 1 */
int status = -1;
uint16_t angle = 0;
FlashConfig_t *flashConfig = NULL;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
@ -89,17 +105,63 @@ int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_CAN1_Init();
MX_I2C2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
can_node_init();
init_cmd();
flashConfig = Flash_ReadConfig();
_dbg_printf("Current CAN ID: 0x%02X\r\n", flashConfig->can_id);
status = -1;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
switch (status)
{
case -1:
if (AS5600_Init() == 0)
{
status = 0;
}
else
{
status = -1;
// _dbg_printf("AS5600 Initialization Failed!\r\n");
HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
HAL_Delay(100);
}
break;
case 0:
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
angle = AS5600_GetAngle();
// _dbg_printf("Angle: %d\r\n", angle);
HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
HAL_Delay(100);
status = 1;
break;
case 1:
{
uint8_t canData[8] = {0};
canData[0] = 0xAA; // 头
canData[1] = flashConfig->can_id; // canID
canData[2] = (angle >> 8) & 0xFF;
canData[3] = angle & 0xFF;
canData[4] = 0x00; // 保留
canData[5] = 0x00; // 保留
canData[6] = 0x00; // 保留
canData[7] = can_checksum_calculate(canData, 7);
can_node_transmit(flashConfig->can_id, canData);
// _dbg_printf("CAN Message send done checksum: %d\n", canData[7]);
status = 0;
}
default:
break;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */

View File

@ -22,6 +22,7 @@
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmd.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -55,7 +56,9 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan1;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -198,6 +201,50 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32l4xx.s). */
/******************************************************************************/
/**
* @brief This function handles DMA1 channel5 global interrupt.
*/
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
/* USER CODE END DMA1_Channel5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
/* USER CODE END DMA1_Channel5_IRQn 1 */
}
/**
* @brief This function handles CAN1 RX0 interrupt.
*/
void CAN1_RX0_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_RX0_IRQn 0 */
/* USER CODE END CAN1_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan1);
/* USER CODE BEGIN CAN1_RX0_IRQn 1 */
/* USER CODE END CAN1_RX0_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
usart_irq_dma_process(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -25,6 +25,7 @@
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
/* USART1 init function */
@ -88,11 +89,32 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Request = DMA_REQUEST_2;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
@ -116,6 +138,11 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
<events>
</events>
</component_viewer>

File diff suppressed because one or more lines are too long

View File

@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf>
<nTsel>6</nTsel>
<nTsel>3</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
@ -114,9 +114,34 @@
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile></tIfile>
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
<pMon>BIN\CMSIS_AGDI.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>CMSIS_AGDI</Key>
<Name>-X"Any" -UAny -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC8000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L431CCUx$CMSIS\Flash\STM32L4xx_256.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
@ -203,7 +228,7 @@
<Group>
<GroupName>Application/User/Core</GroupName>
<tvExp>0</tvExp>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@ -250,6 +275,18 @@
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Core/Src/dma.c</PathWithFileName>
<FilenameWithoutPath>dma.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Core/Src/i2c.c</PathWithFileName>
<FilenameWithoutPath>i2c.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
@ -257,7 +294,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -269,7 +306,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>7</FileNumber>
<FileNumber>8</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -281,7 +318,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>8</FileNumber>
<FileNumber>9</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -301,7 +338,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>9</FileNumber>
<FileNumber>10</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -313,7 +350,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>10</FileNumber>
<FileNumber>11</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -325,7 +362,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>11</FileNumber>
<FileNumber>12</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -337,7 +374,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>12</FileNumber>
<FileNumber>13</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -349,7 +386,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber>
<FileNumber>14</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -361,7 +398,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber>
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -373,7 +410,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber>
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -385,7 +422,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber>
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -397,7 +434,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber>
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -409,7 +446,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber>
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -421,7 +458,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber>
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -433,7 +470,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -445,7 +482,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -457,7 +494,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -469,7 +506,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -481,7 +518,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -493,7 +530,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -505,7 +542,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>26</FileNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -525,7 +562,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>27</FileNumber>
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -537,6 +574,74 @@
</File>
</Group>
<Group>
<GroupName>devices</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\devices\AS5600.c</PathWithFileName>
<FilenameWithoutPath>AS5600.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\devices\log.c</PathWithFileName>
<FilenameWithoutPath>log.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\devices\can_node.c</PathWithFileName>
<FilenameWithoutPath>can_node.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\devices\cmd.c</PathWithFileName>
<FilenameWithoutPath>cmd.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\devices\flash.c</PathWithFileName>
<FilenameWithoutPath>flash.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
<tvExp>0</tvExp>

View File

@ -10,6 +10,7 @@
<TargetName>arm_joint_sensor</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5050106::V5.05 update 1 (build 106)::.\ARMCC</pCCUsed>
<uAC6>0</uAC6>
<TargetOption>
<TargetCommonOption>
@ -339,7 +340,7 @@
<MiscControls></MiscControls>
<Define>USE_HAL_DRIVER,STM32L431xx</Define>
<Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32L4xx/Include;../Drivers/CMSIS/Include</IncludePath>
<IncludePath>../Core/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc;../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32L4xx/Include;../Drivers/CMSIS/Include;../devices</IncludePath>
</VariousControls>
</Cads>
<Aads>
@ -408,6 +409,62 @@
<FileType>1</FileType>
<FilePath>../Core/Src/can.c</FilePath>
</File>
<File>
<FileName>dma.c</FileName>
<FileType>1</FileType>
<FilePath>../Core/Src/dma.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>i2c.c</FileName>
<FileType>1</FileType>
@ -535,6 +592,36 @@
</File>
</Files>
</Group>
<Group>
<GroupName>devices</GroupName>
<Files>
<File>
<FileName>AS5600.c</FileName>
<FileType>1</FileType>
<FilePath>..\devices\AS5600.c</FilePath>
</File>
<File>
<FileName>log.c</FileName>
<FileType>1</FileType>
<FilePath>..\devices\log.c</FilePath>
</File>
<File>
<FileName>can_node.c</FileName>
<FileType>1</FileType>
<FilePath>..\devices\can_node.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\devices\cmd.c</FilePath>
</File>
<File>
<FileName>flash.c</FileName>
<FileType>1</FileType>
<FilePath>..\devices\flash.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>::CMSIS</GroupName>
</Group>
@ -555,4 +642,13 @@
<files/>
</RTE>
<LayerInfo>
<Layers>
<Layer>
<LayName>arm_joint_sensor</LayName>
<LayPrjMark>1</LayPrjMark>
</Layer>
</Layers>
</LayerInfo>
</Project>

View File

@ -8,6 +8,17 @@ CAN1.CalculateTimeBit=1000
CAN1.CalculateTimeQuantum=250.0
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,Prescaler,BS1
CAN1.Prescaler=20
Dma.Request0=USART1_RX
Dma.RequestsNb=1
Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.0.Instance=DMA1_Channel5
Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.0.Mode=DMA_NORMAL
Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW
Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
File.Version=6
GPIO.groupedBy=Group By Peripherals
I2C2.IPParameters=Timing
@ -16,12 +27,13 @@ KeepUserPlacement=false
Mcu.CPN=STM32L431CCU6
Mcu.Family=STM32L4
Mcu.IP0=CAN1
Mcu.IP1=I2C2
Mcu.IP2=NVIC
Mcu.IP3=RCC
Mcu.IP4=SYS
Mcu.IP5=USART1
Mcu.IPNb=6
Mcu.IP1=DMA
Mcu.IP2=I2C2
Mcu.IP3=NVIC
Mcu.IP4=RCC
Mcu.IP5=SYS
Mcu.IP6=USART1
Mcu.IPNb=7
Mcu.Name=STM32L431C(B-C)Ux
Mcu.Package=UFQFPN48
Mcu.Pin0=PH0-OSC_IN (PH0)
@ -31,8 +43,8 @@ Mcu.Pin11=PB5
Mcu.Pin12=PB8
Mcu.Pin13=PB9
Mcu.Pin14=VP_SYS_VS_Systick
Mcu.Pin2=PB10
Mcu.Pin3=PB11
Mcu.Pin2=PB13
Mcu.Pin3=PB14
Mcu.Pin4=PA9
Mcu.Pin5=PA10
Mcu.Pin6=PA13 (JTMS-SWDIO)
@ -46,6 +58,8 @@ Mcu.UserName=STM32L431CCUx
MxCube.Version=6.16.1
MxDb.Version=DB.6.0.161
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.CAN1_RX0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@ -55,7 +69,10 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA10.GPIOParameters=GPIO_PuPd
PA10.GPIO_PuPd=GPIO_PULLUP
PA10.Locked=true
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
@ -69,13 +86,17 @@ PA15\ (JTDI).GPIO_PuPd=GPIO_PULLUP
PA15\ (JTDI).Locked=true
PA15\ (JTDI).PinState=GPIO_PIN_SET
PA15\ (JTDI).Signal=GPIO_Output
PA9.GPIOParameters=GPIO_PuPd
PA9.GPIO_PuPd=GPIO_PULLUP
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB10.Mode=I2C
PB10.Signal=I2C2_SCL
PB11.Mode=I2C
PB11.Signal=I2C2_SDA
PB13.Locked=true
PB13.Mode=I2C
PB13.Signal=I2C2_SCL
PB14.Locked=true
PB14.Mode=I2C
PB14.Signal=I2C2_SDA
PB3\ (JTDO-TRACESWO).GPIOParameters=PinState,GPIO_PuPd,GPIO_Label
PB3\ (JTDO-TRACESWO).GPIO_Label=LED_R
PB3\ (JTDO-TRACESWO).GPIO_PuPd=GPIO_PULLUP
@ -137,7 +158,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_CAN1_Init-CAN1-false-HAL-true,4-MX_I2C2_Init-I2C2-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_CAN1_Init-CAN1-false-HAL-true,5-MX_I2C2_Init-I2C2-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true
RCC.ADCFreq_Value=32000000
RCC.AHBFreq_Value=80000000
RCC.APB1Freq_Value=80000000

138
devices/AS5600.c Normal file
View File

@ -0,0 +1,138 @@
#include "AS5600.h"
#include "i2c.h"
#include "main.h"
#include <stdint.h>
#include "log.h"
#define AS5600_ADDRESS 0x36 << 1 // AS5600的I2C从机地址左移1位
#define AS5600_REG_ZPOS_H 0x01 // 起始位置11-8
#define AS5600_REG_ZPOS_L 0x02 // 起始位置7-0
#define AS5600_REG_MPOS_H 0x03 // 终止位置11-8
#define AS5600_REG_MPOS_L 0x04 // 终止位置7-0
#define AS5600_REG_MANG_H 0x05 // 最大角度11-8
#define AS5600_REG_MANG_L 0x06 // 最大角度7-0
#define AS5600_REG_CFG_1 0x07 // CONF高位寄存器
#define AS5600_REG_CFG_2 0x08 // CONF低位寄存器
#define AS5600_REG_RAW_ANGLE_H 0x0C // 原始角度11-8(读)
#define AS5600_REG_RAW_ANGLE_L 0x0D // 原始角度7-0(读)
#define AS5600_REG_ANGLE_H 0x0E // 角度11-8(读)
#define AS5600_REG_ANGLE_L 0x0F // 角度7-0(读)
#define AS5600_REG_STATUS 0x0B // 状态寄存器(读)
#define AS5600_REG_AGC 0x1A // AGC寄存器(读)
#define AS5600_REG_MAGNITUDE_1 0x1B // MAGNITUDE寄存器(读)
#define AS5600_REG_MAGNITUDE_2 0x1C // MAGNITUDE寄存器(读)
/*
* AS5600初始化
*/
int AS5600_Init(void)
{
int ret = -1;
ret = AS5600_CheckMagnet();
if (ret == 0)
{
// _dbg_printf("AS5600 Init Error: Magnet not detected!\r\n");
return -1; // 磁体异常,返回错误
}
return 0;
}
/*
* AS5600写寄存器
* RegAddress
* Data
*/
void AS5600_WriteReg(uint8_t RegAddress, uint8_t Data)
{
HAL_I2C_Mem_Write(&hi2c2, AS5600_ADDRESS, RegAddress, I2C_MEMADD_SIZE_8BIT, &Data, 1, 1000);
}
/*
* AS5600读寄存器
* RegAddress
*
*/
uint8_t AS5600_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
HAL_I2C_Mem_Read(&hi2c2, AS5600_ADDRESS, RegAddress, I2C_MEMADD_SIZE_8BIT, &Data, 1, 1000);
return Data;
}
/*
* AS5600获取原始角度
*
* 120-4095
*/
uint16_t AS5600_GetRawAngle(void)
{
uint8_t AngleH, AngleL;
uint16_t RawAngle;
// 读取角度高位寄存器0x0E
AngleH = AS5600_ReadReg(AS5600_REG_ANGLE_H);
// 读取角度低位寄存器0x0F
AngleL = AS5600_ReadReg(AS5600_REG_ANGLE_L);
// 组合12位角度值高4位 + 低8位
RawAngle = ((uint16_t)(AngleH & 0x0F) << 8) | AngleL;
return RawAngle;
}
/**
* AS5600获取状态
*
*
* bit5(MD)=1
*/
uint8_t AS5600_GetStatus(void)
{
return AS5600_ReadReg(AS5600_REG_STATUS);
}
/**
* AS5600获取AGC值
*
* AGC值0-255
* 100-150
*/
uint8_t AS5600_GetAGC(void)
{
return AS5600_ReadReg(AS5600_REG_AGC);
}
/**
* AS5600获取处理后的角度
*
* 120-4095
*
*/
uint16_t AS5600_GetAngle(void)
{
uint8_t AngleH, AngleL;
uint16_t Angle;
// 读取角度高位寄存器0x0E
AngleH = AS5600_ReadReg(AS5600_REG_ANGLE_H);
// 读取角度低位寄存器0x0F
AngleL = AS5600_ReadReg(AS5600_REG_ANGLE_L);
// 组合12位角度值高4位 + 低8位
Angle = ((uint16_t)(AngleH & 0x0F) << 8) | AngleL;
return Angle;
}
/**
* AS5600检查磁体状态
*
* 1-0-
*/
uint8_t AS5600_CheckMagnet(void)
{
uint8_t status = AS5600_GetStatus();
// 检查状态寄存器的bit5(MD)
return (status & 0x20) ? 1 : 0;
}

13
devices/AS5600.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _AS5600_H_
#define _AS5600_H_
#include <stdint.h>
int AS5600_Init(void);
uint16_t AS5600_GetRawAngle(void);
uint8_t AS5600_GetStatus(void);
uint8_t AS5600_GetAGC(void);
uint16_t AS5600_GetAngle(void);
uint8_t AS5600_CheckMagnet(void);
#endif /* _AS5600_H_ */

80
devices/can_node.c Normal file
View File

@ -0,0 +1,80 @@
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "can.h"
#include "log.h"
#include "can_node.h"
CAN_RxHeaderTypeDef can1RxHeader; // FDCAN1 接收头
uint8_t can1RxData[8]; // FDCAN1 接收数据
void can_node_init(void)
{
CAN_FilterTypeDef filter;
// 设置接收过滤器
filter.FilterBank = 0;
filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_32BIT;
// 全部接收
filter.FilterIdHigh = 0x0000;
filter.FilterIdLow = 0x0000;
filter.FilterMaskIdHigh = 0x0000;
filter.FilterMaskIdLow = 0x0000;
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan1, &filter) != HAL_OK)
{
Error_Handler();
}
// 启动 CAN1
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
// 启动接收
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
HAL_Delay(5);
_dbg_printf("CAN1 initialized successfully\r\n");
}
void can_node_transmit(uint32_t canID, uint8_t *TxData)
{
CAN_TxHeaderTypeDef txHeader;
uint32_t txMailbox;
txHeader.StdId = canID;
txHeader.ExtId = 0;
txHeader.IDE = CAN_ID_STD;
txHeader.RTR = CAN_RTR_DATA;
txHeader.DLC = 8;
txHeader.TransmitGlobalTime = DISABLE;
// 等待邮箱空闲
while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0)
{
};
HAL_CAN_AddTxMessage(&hcan1, &txHeader, TxData, &txMailbox);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1RxHeader, can1RxData);
if (can1RxHeader.IDE == CAN_ID_STD)
{
// 示例:收到 ID = 0x123
if (can1RxHeader.StdId == 0x123)
{
// 处理数据
// can1RxData[0..can1RxHeader.DLC-1]
}
}
}

10
devices/can_node.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _CAN_NODE_H_
#define _CAN_NODE_H_
#include <stdint.h>
void can_node_init(void);
void can_node_transmit(uint32_t canID, uint8_t *TxData);
#endif /* _CAN_NODE_H_ */

83
devices/cmd.c Normal file
View File

@ -0,0 +1,83 @@
#include "usart.h"
#include <string.h>
#include "cmd.h"
#include "log.h"
#include "main.h"
#include "dma.h"
#include <stdint.h>
#include "stm32l4xx_hal_uart.h"
#include "flash.h"
#include <stdio.h>
uint8_t cmdData[32];
uint8_t uart1len = 0;
extern DMA_HandleTypeDef hdma_usart1_rx;
FlashConfig_t *currentConfig;
void UART_CommandHandler(char *data, uint16_t len)
{
data[len] = '\0'; // 确保字符串结束
if (strncmp(data, "SETID", 5) == 0)
{
uint8_t id;
if (sscanf(data + 5, "%x", &id) == 1)
{
currentConfig = Flash_ReadConfig();
if(currentConfig->can_id != id)
{
_dbg_printf("Current ID: 0x%02X, New ID: 0x%02X\n", currentConfig->can_id, id);
currentConfig->can_id = id;
currentConfig->crc = id ^ 0xFF; // 简单校验
Flash_WriteConfig(currentConfig);
}
else
{
_dbg_printf("CAN ID unchanged: 0x%02X\n", id);
}
}
}
}
void init_cmd(void)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
HAL_UART_Receive_DMA(&huart1, cmdData, sizeof(cmdData));
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
HAL_UART_DMAStop(huart);
uart1len = 0;
memset(cmdData, 0, sizeof(cmdData));
HAL_UART_Receive_DMA(huart, cmdData, sizeof(cmdData));
}
}
void usart_irq_dma_process(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
HAL_UART_DMAStop(huart);
uart1len = sizeof(cmdData) - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
UART_CommandHandler((char *)cmdData, uart1len);
memset(cmdData, 0, sizeof(cmdData));
HAL_UART_Receive_DMA(huart, cmdData, sizeof(cmdData));
}
}
}

8
devices/cmd.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _CMD_H_
#define _CMD_H_
#include "main.h"
void init_cmd(void);
void usart_irq_dma_process(UART_HandleTypeDef *huart);
#endif /* _CMD_H_ */

39
devices/flash.c Normal file
View File

@ -0,0 +1,39 @@
#include "flash.h"
#include "main.h"
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#define FLASH_BASE_ADDR 0x08000000UL
// #define FLASH_PAGE_SIZE 0x800 // 2KB
#define FLASH_PAGE_NUM 128
#define FLASH_USER_PAGE (FLASH_PAGE_NUM - 1)
#define FLASH_USER_ADDR (FLASH_BASE_ADDR + FLASH_USER_PAGE * FLASH_PAGE_SIZE)
FlashConfig_t currentCfg;
FlashConfig_t *Flash_ReadConfig(void)
{
memcpy(&currentCfg, (void *)FLASH_USER_ADDR, sizeof(currentCfg));
return &currentCfg;
}
void Flash_WriteConfig(FlashConfig_t *cfg)
{
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef erase;
uint32_t page_error;
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Page = FLASH_USER_PAGE;
erase.NbPages = 1;
HAL_FLASHEx_Erase(&erase, &page_error);
uint32_t addr = FLASH_USER_ADDR;
uint64_t data = ((uint64_t)cfg->crc << 16) | cfg->can_id;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, data);
HAL_FLASH_Lock();
}

14
devices/flash.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _FLASH_H_
#define _FLASH_H_
#include <stdint.h>
typedef struct
{
uint16_t can_id;
uint16_t crc; // 可选,简单校验
} FlashConfig_t;
FlashConfig_t *Flash_ReadConfig(void);
void Flash_WriteConfig(FlashConfig_t *cfg);
#endif /* _FLASH_H_ */

23
devices/log.c Normal file
View File

@ -0,0 +1,23 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "usart.h"
#include "log.h"
#include "main.h"
static char _dbg_TXBuff[128];
void _dbg_printf(const char *format, ...)
{
uint32_t length;
va_list args;
va_start(args, format);
length = vsnprintf((char *)_dbg_TXBuff, sizeof(_dbg_TXBuff), (char *)format, args);
va_end(args);
// HAL_UART_Transmit_DMA(&huart3, (uint8_t *)_dbg_TXBuff, length);
HAL_UART_Transmit(&huart1, (uint8_t *)_dbg_TXBuff, length, 1000);
}

6
devices/log.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _LOG_H_
#define _LOG_H_
void _dbg_printf(const char *format, ...);
#endif /* _LOG_H_ */