活动介绍

ahb ram验证和ahb gpio验证的区别

时间: 2023-05-31 15:20:21 浏览: 408
### 回答1: AHB RAM验证和AHB GPIO验证是数字电路设计中非常重要的两个方面。AHB RAM验证是检测AHB总线上的RAM中有无错误,而AHB GPIO验证是确保GPIO模块能够正确地连接到AHB总线。 AHB RAM验证的主要目的是确保RAM存储器的正常操作。在AHB系统中,RAM是存储器的最常用类型之一。AHB RAM验证可以确保RAM存储器能够正确地读取和写入数据。这种验证通常涉及到RAM的不同操作模式,例如随机访问和半随机访问,在检测到错误时,该验证可以修复错误在RAM中的位置。 AHB GPIO验证的主要目的是确保GPIO模块与AHB总线的正确连接。在一个完整的AHB系统中,GPIO模块作为输入输出端口使用。由于其重要性,可以使用GPIO模块来与外部设备进行通信,并在需要时向系统控制器发送信息。因此,确保GPIO模块通过AHB总线发送和接收信息是非常重要的。在验证期间,则需要检查所有GPIO口的访问权限和控制能力,以确保其在程序规定的时间内正常工作。 因此,AHB RAM验证和AHB GPIO验证涉及到不同的验证因素。AHB RAM验证重点是存储器的操作,而AHB GPIO验证主要关注GPIO模块在AHB总线上的连接,这些验证都是确保数据的可靠传输和存储的重要组成部分。 ### 回答2: AHB RAM验证和AHB GPIO验证都是针对AHB总线上的不同设备的验证工作。AHB RAM验证主要是验证AHB总线上的RAM存储器,而AHB GPIO验证则主要是验证GPIO(通用输入输出)设备的功能。 首先,AHB RAM验证的目标是验证随机访问存储器(RAM)的正确性。因此,该验证需要验证存储器中的读和写操作。同时,也需要测试存储器的读写时序和数据传输正确性,以确保存储器能够正常使用。 相比之下,AHB GPIO验证的目标则是验证GPIO设备的输入和输出功能是否正确。因此,该验证需要针对GPIO设备的输入和输出信号进行测试,并验证这些信号是否能正确地从GPIO设备进入和离开AHB总线。 另外,AHB RAM验证需要对存储器进行读取和写入操作,以验证存储器内部的数据传输是否正确。这需要读取已存储的数据并对比读取结果,以确保它们匹配。相比之下,AHB GPIO验证需要检测GPIO设备产生信号是否符合规范,无需进行数据匹配。 总体而言,AHB RAM验证和AHB GPIO验证是两种可以同时进行的验证,并且这两个验证方法在AHB总线设备开发过程中都非常重要。选择不同的验证方法需要根据验证的目的来确定。 ### 回答3: AHB RAM验证和AHB GPIO验证是两种不同的验证技术,AHB RAM验证主要是验证AHB总线上的RAM存储器的正常工作和存储功能是否正确,而AHB GPIO验证主要是验证GPIO模块的正常工作是否正确。 在AHB RAM验证中,验证工程师通常会使用AHB总线读写数据到RAM,然后再从RAM中读取数据进行比对。验证工程师还会验证RAM是否正确地响应读写操作,并且验证读写地址能否正确指向RAM中的正确位置。在此过程中,验证工程师还需要验证是否存在因为读写操作而导致的RAM数据异常等。 AHB GPIO验证过程中则需要验证GPIO的各种输入输出操作是否正确。验证工程师需要通过模拟各种输入输出信号或模拟GPIO端口的逻辑状态,然后验证GPIO模块能否正确地对输入/输出信号做出响应,并输出正确的信号状态。GPIO验证还需要验证GPIO模块是否能够正确地工作在不同的工作模式下,并且能否正确地响应GPIO端口与其他芯片之间的通信。 因此,AHB RAM验证和AHB GPIO验证是两个不同领域的验证技术,在验证过程中所需注意的问题和方法也不同。在验证芯片的各个模块时,验证工程师会根据实际情况选择使用适当的验证技术,以确保芯片的正常工作和稳定性。
阅读全文

