|
我采用VL53L8CX型号TOF传感器,来做手势识别,tof传感器检测到的数据取8X8矩阵数据,分为9个区域,检测到物体在哪个区域就显示对应的图片,现在的问题是,每次识别区域后,物体已经拿走了,图像还显示之前的图片,不回到原始位置图片,tof测距距离也不清0,总是保持上一位置,下面是代码,有没有大佬知道是什么原因? / USER CODE BEGIN Header / /**
/ / USER CODE END Header / / Includes ------------------------------------------------------------------*/ include "main.h"include "usart.h"include "gpio.h"include "tof.h"include "MainFun.h"include "53l8a1_ranging_sensor.h"include <stdio.h>include <string.h>include <stdlib.h> // For srand()/rand() declarations (fixes C99 warning)/ Private includes ----------------------------------------------------------/ / USER CODE BEGIN Includes / //PA0=BIN0(bit0);PA1=BIN1(bit1);PA2=BIN2(bit2);PA3=BIN3(bit3) define POS_OUT_PORT GPIOAdefine POS_OUT_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)// Macro: Valid ranging distance range (adjust for your application) define TOF_MIN_DISTANCE 70 // Minimum valid distance (mm)define TOF_MAX_DISTANCE 200 // Maximum valid distance (mm)define MATRIX_SIZE 8 // 8x8 matrix size (easily modifiable)define Y_AXIS_THRESHOLD 2 // Y-axis trigger threshold: first row > 2 (top?bottom)define INCREASE_TOLERANCE 1 // Allow up to 1 non-increasing step (anti-jitter)define LOW_VALUE 2 // Low value thresholddefine INCREASE_CHECK_CNT 2 // Required increasing count for low value validationdefine VALUE_DIFF_THRESH 3 // Value difference threshold// 8x8 grid area definition define Y_TOP_ROW_MAX 3 // Y top 3 rows: Y1~Y3define Y_MID_ROW_MIN 4 // Y middle 2 rows: Y4~Y5define Y_MID_ROW_MAX 5define Y_BOT_ROW_MIN 6 // Y bottom 3 rows: Y6~Y8define X_LEFT_COL_MAX 3 // X left 3 columns: X1~X3define X_MID_COL_MIN 4 // X middle 2 columns: X4~X5define X_MID_COL_MAX 5define X_RIGHT_COL_MIN 6 // X right 3 columns: X6~X8define EYE_OPEN_TIME 25 // Eye open durationdefine EYE_CLOSE_TIME 6 // Eye close durationdefine CONFIRM_COUNT 2//#define WEAK_VALID_THRESHOLD 6 // ȵӐЧϱ˘ʽ //#define WEAK_EXIT_FRAME 3 // Á¬и3֡ȵӐЧÁ¢¿̇勸 // Global variables unsigned char g_ucTofBinary[MATRIX_SIZE][MATRIX_SIZE]; // Original 8x8 binarized data unsigned char g_ucTransformedMatrix[MATRIX_SIZE][MATRIX_SIZE]; // Rotate+mirror matrix unsigned char g_ucRowSum[MATRIX_SIZE]; // Y-axis sum (Top?Bottom Y1-Y8 = [0]-[7]) unsigned char g_ucColSum[MATRIX_SIZE]; // X-axis sum (Left?Right X1-X8 = [0]-[7]) unsigned char g_ucTargetY; // Target Y (1-8, Top?Bottom) unsigned char g_ucTargetX; // Target X (1-8, Left?Right) static unsigned char g_NoTarget_Count = 0; unsigned char Matrix_Has_Data(void); static unsigned int g_Blink_Timer = 0; // Blink timer static unsigned char g_Blink_Flag = 0; // Blink flag static unsigned char g_Last_Zone = 0xFF; // Last zone static unsigned char g_Zone_Confirm_Cnt = 0;// Zone repeat count //static unsigned char g_WeakValidCnt = 0; // ȵӐЧ֡¼Ɗý / USER CODE END Includes / / Private typedef -----------------------------------------------------------/ / USER CODE BEGIN PTD / RANGING_SENSOR_Capabilities_t Cap; RANGING_SENSOR_ProfileConfig_t Profile; RANGING_SENSOR_Result_t stTofDat; // Structure to store positions of maximum values (shared for row/column) typedef struct { unsigned char count; // Number of maximum value positions unsigned char index[MATRIX_SIZE]; // Indices of maximum value positions } MaxPosition_t; / USER CODE END PTD / / Private define ------------------------------------------------------------/ / USER CODE BEGIN PD / // Sensor configuration macros (avoid redefinition warnings) //#undef TIMING_BUDGET //#undef RANGING_FREQUENCY //#define TIMING_BUDGET 50 // Ranging timing budget (ms) //#define RANGING_FREQUENCY 20 // Ranging frequency (Hz) / USER CODE END PD / / USER CODE BEGIN ה¶¨ҥλփʤ³öº¯ʽ / /**
//**** // Determine zone based on target X/Y coordinates and output zone code to master via PA0~PA3 IO //**** void Show_Image_By_Pos(void) { unsigned char current_zone = 0xFF; unsigned char valid_count = 0; //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); for (unsigned char row = 0; row < MATRIX_SIZE; row++) { for (unsigned char col = 0; col < MATRIX_SIZE; col++) { if (g_ucTransformedMatrix[row][col] == 1) valid_count++; } } // ============================================================== // None Target: output code 0 (0000 on PA0-PA3) // ============================================================== if(valid_count <= 3) { // ΞĿ±꣬ʤ³ö±«0 Output_Pos_To_Master(0); g_NoTarget_Count++;
} else { // Reset all status when valid target detected g_NoTarget_Count = 0; g_Blink_Timer = 0; // if(valid_count <= WEAK_VALID_THRESHOLD) // { // g_WeakValidCnt++; // if(g_WeakValidCnt >= WEAK_EXIT_FRAME) // { // g_Last_Zone = 0xFF; // g_Zone_Confirm_Cnt = 0; // g_WeakValidCnt = 0; // } // } // else // { // g_WeakValidCnt = 0; // } } // ====================== 1. Determine X/Y zone ====================== // Row direction: up / middle / down unsigned char y_zone; if(g_ucTargetY <= Y_TOP_ROW_MAX) { y_zone = 1; // up } else if(g_ucTargetY >= Y_BOT_ROW_MIN) { y_zone = 3; // down } else { y_zone = 2; // middle } // Column direction: left / middle / right unsigned char x_zone; if(g_ucTargetX <= X_LEFT_COL_MAX) { x_zone = 1; // left } else if(g_ucTargetX >= X_RIGHT_COL_MIN) { x_zone = 3; // right } else { x_zone = 2; // middle } // ====================== 2. Assign current_zone (9 zone IDs) ====================== if(x_zone == 1 && y_zone == 1) current_zone = 1; // LeftUp ׳ɏ else if(x_zone == 1 && y_zone == 2) current_zone = 4; // Left ׳ else if(x_zone == 1 && y_zone == 3) current_zone = 7; // LeftDown ׳ς else if(x_zone == 3 && y_zone == 1) current_zone = 3; // RightUp Ӓɏ else if(x_zone == 3 && y_zone == 2) current_zone = 6; // Right Ӓ else if(x_zone == 3 && y_zone == 3) current_zone = 9; // RightDown Ӓς else if(x_zone == 2 && y_zone == 1) current_zone = 2; // MiddleUp ɏ else if(x_zone == 2 && y_zone == 3) current_zone = 8; // MiddleDown ς else current_zone = 5; // Middle ս // ====================== 3. Zone confirmation: stable 2 frames then output IO code ====================== if(current_zone == g_Last_Zone) { g_Zone_Confirm_Cnt++; if(g_Zone_Confirm_Cnt >= CONFIRM_COUNT) { // Έ¶¨2֡ºö¶ԓ¦ǸӲ±ցPA0-PA3 Output_Pos_To_Master(current_zone); } } else { // ǸӲǐ»»ʱ£¬¼ƊýƷɨ1£¬µ«ʇȧ¹û¾ɇøӲʇӒɏzone3£¬ֱ½Ӈ偣˸ if(g_Last_Zone == 3) { g_Last_Zone = current_zone; g_Zone_Confirm_Cnt = 0; // Ӓɏǐ»»Á¢¿̽⋸£¬²»Ӄµȴý¼Ɗý } else { g_Last_Zone = current_zone; g_Zone_Confirm_Cnt = 1; } } //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); } //**** // Matrix transformation: Clockwise rotation (90? + Horizontal mirror flip // Input: Original TOF matrix | Output: Transformed matrix (matches physical layout) //**** void Transform_Matrix(void) { unsigned char row, col; unsigned char tempMatrix[MATRIX_SIZE][MATRIX_SIZE]; // Step 1: Clockwise rotate 90 degrees for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { tempMatrix[row][col] = g_ucTofBinary[MATRIX_SIZE - 1 - col][row]; } } // Step 2: Horizontal mirror flip (left-right reverse) for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { g_ucTransformedMatrix[row][col] = tempMatrix[row][MATRIX_SIZE - 1 - col]; } } } //**** // Check if transformed matrix contains any valid data (any pixel = 1) //**** unsigned char Matrix_Has_Data(void) { for(unsigned char row = 0; row < MATRIX_SIZE; row++) { for(unsigned char col = 0; col < MATRIX_SIZE; col++) { if(g_ucTransformedMatrix[row][col] == 1) { return 1; // Matrix has valid data } } } return 0; // Matrix is all zeros (no object detected) } //**** // Check if Y-axis row sum shows an increasing trend from top to bottom // Return: 1 = increasing trend, 0 = no increasing trend //**** unsigned char Check_Y_Axis_Increasing(void) { unsigned char nonZeroStart = 0xFF; unsigned char decreaseCount = 0; // 1. Find first non-zero row (valid data start row) for(unsigned char i = 0; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { nonZeroStart = i; break; } } // No valid data, return 0 directly if(nonZeroStart == 0xFF) { return 0; } // 2. Check increasing trend from valid start row (allow minor tolerance) for(unsigned char i = nonZeroStart; i < MATRIX_SIZE - 1; i++) { // Current row sum < next row sum: normal increasing, skip if(g_ucRowSum[i] < g_ucRowSum[i+1]) { continue; } // Current row sum > next row sum: decrease, count +1 else if(g_ucRowSum[i] > g_ucRowSum[i+1]) { decreaseCount++; // Exceed tolerance: judge as no increasing trend if(decreaseCount > INCREASE_TOLERANCE) { return 0; } } // Equal: keep stable, no count } // Decrease count within tolerance: judge as increasing trend return 1; } //**** // Verify if rows below low-value row meet required strict increasing count // Param: startRow - low value start row | Return: 1 = pass, 0 = fail //**** unsigned char Verify_Low_Value_Increase(unsigned char startRow) { unsigned char increaseCnt = 0; unsigned char currentRow = startRow; // Start row out of range: fail directly if(startRow >= MATRIX_SIZE - 1) { return 0; } // Traverse following rows, count strict increasing times while(currentRow < MATRIX_SIZE - 1 && increaseCnt < INCREASE_CHECK_CNT) { // Strict increasing (current < next) if(g_ucRowSum[currentRow] < g_ucRowSum[currentRow + 1]) { increaseCnt++; } currentRow++; } // Pass if required increasing count reached return (increaseCnt >= INCREASE_CHECK_CNT) ? 1 : 0; } //**** // Preprocess low-value rows (value difference + next row zero check) // Param: topRow - low value start row | Return: final selected row (0-7), 0xFF = fail //**** unsigned char Preprocess_Low_Value_Row(unsigned char topRow) { // 1. Check if next row is 0 (no subsequent data) if(topRow >= MATRIX_SIZE - 1 || g_ucRowSum[topRow + 1] == 0) { return 0xFF; // No value in next row, discard current row } // 2. Calculate difference between next row and current low value unsigned char valueDiff = g_ucRowSum[topRow + 1] - g_ucRowSum[topRow]; // 3. Difference >=3: discard current, search new valid row from next if(valueDiff >= VALUE_DIFF_THRESH) { unsigned char newTopRow = 0xFF; // Find first non-zero row from next row for(unsigned char i = topRow + 1; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { newTopRow = i; break; } } // New row still low value: recursive process; else return directly if(newTopRow != 0xFF) { if(g_ucRowSum[newTopRow] <= LOW_VALUE) { return Preprocess_Low_Value_Row(newTopRow); // Recursive process new low value row } else { return newTopRow; // Not low value: return directly } } return 0xFF; // No new valid row } // 4. Difference <3: perform secondary increasing verification else { if(Verify_Low_Value_Increase(topRow)) { return topRow; // Pass verification, keep current row } else { return 0xFF; // Fail verification, discard current row } } } //**** // Get top valid row of Y-axis under increasing trend (integrate low-value preprocess + force discard top row sum =1) // Return: valid row index (0-7), 0xFF = fail //**** unsigned char Get_Top_Y_In_Increasing(void) { unsigned char topRow = 0xFF; // 1. Find first non-zero row (valid data start row) for(unsigned char i = 0; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { topRow = i; break; } } // No valid data if(topRow == 0xFF) { return 0xFF; } // ====================== Universal anti-jitter: discard top valid row if =1 ====================== // Loop check: if current top valid row ==1, discard and continue searching downward while(topRow != 0xFF && g_ucRowSum[topRow] == 1) { // Find new valid row from next row (>0) unsigned char newTop = 0xFF; for(unsigned char i = topRow + 1; i < MATRIX_SIZE; i++) { if(g_ucRowSum[i] > 0) { newTop = i; break; } }
} // ========================================================================== // 2. Check if low value if(g_ucRowSum[topRow] <= LOW_VALUE) { // Low value row preprocess (value diff + next row 0 + secondary check) return Preprocess_Low_Value_Row(topRow); } else { return topRow; // Not low value: return directly } } //**** // Calculate up/down side sum for max position judgment (for X-axis now) // - Edge positions: double the only adjacent value // - Normal positions: sum up + down values //**** unsigned int Calc_Side_Sum(unsigned char *sumArray, unsigned char idx) { unsigned int sideSum = 0; // Edge case: first position (idx=0) if(idx == 0) { sideSum = sumArray[idx+1] 2; // Double the only adjacent value } // Edge case: last position (idx=7 for 8x8 matrix) else if(idx == MATRIX_SIZE - 1) { sideSum = sumArray[idx-1] 2; // Double the only adjacent value } // Normal case: sum up + down values else { sideSum = sumArray[idx-1] + sumArray[idx+1]; } return sideSum; } //**** // General max position finding logic (NOW FOR X-AXIS: side sum comparison) // Handles multiple max values via side sum comparison, then middle/random selection //**** unsigned char Find_Target_X_Pos_General(unsigned char *sumArray) { MaxPosition_t maxPos; unsigned char maxValue = 0; unsigned int maxSideSum = 0; unsigned char targetIdx = 0; unsigned char i; // Step 1: Find maximum value and collect all positions with this value maxPos.count = 0; // First pass: find the maximum value in the array for(i = 0; i < MATRIX_SIZE; i++) { if(sumArray[i] > maxValue) { maxValue = sumArray[i]; } } // Second pass: collect all indices that have the maximum value for(i = 0; i < MATRIX_SIZE; i++) { if(sumArray[i] == maxValue) { maxPos.index[maxPos.count++] = i; } } // If only one max value exists: return it directly if(maxPos.count == 1) { return maxPos.index[0]; } // Step 2: Multiple max values exist ? compare up/down side sums unsigned int sideSumArray[MATRIX_SIZE] = {0}; unsigned char maxSideSumCount = 0; unsigned char maxSideSumIndex[MATRIX_SIZE] = {0}; // Calculate side sum for each max position for(i = 0; i < maxPos.count; i++) { sideSumArray[i] = Calc_Side_Sum(sumArray, maxPos.index[i]);
} // If only one max side sum exists: return the corresponding index if(maxSideSumCount == 1) { targetIdx = maxPos.index[maxSideSumIndex[0]]; } // Step 3: Side sums are equal ? select middle position (or random for even count) else { // Odd count: select exact middle index if(maxPos.count % 2 == 1) { targetIdx = maxPos.index[maxPos.count / 2]; } // Even count: randomly select between the two middle indices else { static unsigned char seed = 0; seed++; srand(seed);
} return targetIdx; } //**** // Y-axis position search function (integrate all logic) // - Increasing trend detected: select top valid row (low-value preprocess) // - No increasing trend: keep original threshold logic //**** unsigned char Find_Target_Y_Pos_Threshold(unsigned char *sumArray) { unsigned char targetRow = 0xFF; // Step 1: Check if Y-axis increasing trend exists if(Check_Y_Axis_Increasing()) { // Increasing trend: try get top valid row (include low-value preprocess) targetRow = Get_Top_Y_In_Increasing(); if(targetRow != 0xFF) { return targetRow; } } // Step 2: No increasing trend / preprocess fail: use original logic (find first row above threshold) for(unsigned char row = 0; row < MATRIX_SIZE; row++) { if(sumArray[row] > Y_AXIS_THRESHOLD) { return row; // Return first qualified Y-axis index (0-7 ? Y1-Y8) } } // Step 3: No row above threshold: use general max value logic return Find_Target_X_Pos_General(sumArray); } //**** // TOF sensor initialization (hardware reset + configuration + start ranging) //**** void Tof_Device_Init(void) { unsigned char status; unsigned int Id; // Hardware reset sequence TOF_RST_HIGH; HAL_Delay(5); TOF_RST_LOW; TOF_LPN_LOW; HAL_Delay(5); TOF_LPN_HIGH; // Initialize VL53L8A1 sensor status = VL53L8A1_RANGING_SENSOR_Init(VL53L8A1_DEV_LEFT); if (status != BSP_ERROR_NONE) { //printf("VL53L8A1_Init failed (0x%02X)\r\n", status); return; } // Read sensor ID and capabilities (optional, for debugging) VL53L8A1_RANGING_SENSOR_ReadID(VL53L8A1_DEV_LEFT, &Id); VL53L8A1_RANGING_SENSOR_GetCapabilities(VL53L8A1_DEV_LEFT, &Cap); // Configure 8x8 continuous ranging mode Profile.RangingProfile = RS_PROFILE_8x8_CONTINUOUS; Profile.TimingBudget = TIMING_BUDGET; Profile.Frequency = RANGING_FREQUENCY; Profile.EnableAmbient = 0; Profile.EnableSignal = 0; VL53L8A1_RANGING_SENSOR_ConfigProfile(VL53L8A1_DEV_LEFT, &Profile); // Start continuous blocking ranging mode
// status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_LEFT, RS_MODE_BLOCKING_CONTINUOUS);
status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_LEFT, RS_MODE_ASYNC_ONESHOT); //printf("TOF Sensor Initialized Successfully!\r\n"); } //**** // Binarization: Convert raw ranging data to 0/1 matrix + apply transformation //**** void Tof_Binarization(void) { unsigned char row, col; unsigned int distance; unsigned int idx = 0; //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // Traverse all 8x8 pixels (original TOF output order) for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { // Read raw distance value (with boundary check to avoid overflow) if(idx < sizeof(stTofDat.ZoneResult)/sizeof(stTofDat.ZoneResult[0])) { distance = stTofDat.ZoneResult[idx].Distance[0]; } else { distance = 0; // Default to invalid if index out of bounds } idx++;
} // Apply matrix transformation (rotate + mirror) Transform_Matrix(); //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); } //**** // Calculate Y/X axis sums (Y: Top?Bottom Y1-Y8 = [0]-[7] | X: Left?Right X1-X8 = [0]-[7]) //**** void Tof_Calc_Target_Pos(void) { unsigned char row, col; //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 1. Calculate Y-axis sum (DIRECT mapping: Top?Bottom Y1-Y8 = g_ucRowSum[0]-[7]) memset(g_ucRowSum, 0, sizeof(g_ucRowSum)); for(row = 0; row < MATRIX_SIZE; row++) { for(col = 0; col < MATRIX_SIZE; col++) { g_ucRowSum[row] += g_ucTransformedMatrix[row][col]; } } // 2. Calculate X-axis sum (DIRECT mapping: Left?Right X1-X8 = g_ucColSum[0]-[7]) memset(g_ucColSum, 0, sizeof(g_ucColSum)); for(col = 0; col < MATRIX_SIZE; col++) { for(row = 0; row < MATRIX_SIZE; row++) { g_ucColSum[col] += g_ucTransformedMatrix[row][col]; } } // 3. Calculate target position (convert 0-7 index ? 1-8 coordinate) g_ucTargetX = 0xFF; g_ucTargetY = 0xFF; // Only calculate valid coordinates if matrix has data (any 1) if(Matrix_Has_Data()) { // X-axis: Use side sum comparison logic g_ucTargetX = Find_Target_X_Pos_General(g_ucColSum) + 1; // Y-axis: Use integrated logic g_ucTargetY = Find_Target_Y_Pos_Threshold(g_ucRowSum) + 1; } //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); } //**** // Serial port print function //**** /***** void Tof_Print_Data(void) { unsigned char row, col; unsigned char hasYOverThreshold = 0; unsigned char printYLabel; // Check if any Y-axis row sum exceeds threshold for(row = 0; row < MATRIX_SIZE; row++) { if(g_ucRowSum[row] > Y_AXIS_THRESHOLD) { hasYOverThreshold = 1; break; } } // Print header + transformed matrix printf("=====================\r\n"); // Print matrix rows with Y1-Y8 top?bottom for(row = 0; row < MATRIX_SIZE; row++) { printYLabel = row + 1; // row0=Y1, row1=Y2 ... row7=Y8 for(col = 0; col < MATRIX_SIZE; col++) { printf("%d ", g_ucTransformedMatrix[row][col]); } printf(" | Y%d Sum: %d\r\n", printYLabel, g_ucRowSum[row]); } // Print X-axis sum results printf("X-axis Sum (Side Sum Logic): "); for(col = 0; col < MATRIX_SIZE; col++) { printf("%d ", g_ucColSum[col]); } printf("\r\n"); // Print Y-axis sum results (highlight rows > threshold) printf("Y-axis Sum (Threshold=%d): ", Y_AXIS_THRESHOLD); for(row = 0; row < MATRIX_SIZE; row++) { if(g_ucRowSum[row] > Y_AXIS_THRESHOLD) { printf("[%d] ", g_ucRowSum[row]); // Highlight qualified Y rows } else { printf("%d ", g_ucRowSum[row]); } } printf("\r\n"); // Print final detection result if(!Matrix_Has_Data()) { printf("Result: No object (Empty matrix)\r\n"); } else { printf("Result: Object Position [X=%d, Y=%d]\r\n", g_ucTargetX, g_ucTargetY); } printf("=====================\r\n\r\n"); } */ //**** // Main TOF processing function (data read ? binarization ? calculation ? print) //**** void Pro_Tof_Fun(void) { unsigned char status; HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_LEFT, &stTofDat); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); Tof_Binarization(); Tof_Calc_Target_Pos(); //Tof_Print_Data(); Show_Image_By_Pos(); HAL_Delay(50); } |
STM32H750VBT6无法使用flymcu.exe或flashloader,通过串口1烧写程序
STM32H723VGT6 通过USART1/3连接CubeProgrammer失败
求助:USB 设备模式下的 UF2 更新,擦写非活动 Bank 时引起主机复位,但加 Hub 正常 —— 双 Bank 不是应该无干扰吗?
stm32h745-nucleo下不进程序,就是用programmer看,识别得到stlink,但是连不到芯片
STM32H723 ULPI接口失效
STM32H7R7的SPI DMA双缓冲怎么做。
有人用过PVD在掉电瞬间写Flash
STM32H743 配置USBOTG 使用U盘几周后 stm32无法识别usb
在STM32CubeIDE 中用sprintf,printf总感觉差点什么
STM32H743使用Keil V6(AC6)编译FreeRTOS报错__forceinline未定义及CMSIS-RTOS2配置错误,如何解决?
微信公众号
手机版