相关推荐

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2023 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" #include "stdio.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 ---------------------------------------------------------*/ UART_HandleTypeDef huart1; TIM_HandleTypeDef htim6; /* USER CODE BEGIN PV */ volatile uint8_t received_data = 0; volatile uint8_t data_ready = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); static void MX_TIM6_Init(void); /* USER CODE BEGIN PFP */ void process_received_data(uint8_t data) { // ����LED��ʾ���� HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, (data & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, (data & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_2, (data & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3, (data & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET); printf("[Receiver] �յ�����: %d (0x%X)\r\n", data, data); } /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /*to redirect printf to uart with semihosting.*/ int _write(int fd, char* ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY); return len; } /* 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_USART1_UART_Init(); MX_TIM6_Init(); /* USER CODE BEGIN 2 */ printf("ReceiveReady\r\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(data_ready) { process_received_data(received_data); data_ready = 0; } HAL_Delay(10); // ����CPUռ���� } /* 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}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** 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.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 4; 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_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } /** * @brief TIM6 Initialization Function * @param None * @retval None */ static void MX_TIM6_Init(void) { /* USER CODE BEGIN TIM6_Init 0 */ /* USER CODE END TIM6_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM6_Init 1 */ /* USER CODE END TIM6_Init 1 */ htim6.Instance = TIM6; htim6.Init.Prescaler = 16 * 168 * 2 - 1; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 65535; htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM6_Init 2 */ /* USER CODE END TIM6_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 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_Initure; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pins output : PF0123 8 12(�ж�) 11(������)*/ GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_Initure.Pull = GPIO_NOPULL; GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOF, &GPIO_Initure); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_11, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_RESET); /*Configure GPIO pins : PC01234567 8 all sw */ GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; /* all sw */ GPIO_Initure.Mode = GPIO_MODE_INPUT; GPIO_Initure.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_Initure); /*Configure GPIO pin : PC11����ͨ������ */ GPIO_Initure.Pin = GPIO_PIN_8 | GPIO_PIN_11; /* key1_n && key2_n*/ GPIO_Initure.Mode = GPIO_MODE_IT_RISING; GPIO_Initure.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_Initure); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 4, 0); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); } /* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_12) { // �ж����� // ��PC0-PC3��ȡ���� received_data = 0; received_data |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) ? 0x01 : 0x00; received_data |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1) ? 0x02 : 0x00; received_data |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) ? 0x04 : 0x00; received_data |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3) ? 0x08 : 0x00; data_ready = 1; } } /* 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 */ 编译失败

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention »ùÓÚSTM32µÄÍòÄêÀú Ч¹ûÑÝʾÊÓÆµÁ´½Ó£ºhttps://www.bilibili.com/video/BV11w4m1a74J/ ÓÎϷЧ¹û¿ÉÒÔ ¹Ø×¢ ΢ÐŹ«Öںš¢BÕ¾¡¢¶¶ÒôºÍ¿ìÊÖµÈÆ½Ì¨£¨Õ˺ÅÃû³Æ£ºJLµ¥Æ¬»ú£©£¬ÓÐÂ¼ÖÆµÄÊÓÆµµÄЧ¹û¡£ Ò²·ÖÏíÁËÆäËûºÃÍæÓÐȤµÄ´úÂ룬¶¼¿ÉÒÔȥ΢ÐŹ«ÖÚºÅÏÂÔØ¡£¸ÐÐËȤµÄ¿ÉÒÔ¿´Ï¡£ ²ÄÁÏ£º STM32F103C8T6×îСϵͳ°å SSD1306 OLED128*64ÏÔʾÆÁ 6¸ö°´¼ü IO½ÓÏß˵Ã÷£º Ïòϰ´¼ü£ºPA4 ÏòÓÒ°´¼ü£ºPA5 ÏòÉϰ´¼ü£ºPB11 Ïò×ó°´¼ü£ºPB10 F1°´¼ü£ºPA6 OLED SCK£ºPA11 OLED SDA£ºPA12 * 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 "OLED.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define LEFT_BUTTON 1 #define RIGHT_BUTTON 2 #define UP_BUTTON 3 #define DOWN_BUTTON 4 #define A_BUTTON 5 #define B_BUTTON 6 /* 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 ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint32_t yr = 2024; uint8_t mo = 7; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ unsigned char isLeapYear(uint32_t yr) { if (yr % 100) return (yr % 400) == 0; else return (yr % 4) == 0; } uint8_t getDaysOfMonth(uint32_t yr, uint8_t mo) { return (mo == 2) ? (28 + isLeapYear(yr)) : 31 - (mo - 1) % 7 % 2; } uint8_t getDayOfWeek(uint32_t yr, uint8_t mo, uint8_t d) { return (d += mo < 3 ? yr-- : yr - 2, 23 * mo / 9 + d + 4 + yr / 4 - yr / 100 + yr / 400) % 7; } int get_key_input() { if(HAL_GPIO_ReadPin(left_key_GPIO_Port, left_key_Pin)==0){ HAL_Delay(100); if(HAL_GPIO_ReadPin(left_key_GPIO_Port, left_key_Pin)==0) return LEFT_BUTTON; } if(HAL_GPIO_ReadPin(right_key_GPIO_Port, right_key_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(right_key_GPIO_Port, right_key_Pin)==0) return RIGHT_BUTTON; } if(HAL_GPIO_ReadPin(up_key_GPIO_Port, up_key_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(up_key_GPIO_Port, up_key_Pin)==0) return UP_BUTTON; } if(HAL_GPIO_ReadPin(down_key_GPIO_Port, down_key_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(down_key_GPIO_Port, down_key_Pin)==0) return DOWN_BUTTON; } if(HAL_GPIO_ReadPin(f1_key_GPIO_Port, f1_key_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(f1_key_GPIO_Port, f1_key_Pin)==0) return A_BUTTON; } if(HAL_GPIO_ReadPin(f2_key_GPIO_Port, f2_key_Pin)==0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(f2_key_GPIO_Port, f2_key_Pin)==0) return B_BUTTON; } return 0; } void update() { switch (get_key_input()) { case LEFT_BUTTON: if (--yr < 1970) yr = 1970; break; case RIGHT_BUTTON: if (++yr > 2199) yr = 2199; break; case UP_BUTTON: if (++mo > 12) { if (++yr > 2199) { yr = 2199; mo = 12; } else { mo = 1; } } break; case DOWN_BUTTON: if (--mo < 1) { if (--yr < 1970) { yr = 1970; mo = 1; } else { mo = 12; } } break; case A_BUTTON: yr = 2024; mo = 7; break; case B_BUTTON: break; } } void draw() { uint8_t days = getDaysOfMonth(yr, mo); uint8_t day = getDayOfWeek(yr, mo, 1); OLED_ShowNum(40, 0, yr, 4, OLED_6X8); OLED_ShowNum(70, 0, mo, 2, OLED_6X8); OLED_ShowString(4, 8, "SU MO TU WE TH FR SA", OLED_6X8); uint8_t x = day; uint8_t y = 0; for (uint8_t i = 1; i <= days; ++i) { if (i < 10) { OLED_ShowNum(x * 18 + 4 + 6, y * 8 + 16, i, 1, OLED_6X8); } else { OLED_ShowNum(x * 18 + 4, y * 8 + 16, i, 2, OLED_6X8); } if (++x == 7) { x = 0; ++y; } } } /* 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(); /* USER CODE BEGIN 2 */ OLED_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while(get_key_input()==0); while (1) { OLED_Clear(); update(); draw(); OLED_Update(); /* 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}; /** 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(); } } /** * @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_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, scl_Pin|sda_Pin, GPIO_PIN_SET); /*Configure GPIO pins : down_key_Pin right_key_Pin f1_key_Pin f2_key_Pin */ GPIO_InitStruct.Pin = down_key_Pin|right_key_Pin|f1_key_Pin|f2_key_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : left_key_Pin up_key_Pin */ GPIO_InitStruct.Pin = left_key_Pin|up_key_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pins : scl_Pin sda_Pin */ GPIO_InitStruct.Pin = scl_Pin|sda_Pin; 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 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 */ 讲解代码

/* main.c - 主程序文件 */ #include "main.h" #include <string.h> #include <stdio.h> #include <math.h> /* 外设句柄 */ extern TIM_HandleTypeDef htim2; extern I2C_HandleTypeDef hi2c1; extern UART_HandleTypeDef huart1; // GPS extern UART_HandleTypeDef huart2; // SIM800C /* 全局变量 */ volatile uint32_t IC_Val1 = 0, IC_Val2 = 0; volatile uint32_t pulse_width = 0; volatile uint8_t is_first_captured = 0; volatile float distance_cm = 0; // 独立缓冲区 char gps_buffer[128]; uint8_t gps_index = 0; char sim800c_buffer[64]; uint8_t sim800c_index = 0; float latitude = 0.0, longitude = 0.0; uint8_t gps_fix_valid = 0; uint8_t emergency_flag = 0; const char EMERGENCY_PHONE[] = "13800138000"; // 预设紧急电话号码 /* 函数原型 */ void SystemClock_Config(void); //static void MX_GPIO_Init(void); //static void MX_TIM2_Init(void); //static void MX_USART1_UART_Init(void); //static void MX_USART2_UART_Init(void); //static void MX_I2C1_Init(void); void Trigger_Ultrasonic(void); void Ultrasonic_Process(void); void GPS_Process(void); void SIM800C_Init(void); uint8_t SIM800C_SendCommand(const char *cmd, const char *expect, uint32_t timeout); void SIM800C_Emergency_Call(void); void MPU6050_Init(void); uint8_t MPU6050_ReadAccel(int16_t *accel); uint8_t Check_Fall_Detection(void); void Parse_GPGGA(const char *ggastr); void Feedback_Distance(float dist); /* MPU6050 寄存器地址 */ #define MPU6050_ADDR 0xD0 #define MPU6050_WHO_AM_I 0x75 #define MPU6050_PWR_MGMT_1 0x6B #define MPU6050_ACCEL_CONFIG 0x1C #define MPU6050_ACCEL_XOUT_H 0x3B #ifndef M_PI #define M_PI 3.14159265358979323846 // 定义M_PI常量 #endif // 超声波超时计数器 volatile uint32_t ultrasonic_timeout = 0; int main(void) { /* HAL库初始化 */ HAL_Init(); /* 系统时钟配置 */ SystemClock_Config(); /* 外设初始化 */ MX_GPIO_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_I2C1_Init(); /* 启动外设 */ HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); // 超声波输入捕获 HAL_UART_Receive_IT(&huart1, (uint8_t*)&gps_buffer[0], 1); // GPS接收 HAL_UART_Receive_IT(&huart2, (uint8_t*)&sim800c_buffer[0], 1); // SIM800C接收 /* 模块初始化 */ MPU6050_Init(); SIM800C_Init(); /* 启用超声波超时定时器 */ HAL_TIM_Base_Start_IT(&htim2); /* 主循环 */ while (1) { /* 1. 超声波测距 */ Trigger_Ultrasonic(); Ultrasonic_Process(); /* 2. 障碍物反馈 */ if (distance_cm > 0 && distance_cm < 40) { Feedback_Distance(distance_cm); } /* 3. 摔倒检测 */ if (Check_Fall_Detection()) { emergency_flag = 1; } /* 4. 紧急按钮检测 */ if (HAL_GPIO_ReadPin(EMERGENCY_BTN_GPIO_Port, EMERGENCY_BTN_Pin) == GPIO_PIN_SET) { HAL_Delay(50); // 防抖 if (HAL_GPIO_ReadPin(EMERGENCY_BTN_GPIO_Port, EMERGENCY_BTN_Pin) == GPIO_PIN_SET) { emergency_flag = 1; } } /* 5. 处理紧急情况 */ if (emergency_flag) { SIM800C_Emergency_Call(); emergency_flag = 0; HAL_Delay(5000); // 防止重复触发 } /* 6. 空闲时延时 */ HAL_Delay(100); // 100ms循环周期 } } /* 超声波触发函数 */ void Trigger_Ultrasonic(void) { // 重置捕获状态 is_first_captured = 0; ultrasonic_timeout = 0; // 发送10μs触发脉冲 HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); HAL_Delay(0.01); // 10μs HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); } /* TIM2全局中断回调 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { // 超声波超时处理 if (is_first_captured) { ultrasonic_timeout++; if (ultrasonic_timeout > 100) { // 100ms超时 is_first_captured = 0; __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); } } } } /* TIM2输入捕获中断回调 */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { if (!is_first_captured) { // 获取第一个捕获值(上升沿) IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); is_first_captured = 1; ultrasonic_timeout = 0; // 切换为下降沿捕获 __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); } else { // 获取第二个捕获值(下降沿) IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); // 计算脉冲宽度 if (IC_Val2 > IC_Val1) { pulse_width = IC_Val2 - IC_Val1; } else { pulse_width = (0xFFFF - IC_Val1) + IC_Val2; } // 计算距离(cm) distance_cm = pulse_width * 0.034 / 2; // 重置状态 is_first_captured = 0; // 恢复为上升沿捕获 __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); __HAL_TIM_SET_COUNTER(htim, 0); } } } /* 超声波数据处理 */ void Ultrasonic_Process(void) { static float filtered_distance = 0; const float alpha = 0.3; // 滤波器系数 // 应用一阶低通滤波器 if (distance_cm > 0) { if (filtered_distance == 0) { filtered_distance = distance_cm; } else { filtered_distance = alpha * distance_cm + (1 - alpha) * filtered_distance; } } // 更新有效距离 distance_cm = filtered_distance; } /* USART接收中断回调 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { uint8_t rx_data; if (huart->Instance == USART1) { // GPS HAL_UART_Receive_IT(&huart1, &rx_data, 1); if (rx_data == '\n') { gps_buffer[gps_index] = '\0'; // 检查是否为GPGGA语句 if (strstr(gps_buffer, "$GPGGA")) { Parse_GPGGA(gps_buffer); } gps_index = 0; } else if (gps_index < sizeof(gps_buffer) - 1) { gps_buffer[gps_index++] = rx_data; } } else if (huart->Instance == USART2) { // SIM800C HAL_UART_Receive_IT(&huart2, &rx_data, 1); if (rx_data == '\n') { sim800c_buffer[sim800c_index] = '\0'; // 这里可以处理SIM800C响应 sim800c_index = 0; } else if (sim800c_index < sizeof(sim800c_buffer) - 1) { sim800c_buffer[sim800c_index++] = rx_data; } } } /* 解析GPGGA语句 (无破坏性解析) */ void Parse_GPGGA(const char *ggastr) { char buffer[128]; strncpy(buffer, ggastr, sizeof(buffer)); buffer[sizeof(buffer)-1] = '\0'; char *token = strtok(buffer, ","); uint8_t field = 0; char lat_str[16] = {0}, lon_str[16] = {0}; char ns = 'N', ew = 'E'; uint8_t fix_quality = 0; while (token != NULL && field < 15) { switch (field) { case 2: // 纬度 strncpy(lat_str, token, sizeof(lat_str)-1); break; case 3: // 北纬/南纬 ns = token[0]; break; case 4: // 经度 strncpy(lon_str, token, sizeof(lon_str)-1); break; case 5: // 东经/西经 ew = token[0]; break; case 6: // 定位质量 fix_quality = atoi(token); break; } token = strtok(NULL, ","); field++; } // 如果定位有效 if (fix_quality > 0 && lat_str[0] != '\0' && lon_str[0] != '\0') { // 解析纬度 (格式: DDMM.MMMMM) double lat_deg = atof(lat_str) / 100.0; int lat_deg_int = (int)lat_deg; double lat_min = lat_deg - lat_deg_int; latitude = lat_deg_int + (lat_min * 100.0) / 60.0; if (ns == 'S') latitude = -latitude; // 解析经度 (格式: DDDMM.MMMMM) double lon_deg = atof(lon_str) / 100.0; int lon_deg_int = (int)lon_deg; double lon_min = lon_deg - lon_deg_int; longitude = lon_deg_int + (lon_min * 100.0) / 60.0; if (ew == 'W') longitude = -longitude; gps_fix_valid = 1; } else { gps_fix_valid = 0; } } /* SIM800C初始化 */ void SIM800C_Init(void) { // 等待模块启动 HAL_Delay(2000); // 发送AT指令测试连接 SIM800C_SendCommand("AT\r\n", "OK", 1000); // 禁用命令回显 SIM800C_SendCommand("ATE0\r\n", "OK", 1000); // 设置短信文本模式 SIM800C_SendCommand("AT+CMGF=1\r\n", "OK", 1000); } /* 发送AT命令并等待响应 */ uint8_t SIM800C_SendCommand(const char *cmd, const char *expect, uint32_t timeout) { HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), timeout); uint32_t start = HAL_GetTick(); uint8_t response[128] = {0}; uint8_t index = 0; while ((HAL_GetTick() - start) < timeout) { if (HAL_UART_Receive(&huart2, &response[index], 1, 10) == HAL_OK) { if (response[index] == '\n') { if (strstr((char*)response, expect)) { return 1; // 成功 } index = 0; memset(response, 0, sizeof(response)); } else if (index < sizeof(response)-1) { index++; } } } return 0; // 超时或未找到 } /* SIM800C紧急呼叫 */ void SIM800C_Emergency_Call(void) { // 1. 拨打紧急电话 char call_cmd[32]; sprintf(call_cmd, "ATD%s;\r\n", EMERGENCY_PHONE); SIM800C_SendCommand(call_cmd, "OK", 2000); // 等待10秒通话 HAL_Delay(10000); // 挂断电话 SIM800C_SendCommand("ATH\r\n", "OK", 1000); // 2. 发送紧急短信 SIM800C_SendCommand("AT+CMGF=1\r\n", "OK", 1000); char sms_cmd[64]; sprintf(sms_cmd, "AT+CMGS=\"%s\"\r", EMERGENCY_PHONE); HAL_UART_Transmit(&huart2, (uint8_t*)sms_cmd, strlen(sms_cmd), 100); // 等待提示符 HAL_Delay(500); // 短信内容 char sms[128]; if (gps_fix_valid) { sprintf(sms, "紧急求助!位置:https://maps.google.com/?q=%.6f,%.6f", latitude, longitude); } else { strcpy(sms, "紧急求助!GPS未定位"); } HAL_UART_Transmit(&huart2, (uint8_t*)sms, strlen(sms), 1000); // 发送Ctrl+Z结束短信 uint8_t ctrl_z = 0x1A; HAL_UART_Transmit(&huart2, &ctrl_z, 1, 100); // 等待发送完成 HAL_Delay(2000); } /* MPU6050初始化 */ void MPU6050_Init(void) { uint8_t data[2]; // 唤醒MPU6050 data[0] = MPU6050_PWR_MGMT_1; data[1] = 0x01; // 使用X轴陀螺仪作为参考 HAL_I2C_Master_Transmit(&hi2c1, MPU6050_ADDR, data, 2, 100); HAL_Delay(100); // 设置加速度量程±8g data[0] = MPU6050_ACCEL_CONFIG; data[1] = 0x10; // ±8g HAL_I2C_Master_Transmit(&hi2c1, MPU6050_ADDR, data, 2, 100); HAL_Delay(100); // 验证设备ID uint8_t reg = MPU6050_WHO_AM_I; uint8_t id; HAL_I2C_Master_Transmit(&hi2c1, MPU6050_ADDR, ®, 1, 100); HAL_I2C_Master_Receive(&hi2c1, MPU6050_ADDR, &id, 1, 100); if (id != 0x68) { // 设备ID错误处理 while(1) { HAL_GPIO_TogglePin(BUZZER_GPIO_Port, BUZZER_Pin); HAL_Delay(200); } } } /* 读取加速度数据 */ uint8_t MPU6050_ReadAccel(int16_t *accel) { uint8_t buffer[6]; uint8_t reg = MPU6050_ACCEL_XOUT_H; // 发送寄存器地址 if (HAL_I2C_Master_Transmit(&hi2c1, MPU6050_ADDR, ®, 1, 10) != HAL_OK) { return 0; } // 读取6字节数据 if (HAL_I2C_Master_Receive(&hi2c1, MPU6050_ADDR, buffer, 6, 10) != HAL_OK) { return 0; } // 转换数据 accel[0] = (buffer[0] << 8) | buffer[1]; // X轴 accel[1] = (buffer[2] << 8) | buffer[3]; // Y轴 accel[2] = (buffer[4] << 8) | buffer[5]; // Z轴 return 1; } /* 检测摔倒 */ uint8_t Check_Fall_Detection(void) { static int16_t accel_history[3][5] = {0}; // 历史数据 (X,Y,Z × 5个样本) static uint8_t index = 0; static uint32_t last_check = 0; int16_t current_accel[3]; // 每200ms检查一次 if (HAL_GetTick() - last_check < 200) { return 0; } last_check = HAL_GetTick(); if (!MPU6050_ReadAccel(current_accel)) { return 0; } // 保存历史数据 accel_history[0][index] = current_accel[0]; accel_history[1][index] = current_accel[1]; accel_history[2][index] = current_accel[2]; index = (index + 1) % 5; // 计算移动平均值 int32_t avg_accel[3] = {0}; for (int i = 0; i < 5; i++) { avg_accel[0] += accel_history[0][i]; avg_accel[1] += accel_history[1][i]; avg_accel[2] += accel_history[2][i]; } avg_accel[0] /= 5; avg_accel[1] /= 5; avg_accel[2] /= 5; // 计算加速度矢量 float ax = avg_accel[0] / 4096.0; // ±8g灵敏度4096 LSB/g float ay = avg_accel[1] / 4096.0; float az = avg_accel[2] / 4096.0; float magnitude = sqrt(ax*ax + ay*ay + az*az); // 计算姿态角度 (判断是否平躺) float pitch = atan2(-ax, sqrt(ay*ay + az*az)) * 180.0 / M_PI; float roll = atan2(ay, az) * 180.0 / M_PI; // 摔倒判断条件 if ((magnitude < 0.5 || magnitude > 2.5) && // 加速度剧烈变化 (fabs(pitch) > 60 || fabs(roll) > 60)) { // 身体倾斜角度大 return 1; } return 0; } /* 距离反馈 */ void Feedback_Distance(float dist) { // 距离越近,反馈越强烈 uint16_t duration = 50; // 基础持续时间 uint16_t interval = (uint16_t)(dist * 10); // 间隔时间 // 蜂鸣器和马达同时工作 HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(VIBRATION_MOTOR_GPIO_Port, VIBRATION_MOTOR_Pin, GPIO_PIN_SET); HAL_Delay(duration); HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(VIBRATION_MOTOR_GPIO_Port, VIBRATION_MOTOR_Pin, GPIO_PIN_RESET); HAL_Delay(interval); } /* I2C错误中断回调 */ void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) { if (hi2c->Instance == I2C1) { // I2C恢复 - 重新初始化 HAL_I2C_DeInit(&hi2c1); MX_I2C1_Init(); MPU6050_Init(); } } /* 系统时钟配置函数 */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 配置主电源调节器 __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); // 初始化RCC振荡器 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } // 初始化CPU、AHB和APB总线时钟 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_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } /* 错误处理函数 */ void Error_Handler(void) { // 错误时快速闪烁LED while(1) { HAL_GPIO_TogglePin(BUZZER_GPIO_Port, BUZZER_Pin); HAL_Delay(100); } } 这是我mian.c里的代码,按图片中的引脚,基于STM32F407VET6和cubemx。装置集成hc-sr04超声波测距模块、neo6M的GPS定位模块及sim800c紧急通信模块和mpu6050。超声波模块扫描前方40厘米范围内的障碍物,通过蜂鸣器反馈距离信息;GPS模块实时获取地理位置,mpu6050检测到摔倒或者遇紧急情况时可一键触发SIM800c模块拨打预设电话并发送含经纬度的求救短信。这是我要实现功能,但是烧录后没反应,debug后发现他卡在 HAL_Init();这一步,然后我把所有外设都断开后发现他还是卡在debug这一步

int8_t SWD_test( SWD_GPIO_TypeDef *SWD_GPIO, uint32_t *data ) { int Erase_Check_Times = PER * 32 + SER * 1024 + MER * 1024*16; // 设置擦除校验次数 uint32_t Addr_Base; // 设置擦写起始位置 uint32_t busybit; // 发送50+个时钟周期 进行初始化 SET_SWDIO_OUT(); *SWD_GPIO->SWD_HIGH = SWD_GPIO->SWD_BIT; // SWD取1 for ( int i = 0; i < 60; i++ ) { *SWD_GPIO -> SWC_HIGH = SWD_GPIO -> SWC_BIT; Delayus( 2 ); // 高电平保持 *SWD_GPIO -> SWC_LOW = SWD_GPIO -> SWC_BIT; Delayus( 2 ); // 低电平保持 } *SWD_GPIO->SWD_LOW = SWD_GPIO->SWD_BIT; // SWD取1 for ( int i = 0; i < 10; i++ ) { *SWD_GPIO -> SWC_HIGH = SWD_GPIO -> SWC_BIT; Delayus( 2 ); // 高电平保持 *SWD_GPIO -> SWC_LOW = SWD_GPIO -> SWC_BIT; Delayus( 2 ); // 低电平保持 } uint32_t id = SWD_Read( SWD_GPIO, RD_DP_0 ); // 读IDCODE //DEBUG("id: 0x%11X\r\n",id); SWD_Write( SWD_GPIO, WT_DP_4, 0x50000000 ); // 使能AP寄存器 SWD_Write( SWD_GPIO, WT_DP_8, 0x000000F0 ); // 选择AP的BankF区 SWD_Read( SWD_GPIO, RD_AP_C ); // 空读AP的DRW SWD_Read( SWD_GPIO, RD_DP_C ); // 读取AP的ID SWD_Write( SWD_GPIO, WT_DP_8, 0x00000000 ); // 选择AP的Bank0区 SWD_Write( SWD_GPIO, WT_AP_0, 0x23000002 ); // 设置CPU地址的读写位宽32位 连续读写地址自增 // 擦除操作 if( MER ) { Addr_Base = 0x08000000; } else { Addr_Base = FLASH_WRITE_BASE; } //解锁FLASH_CR SWD_Write( SWD_GPIO, WT_AP_4, 0x40022008 ); // 选择FLASH_KERY地址 SWD_Write( SWD_GPIO, WT_AP_C, KEY1 ); // 输入key1 SWD_Write( SWD_GPIO, WT_AP_C, KEY2 ); // 输入key2 //配置FLASH_CR寄存器 SWD_Write( SWD_GPIO, WT_AP_4, 0x40022014 ); // 选择FLASH_CR地址 /* if( PER ) { SWD_Write( SWD_GPIO, WT_AP_C, FLASH_PER ); // PER置1 } else if( SER ) { SWD_Write( SWD_GPIO, WT_AP_C, FLASH_SER ); // SER置1 } else if( MER ) { SWD_Write( SWD_GPIO, WT_AP_C, FLASH_MER ); // MER置1 } */ SWD_Write( SWD_GPIO, WT_AP_C, FLASH_SER ); // SER置1 SWD_Write( SWD_GPIO, WT_AP_4, Addr_Base ); SWD_Write( SWD_GPIO, WT_AP_C, 0x11451419 ); //随便写 开始擦除 //等待FLASH内部操作时间 SWD_Write( SWD_GPIO, WT_AP_4, 0x40022010 ); // 查询FLASH_SR状态这些操作都可以正确执行,但是添加了下面这段代码之后重新运行,除了读idcode能执行以外,其他的指令全都无法识别while( 1 ) // 查看BSY位 { SWD_Read( SWD_GPIO, RD_AP_C ); // 空读AP的DRW busybit = SWD_Read( SWD_GPIO, RD_DP_C ); if( busybit & ( 1 << 15 ) ) { Delayus( 10 ); } else { break; } }

最新推荐

recommend-type

中孚密保卫士是由中孚信息股份有限公司开发的一款信息安全产品,主要用于终端计算机的保密管理和数据防泄漏 它主要面向政府机关、军工单位、科研院所等对信息安全有较高要求的涉密单位,帮助其实现对涉密信息的全

终端保密管理:对计算机终端的操作行为进行监控和审计,防止违规外联、非法拷贝、打印、截屏等行为。 数据防泄漏(DLP):通过内容识别、加密、权限控制等手段,防止敏感或涉密数据通过U盘、网络、邮件等途径泄露。 文件加密与权限控制:对涉密文件进行透明加密,确保文件在授权范围内使用,防止未授权人员查看或传播。 行为审计与日志记录:详细记录用户的操作行为(如文件访问、外发、打印等),便于事后追溯和审计。 违规外联监控:防止涉密计算机违规连接互联网或其他非授权网络,保障网络边界安全。 移动存储介质管理:对U盘、移动硬盘等设备进行授权管理,区分普通盘和专用盘,防止非法数据拷贝。
recommend-type

快速浏览Hacker News热门故事的浏览器扩展

Hacker News Browser-crx插件是一款专为浏览器设计的扩展程序,它允许用户从任何网页上浏览Hacker News上的热门故事,该网站是科技界尤其是编程和创业圈子中非常受欢迎的信息交流平台。Hacker News上的内容主要包括编程、科技创业、互联网趣闻以及相关的讨论。它由Y Combinator(一家知名的硅谷创业孵化器)所维护。 ### 关键知识点解析: 1. **扩展程序(Extension)**: - 扩展程序是一种软件,旨在为浏览器提供额外功能和定制选项。它们可以增强用户的浏览体验,提高效率和安全性。扩展程序通常开发于HTML、CSS和JavaScript技术栈,可以针对不同的浏览器开发,如Chrome、Firefox、Safari等。 2. **Hacker News简介**: - Hacker News(也称为Hacker News或者HN)是一个新闻社交网站,由Paul Graham和Trevor Blackwell等人于2007年发起,隶属于Y Combinator。它提供了一个平台,让用户分享、讨论技术新闻和创业公司的相关文章。Hacker News社区以其高质量的讨论和新闻而闻名,吸引了大量程序员、企业家和科技爱好者。 3. **Hacker News Browser-crx插件功能**: - **浏览过去24小时的热门故事**:插件允许用户查看Hacker News中最近24小时内的热门内容。这为用户提供了快速获取当前科技界热门话题的途径。 - **保存故事到Pocket**:Pocket是一个服务,允许用户保存文章、视频和网页以便离线阅读。Hacker News Browser-crx插件可以与用户的Pocket账户集成,方便用户保存他们感兴趣的内容到自己的Pocket列表中。 - **直接从扩展发推文**:社交媒体是现代信息传播的一个重要渠道。通过这个功能,用户可以将他们在Hacker News上的发现直接通过Twitter分享给他们的关注者。 - **搜索特定主题**:用户可以使用这个功能来搜索Hacker News上的特定主题或关键词,从而快速定位他们感兴趣的内容。 4. **如何使用Hacker News Browser-crx插件**: - 安装扩展:用户需要从浏览器的扩展商店下载并安装Hacker News Browser-crx插件。由于给定信息中提供的文件名为Hacker_News_Browser.crx,这表明这可能是一个Chrome扩展。 - 启用扩展:安装完成后,用户需要在浏览器的扩展管理界面启用该插件。 - 进行配置(可选):根据需要,用户可能需要对插件进行一些基本配置,比如设置Pocket账户等。 - 使用功能:安装并配置完成后,用户可以开始使用扩展提供的各项功能,包括浏览热门故事、保存内容到Pocket、发推文和搜索特定主题。 ### 总结: Hacker News Browser-crx插件作为一个扩展程序,为用户提供了便捷的途径去浏览和参与Hacker News上的讨论。该插件整合了多种功能,让读者能够实时关注科技动态,并与他人分享讨论。对于科技爱好者以及相关行业的专业人士,这是一个极具价值的工具,它能够帮助他们保持信息的及时更新和知识的持续吸收。
recommend-type

【MATLAB通信建模秘籍】:5个技巧让你为通信系统打下坚实基础

# 1. MATLAB通信建模基础概览 MATLAB(矩阵实验室)作为一种强大的科学计算软件,在通信系统建模和仿真领域扮演着重要角色。对于初学者而言,了解MATLAB的基础操作和通信建模的基本概念是开启深入学习之旅的第一步。 ## 1.1 MATLAB简介及其在通信领域的应用 MATLAB是一个高性能的数值计算和可视化软件,广泛应用于工程计算、算法开发、数据分析等领域。在通
recommend-type

汽车车载通讯技术

<think>我们正在讨论汽车车载通讯技术。根据之前的引用,我们知道汽车通信网络分为车内(有线)和车外(无线)两部分。同时,车载SOA架构使用多种通信技术(如CAN总线、以太网、MQTT等)来实现模块化和可扩展的通信。 用户的问题:汽车车载通讯技术原理及应用 回答结构: 1. 概述:简要介绍汽车车载通讯技术的定义和分类。 2. 原理部分:分别介绍车内网络和车外网络的主要技术原理。 2.1 车内网络:重点介绍CAN总线、LIN总线、FlexRay、MOST、Automotive Ethernet等。 2.2 车外网络:介绍V2X(包括V2V、V2I、V2P、V2N)及相
recommend-type

Dev Context Menu Utils (beta)-快速开发浏览器扩展

Dev Context Menu Utils (beta)-crx插件是一款面向开发者群体的浏览器扩展程序,其beta版本的命名暗示了它目前还在开发的早期阶段,可能尚未完全稳定或者未包含全部功能。从标题来看,这款扩展程序旨在为开发者提供便捷的上下文菜单功能。 上下文菜单(Context Menu)通常指的是当用户在软件或网页上右键点击时弹出的菜单。上下文菜单的内容根据点击的位置和对象会有所不同,它可以为用户提供快捷、针对当前情境的操作选项。在浏览器中,上下文菜单经常被用于快速访问开发者工具、页面操作、或是网页内容处理等功能。 标题中提到的“CNPJ”和“CPF”是巴西的法人和自然人的税务识别代码。CNPJ(Cadastro Nacional de Pessoas Jurídicas)是巴西所有公司和企业的全国性注册代码,而CPF(Cadastro de Pessoas Físicas)是巴西公民的个人税务识别码。在Dev Context Menu Utils (beta)中加入这两个菜单项,可能意味着插件能够让开发者在遇到需要验证或输入这些税务识别码的场景时,通过浏览器的右键菜单快速生成示例代码或进行其他相关操作。 “Lorem Ipsum”是设计和排版行业常用的一种占位文本,它起源于拉丁文学,经常用于设计软件的文本预览,以便设计师在不影响最终版式的情况下测试页面布局。在这款插件的上下文菜单中加入这一项,可能允许用户快速生成一段Lorem Ipsum文本,用于测试网页布局或者排版效果,从而让开发者在设计过程中获得更真实的视觉体验。 “电话”菜单项则可能用于提供快速生成或者验证电话号码格式的功能,这对于处理与电话相关的用户输入或数据录入工作非常有用。考虑到不同国家和地区的电话号码格式可能有所不同,这一功能可能允许用户选择特定的地区代码,从而生成相应格式的电话号码样例。 【标签】中提到的“扩展程序”一词,是指能够被浏览器安装并添加额外功能的软件。扩展程序可以改变浏览器的基本界面、行为和功能,是Web开发和测试中常见的工具。它们通常由浏览器的开发者或者第三方开发者创建,对于提升开发效率、调试和测试网站有着重要的作用。 【压缩包子文件的文件名称列表】中的“Dev_Context_Menu_Utils_(beta).crx”是这款插件的文件名,CRX是Chrome扩展程序的文件格式,类似于Windows平台上的.exe可执行文件格式,只不过CRX是为Chrome浏览器特别设计的。扩展程序开发者需要通过Chrome Web Store或者其他途径将CRX文件分发给用户,用户可以通过下载并安装CRX文件来使用扩展程序。 总体来说,Dev Context Menu Utils (beta) 插件通过为开发者提供便捷的上下文菜单项来增强开发效率,允许快速生成重要的代码片段和数据格式,从而简化开发过程中的常见任务。对于那些在开发阶段需要频繁使用这些功能的开发者来说,这款插件将是一个非常有价值的工具。然而,由于它目前还是beta版本,使用时可能需要注意可能存在的一些错误或功能限制,并建议开发者在实际项目中使用前先在测试环境中进行充分的测试。
recommend-type

【Coz进阶秘籍】:解锁工作流高级功能,提升效率的终极技巧

# 1. Coz工作流基础概述 工作流系统是现代IT运营不可或缺的一部分,它通过自动化执行任务和协调业务流程来提高效率。在本章节中,我们将首先介绍Coz工作流的基础概念和其在业务流程自动化中的应用。Coz工作流利用一系列预定义的任务、规则以及任务之间的依赖关系,按照既定规
recommend-type

HR和HRBP区别

<think>首先,用户意图是了解HR和HRBP的区别。用户问题是“HR和HRBP的区别”。我需要根据任务要求进行网络搜索。 任务要求: 1. 调用网络搜索工具进行检索。 2. 整合检索到的内容,生成详细且清晰的回答。 3. 禁止将所有引用内容集中在回答末尾。 4. 避免使用第一人称如“我”。 5. 避免步骤词汇如“首先”、“然后”。 6. 尽量将答案组织为多个方法或步骤,并在每个步骤间换行。 7. 对于代码和公式:如果有,必须使用指定格式。 8. 在回答最后添加相关问题部分,标题为“§§相关问题§§:”,后跟至少3个相关问题,每个用阿拉伯数字标号。 由于问题是关于HR和HRBP的区别,不
recommend-type

阻止Web加密货币挖掘的Miner Away扩展

### 知识点分析 #### 标题:“Miner Away-crx插件” **知识点**: 1. **CRX插件格式**:CRX是Chrome扩展程序的文件格式,它是一个ZIP压缩包,包含了扩展程序的所有文件和文件夹,例如HTML、JavaScript、CSS文件,以及扩展程序的清单文件(manifest.json)。CRX文件可以直接在Chrome浏览器的扩展管理界面拖拽安装。 2. **扩展程序(Extension)**:浏览器扩展程序是一种增加或改进浏览器功能的软件模块。它可以通过第三方开发者创建,用以提供特定的功能,比如用户界面定制、广告拦截、内容过滤等。 #### 描述:“在网上停止硬币矿工!” **知识点**: 3. **加密货币挖掘(Cryptocurrency Mining)**:指的是利用计算机的处理能力来计算加密货币的交易并维护区块链的过程。传统的加密货币挖掘需要大量的计算资源和电力消耗,近年来出现了基于Web的挖矿,即在网页中嵌入JavaScript代码,利用访问者的浏览器进行挖掘。 4. **矿工拒绝(Cryptominer Blocking)**:矿工拒绝功能的扩展通常用于识别和阻止这类JavaScript代码运行,从而保护用户设备的性能不受影响。这类扩展程序通常会维护一个黑名单,其中包含已知的挖矿脚本或网站地址。 5. **Opera Web Store**:Opera浏览器的官方扩展商店,类似于Chrome Web Store或Firefox Add-ons,是用户下载、安装和管理Opera浏览器扩展程序的平台。 6. **特征(Features)**: - **阻止JavaScript或Web矿工**:扩展能够检测并阻止网页加载的挖矿脚本。 - **域名选择性允许**:用户可以自行选择允许哪些特定网站加载JavaScript。 - **状态显示**:扩展程序会实时显示当前是否有挖矿行为发生。 - **通知功能**:当有网站尝试进行挖矿时,用户会即时收到桌面通知。 7. **技术实现细节**: - **黑名单机制**:扩展使用黑名单文件(*blacklist.txt*),其中包含被识别为执行挖矿行为的域名。 - **请求拦截**:对与黑名单中域名匹配的网站请求进行拦截,从而防止挖矿脚本运行。 #### 标签:“扩展程序” **知识点**: 8. **浏览器扩展程序的分类**:扩展程序通常根据其功能进行分类,如广告拦截器、密码管理器、下载管理器等。 9. **扩展程序的管理**:用户通常可以在浏览器的扩展管理界面中开启/关闭扩展、管理扩展权限、删除扩展等。 #### 压缩包子文件的文件名称列表:“Miner_Away.crx” **知识点**: 10. **文件命名约定**:扩展程序的文件名通常与其功能相关,例如本例中的“Miner_Away”暗示了该扩展用于阻止挖矿行为。 11. **文件的安装**:CRX文件可以通过多种方式进行安装,最常见的方式是直接从浏览器的扩展管理界面导入(通常通过拖拽文件到浏览器窗口),或者从扩展商店下载安装。 12. **文件的安全性**:用户应从可信来源下载扩展程序,避免下载可能含有恶意软件的非官方版本。 总结以上知识点,Miner Away扩展程序是一种专门设计用于阻止Web矿工的浏览器扩展,它通过黑名单机制拦截和阻止网站加载的加密货币挖掘脚本,保护用户的设备免受未经授权的资源消耗。该扩展还提供实时状态通知和请求拦截功能,为用户提供了更为安全和高效的网络浏览体验。
recommend-type

量子计算模拟与硬件发展:NISQ时代的探索

# 量子计算模拟与硬件发展:NISQ时代的探索 ## 1. 分布式计算在量子模拟中的应用 在量子计算领域,充分利用经典资源是一个重要的课题。分布式计算框架为我们提供了一种有效的途径,如今,这些框架在各大组织中广泛存在。例如,Apache Spark和Ray等分布式计算框架,已被广泛应用于大数据处理和深度学习模型训练。 量子计算模拟器也可以借助分布式生态系统,通过拆分需要执行的数学运算来实现。不过,将一个整体系统拆分为一组独立操作,需要我们深入理解当前问题的可拆分性。目前,处理分布式量子计算模拟的框架大多来自研究团队,像英特尔和百度等大型组织也有相关研究。 随着量子硬件的不断成熟,设备无关
recommend-type

1>&2

<think>首先,用户的问题是:“1>&2”,这是一个shell命令中的重定向操作符。我需要用中文回答。 用户的要求: - 使用中文回答问题。 - 回答完问题后,必须根据用户的问题及我的回答提出3-5个相关问题。 - 相关问题必须输出在回答的末尾。 - 第一行必须完整输出“§§相关问题§§”,禁止换行分散。 - 确保所有内容符合规则。 问题分析:“1>&2”在shell中表示将标准输出(stdout)重定向到标准错误(stderr)。具体来说: - “1”代表文件描述符1(stdout)。 - “>”表示重定向。 - “&2”表示文件描述符2(stderr)。 - 所以,“1>&2”的意