void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) { /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_DATA(Data)); /* Transmit Data */ USARTx->DR = (Data & (uint16_t)0x01FF); }

时间: 2025-06-18 11:20:23 浏览: 18
<think>嗯,用户想了解STM32的USART_SendData函数的工作原理和参数检查过程。首先,我需要回忆一下USART的基本知识。USART是通用同步异步收发器,用于串口通信。STM32的库函数里有USART_SendData这个函数,用来发送数据。但用户提供的引用中提到了一些问题,比如只能发送两个字节,或者需要检查标志位。 首先,函数原型是void USART_SendData(USART_TypeDef* USARTx, u16 Data)。参数USARTx是指向USART外设的指针,比如USART1、USART2等。第二个参数是u16类型的数据,但实际上串口数据寄存器是16位的,但通常只用低9位。所以发送数据时,用户需要确保数据在有效范围内,比如8位模式下是0-0xFF,9位则是0-1FF。但库函数是否做了参数检查呢?根据引用[1],USART_StructInit函数会设置缺省值,但USART_SendData本身可能不会检查参数的有效性,需要用户自己确保。例如,如果传入的数据超过9位,高位会被忽略,或者导致错误。 然后,关于工作原理。函数将数据写入USART的DR寄存器,但发送过程是异步的,需要等待发送完成。引用[3]和[4]提到,发送后需要检查TC(传输完成)标志位,或者TXE(发送寄存器空)标志位,以确保数据已经移出到移位寄存器,避免覆盖。比如,使用while循环等待USART_FLAG_TC置位。如果不等待,连续发送多个字节时,可能会覆盖之前的未发送数据,导致数据丢失,如引用[4]中的例子,发送第三个字节失败。 参数检查方面,STM32的库函数通常不会在运行时进行严格的参数校验,比如是否传入了正确的USART外设地址,或者数据是否超出范围。这些需要用户在调用前自行检查,否则可能导致硬件错误或未定义行为。比如,传入无效的USARTx指针会导致访问错误。 总结,USART_SendData函数的工作原理是将数据写入DR寄存器,启动发送,但需配合标志位检查确保数据正确发送。参数检查主要依赖用户,库函数可能仅做基本有效性验证,如寄存器写入,但不处理数据范围或外设状态。用户需在调用后等待TC或TXE标志,避免覆盖问题。 用户可能的问题可能涉及如何正确使用这个函数,常见错误(如数据丢失的原因),或者如何优化发送过程。例如,是否需要每次发送都等待标志位,或者有没有更高效的方法,比如使用DMA。此外,可能想知道为什么库函数不自动处理这些检查,或者如何自定义发送函数来封装等待过程,如引用[4]中的USART2_putc函数。</think>### 解释STM32 USART_SendData函数的工作原理及参数检查过程 #### 1. 函数功能与参数定义 `USART_SendData`是STM32标准外设库中用于通过串口发送单个数据的函数,其原型为: ```c void USART_SendData(USART_TypeDef* USARTx, u16 Data); ``` - **参数说明**: - `USARTx`:指向目标USART外设的指针(如`USART1`、`USART2`等)。 - `Data`:待发送的16位数据(实际有效位数取决于USART配置,通常为8或9位)。 #### 2. 工作原理 1. **数据写入数据寄存器(DR)** 函数将`Data`写入USART的数据寄存器`DR`,触发发送过程[^2]。 ```c USARTx->DR = (Data & (uint16_t)0x01FF); // 仅保留低9位(兼容不同数据位配置) ``` 2. **硬件发送流程** - 数据从`DR`寄存器加载到发送移位寄存器。 - 移位寄存器通过TX引脚逐位发送数据。 - **关键标志位**: - `TXE`(发送寄存器空):表示`DR`已空,可写入新数据。 - `TC`(传输完成):表示所有数据(包括停止位)已发送完毕[^3]。 3. **发送完成检测** 需通过`USART_GetFlagStatus`检查标志位,避免数据覆盖: ```c while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); // 等待发送完成[^4] ``` #### 3. 参数检查过程 1. **库函数内部检查** STM32标准库**不主动验证参数合法性**,例如: - 不检查`USARTx`是否为有效外设地址。 - 不验证`Data`是否超出当前配置的数据位范围(如8位模式下发送`0x2FF`会导致高位丢失)。 2. **用户责任** 开发者需自行确保: - USART外设已正确初始化(波特率、数据位等)。 - `Data`值符合当前数据位配置(如8位模式使用`0x00~0xFF`)。 - 调用函数前使能USART和发送器(通过`USART_Cmd`和`USART_SendData`配置)[^1]。 #### 4. 典型问题与解决方案 - **问题1:仅发送部分数据** **原因**:未等待`TC`标志,导致后续数据覆盖未发送的内容[^4]。 **解决**:在每次发送后添加等待标志位的代码。 - **问题2:数据错位或丢失** **原因**:数据位配置(8/9位)与`Data`值不匹配。 **解决**:根据配置对`Data`进行掩码操作(如`Data & 0xFF`)。 --- ###
阅读全文

相关推荐

#include "stm32f10x.h" #include "delay.h" #include "OLED.h" #include "dht11.h" #include "FMQ.h" #include "Serial.h" #include "esp8266.h" #include "stm32f10x_it.h" // 系统时钟配置 void SystemClock_Config(void) { SystemInit(); RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); // 添加HSE启动检测 if(!RCC_WaitForHSEStartUp()) { while(1); // HSE启动失败,陷入死循环 } FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() != 0x08); } // 全局变量 u8 temp, humi; int main(void) { // 系统初始化 SystemClock_Config(); Delay_Init(); OLED_Init(); DHT11_Init(); mfq_Init(); Serial_Init(); // 用于调试的串口 // 显示初始化 OLED_ShowCN(0, 0, "温度:"); // 修改为正确的中文字库函数 OLED_ShowCN(0, 16, "湿度:"); OLED_ShowCN(64, 16, "RH"); OLED_ShowCN(64, 0, "C"); OLED_Update(); // 初始化ESP8266为AP模式 ESP8266_Init(); printf("ESP8266 AP Mode Ready\r\n"); printf("Connect to WiFi: ESP8266wd, Password:123456789\r\n"); printf("Then connect to TCP Server: 192.168.4.1:8080\r\n"); uint32_t lastSendTime = 0; while(1) { // 读取温湿度 if(DHT11_Read_Data(&temp, &humi)) { // 更新显示 OLED_ShowNum(47, 0, temp, 2, OLED_8X16); OLED_ShowNum(47, 16, humi, 2, OLED_8X16); OLED_Update(); // 控制蜂鸣器 fmq(temp, humi); // 串口输出信息 printf("temp=%d, humi=%d RH\r\n", temp, humi); // 准备WiFi发送数据 sprintf(wifi_data, "Temp:%d,Humi:%d\r\n", temp, humi); ESP8266_SendData(wifi_data); } delay_ms(5000); // 5秒更新一次 } } /** ****************************************************************************** * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Library configuration file. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *
© COPYRIGHT 2011 STMicroelectronics
****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F10x_CONF_H #define __STM32F10x_CONF_H /* Includes ------------------------------------------------------------------*/ /* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ #include "stm32f10x_adc.h" #include "stm32f10x_bkp.h" #include "stm32f10x_can.h" #include "stm32f10x_cec.h" #include "stm32f10x_crc.h" #include "stm32f10x_dac.h" #include "stm32f10x_dbgmcu.h" #include "stm32f10x_dma.h" #include "stm32f10x_exti.h" #include "stm32f10x_flash.h" #include "stm32f10x_fsmc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_i2c.h" #include "stm32f10x_iwdg.h" #include "stm32f10x_pwr.h" #include "stm32f10x_rcc.h" #include "stm32f10x_rtc.h" #include "stm32f10x_sdio.h" #include "stm32f10x_spi.h" #include "stm32f10x_tim.h" #include "stm32f10x_usart.h" #include "stm32f10x_wwdg.h" #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* Uncomment the line below to expanse the "assert_param" macro in the Standard Peripheral Library drivers code */ /* #define USE_FULL_ASSERT 1 */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT /** * @brief The assert_param macro is used for function's parameters check. * @param expr: If expr is false, it calls assert_failed function which reports * the name of the source file and the source line number of the call * that failed. If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) #endif /* USE_FULL_ASSERT */ #endif /* __STM32F10x_CONF_H */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ /** ****************************************************************************** * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *
© COPYRIGHT 2011 STMicroelectronics
****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_it.h" volatile uint32_t sysTickUptime = 0; // 添加在文件顶部 /** @addtogroup STM32F10x_StdPeriph_Template * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************/ /* Cortex-M3 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. * @param None * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. * @param None * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. * @param None * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @retval None */ void SVC_Handler(void) { } /** * @brief This function handles Debug Monitor exception. * @param None * @retval None */ void DebugMon_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { // 添加SysTick中断处理 sysTickUptime++; } /******************************************************************************/ /* STM32F10x Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ /* file (startup_stm32f10x_xx.s). */ /******************************************************************************/ /** * @brief This function handles USART3 global interrupt request. * @param None * @retval None */ void USART2_IRQHandler(void) { // 调用ESP8266模块的中断处理函数 extern void ESP8266_IRQHandler(void); ESP8266_IRQHandler(); } uint32_t HAL_GetTick(void) { return sysTickUptime; } /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ /** ****************************************************************************** * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief This file contains the headers of the interrupt handlers. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *
© COPYRIGHT 2011 STMicroelectronics
****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F10x_IT_H #define __STM32F10x_IT_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" extern volatile uint32_t sysTickUptime; uint32_t HAL_GetTick(void); /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); #ifdef __cplusplus } #endif #endif /* __STM32F10x_IT_H */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ #include "esp8266.h" #include <string.h> #include "stm32f10x_usart.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" // 发送AT指令 void ESP8266_SendCmd(char* cmd, char* resp, uint16_t timeout) { USART_ClearFlag(ESP8266_USARTx, USART_FLAG_TC); // 发送命令 while(*cmd) { USART_SendData(ESP8266_USARTx, *cmd++); while(USART_GetFlagStatus(ESP8266_USARTx, USART_FLAG_TC) == RESET); } // 等待响应 uint32_t start = HAL_GetTick(); while(strstr((const char*)USART_RxBuffer, resp) == NULL) { if(HAL_GetTick() - start > timeout) { break; } } delay_ms(50); } // 初始化ESP8266为AP模式 void ESP8266_Init(void) { // 初始化USART2 USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; // 配置USART2 Tx (PA2) 为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART2 Rx (PA3) 为浮空输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = ESP8266_USART_BAUDRATE; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(ESP8266_USARTx, &USART_InitStructure); USART_Cmd(ESP8266_USARTx, ENABLE); // 添加NVIC中断配置 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 配置ESP8266为AP模式 Delay_ms(1000); // 等待模块启动 ESP8266_SendCmd("AT+RST\r\n", "OK", 2000); ESP8266_SendCmd("AT+CWMODE=2\r\n", "OK", 2000); // 设置为AP模式 ESP8266_SendCmd("AT+CWSAP=\"ESP8266_AP\",\"12345678\",1,4\r\n", "OK", 2000); // 设置AP参数 ESP8266_SendCmd("AT+CIPMUX=1\r\n", "OK", 2000); // 允许多连接 ESP8266_SendCmd("AT+CIPSERVER=1,8080\r\n", "OK", 2000); // 开启TCP服务器 } // 发送数据到TCP客户端 u8 ESP8266_SendData(char* data) { char cmd[64]; sprintf(cmd, "AT+CIPSEND=0,%d\r\n", strlen(data)); ESP8266_SendCmd(cmd, "OK", 1000); // 等待OK响应 ESP8266_SendCmd(data, ">", 1000); // 等待>提示符 ESP8266_SendCmd((char*)0x1A, "SEND OK", 1000); // 发送Ctrl+Z return 0; } // esp8266.h #ifndef __ESP8266_H #define __ESP8266_H #include "stm32f10x.h" #include "stm32f10x_usart.h" #include "delay.h" #define ESP8266_USARTx USART2 #define ESP8266_USART_BAUDRATE 115200 void ESP8266_Init(void); void ESP8266_SendCmd(char* cmd); u8 ESP8266_SendData(char* data); #endif 将代码修改正确

单片机甲:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <string.h> #include <stdio.h> // 添加stdio.h以支持sprintf函数 /* 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 ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint8_t rxBuffer1[20]; // USART1接收缓冲区 uint8_t rxBuffer3[20]; // USART3接收缓冲区 uint8_t txBuffer[50]; // 发送缓冲区 uint8_t irStatus = 0; // 红外传感器状态 uint8_t lastIrStatus = 0; // 上一次红外传感器状态 /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ void IR_Detection(void); // 添加函数声明 /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); // 启动USART1接收中断 HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); // 启动USART3接收中断,波特率9600 HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ // 调用红外检测函数 IR_Detection(); // 根据红外传感器状态控制PWM输出 if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15) == GPIO_PIN_SET) { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0); } else { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 180); } // 添加延时以避免过度占用CPU HAL_Delay(100); } /* 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(); } } /* USER CODE BEGIN 4 */ // 统一的UART接收回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { // USART1数据处理逻辑 // 例如:可以在这里添加对USART1接收到的数据的处理 // 重新启动接收 HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); } else if(huart->Instance == USART3) { // USART3数据处理逻辑 // 例如:可以在这里添加对USART3接收到的数据的处理 // 重新启动接收 HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); } } // 红外传感器检测函数 void IR_Detection(void) { // 读取红外传感器状态 irStatus = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15); // 根据当前状态发送对应信息 if(irStatus == GPIO_PIN_SET) { // 障碍物检测到 sprintf((char*)txBuffer, "IR Sensor: No Obstacle\r\n"); } else { // 无障碍物 sprintf((char*)txBuffer, "IR Sensor: Obstacle Detected\r\n"); } // 通过两个串口发送信息 HAL_UART_Transmit(&huart1, txBuffer, strlen((char*)txBuffer), 100); HAL_UART_Transmit(&huart3, txBuffer, strlen((char*)txBuffer), 100); // 添加1秒延时 HAL_Delay(500); } /* 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 * * Copyright (c) 2025 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 "adc.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include <stdio.h> #include <string.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 */ /* ??LED?? */ #define LED_PIN GPIO_PIN_13 #define LED_GPIO_PORT GPIOC /* ???? */ #define FILTER_DEPTH 5 // ???????? /* ???? */ #define LIGHT_THRESHOLD_LOW 1000 // ????? #define LIGHT_THRESHOLD_HIGH 3000 // ????? /* ?????? */ #define MOTOR_MIN_SPEED 50 // ??????(????) #define MOTOR_MAX_SPEED 199 // ??????(???????) /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint16_t light_value = 0; // ????? uint16_t light_filtered = 0; // ??????? uint16_t motor_speed = 0; // ???? uint16_t filter_buffer[FILTER_DEPTH]; // ????? uint8_t filter_index = 0; // ???? uint8_t led_state = 0; // LED?? char uart_buffer[100]; // ????? uint8_t rxBuffer1[20]; // USART1????? - ???? uint8_t rxBuffer3[20]; // USART3????? - ???? /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ uint16_t Read_LightSensor(void); uint16_t ApplyFilter(uint16_t new_value); void Control_Motor(uint16_t light_value); void Send_Data_To_UART(uint16_t light_value, uint16_t motor_speed); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /** * ???????? */ uint16_t Read_LightSensor(void) { uint16_t adc_value = 0; /* ??ADC?? */ if(HAL_ADC_Start(&hadc1) != HAL_OK) { Error_Handler(); } /* ?????? */ if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { /* ??ADC? */ adc_value = HAL_ADC_GetValue(&hadc1); } return adc_value; } /** * ?????? */ uint16_t ApplyFilter(uint16_t new_value) { uint32_t sum = 0; /* ???????? */ filter_buffer[filter_index] = new_value; filter_index = (filter_index + 1) % FILTER_DEPTH; /* ????? */ for(int i = 0; i < FILTER_DEPTH; i++) { sum += filter_buffer[i]; } return (uint16_t)(sum / FILTER_DEPTH); } /** * ?????? */ void Control_Motor(uint16_t light_value) { // ????????????? // ??ADC????0-4095 // ???????MOTOR_MIN_SPEED-MOTOR_MAX_SPEED // ?????,?????? motor_speed = (light_value * (MOTOR_MAX_SPEED - MOTOR_MIN_SPEED)) / 4095 + MOTOR_MIN_SPEED; // ???????? if(motor_speed > MOTOR_MAX_SPEED) motor_speed = MOTOR_MAX_SPEED; if(motor_speed < MOTOR_MIN_SPEED) motor_speed = 0; // ??????????,???? // ??PWM??? __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, motor_speed); } /** * ??????? */ void Send_Data_To_UART(uint16_t light_value, uint16_t motor_speed) { /* ????? */ sprintf(uart_buffer, "Light: %d, Motor Speed: %d\r\n", light_value, motor_speed); /* ???? */ HAL_UART_Transmit(&huart1, (uint8_t *)uart_buffer, strlen(uart_buffer), 100); } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* ???????? */ for(int i = 0; i < FILTER_DEPTH; i++) { filter_buffer[i] = 0; } /* 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_ADC1_Init(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); MX_TIM4_Init(); /* USER CODE BEGIN 2 */ /* ??PWM?? */ HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); /* ??USART3???? */ HAL_UART_Receive_IT(&huart3, rxBuffer3, 1); /* ??????? */ HAL_UART_Transmit(&huart1, (uint8_t *)"System initialized! Light sensor and motor control enabled.\r\n", 62, 100); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* ????? */ light_value = Read_LightSensor(); /* ???? */ light_filtered = ApplyFilter(light_value); /* ?????? */ Control_Motor(light_filtered); /* ??????????? */ Send_Data_To_UART(light_filtered, motor_speed); /* ????????LED - ????????? */ if(light_filtered < LIGHT_THRESHOLD_LOW) { led_state = 1; // ???,LED?? } else if(light_filtered > LIGHT_THRESHOLD_HIGH) { led_state = 0; // ???,LED?? } HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, led_state ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_Delay(100); // ????,?????? } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ // UART?????? void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { // ??USART1?????? // ?????? HAL_UART_Receive_IT(&huart1, rxBuffer1, 1); } else if(huart->Instance == USART3) { // ??USART3?????? // ??:????????????????? // ?????? HAL_UART_Receive_IT(&huart3, rxBuffer3, 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 */ 串口无法给对方发送信息

/********************************************************************************************************* * * File : ws_W25Qx.c * Hardware Environment: * Build Environment : RealView MDK-ARM Version: 4.20 * Version : V1.0 * By : * * (c) Copyright 2005-2011, WaveShare * http://www.waveshare.net * All Rights Reserved * *********************************************************************************************************/ #include "W25QXX.h" /** * @brief Initializes the W25Q128FV interface. * @retval None */ uint8_t BSP_W25Qx_Init(void) { /* Reset W25Qxxx */ BSP_W25Qx_Reset(); return BSP_W25Qx_GetStatus(); } /** * @brief This function reset the W25Qx. * @retval None */ static void BSP_W25Qx_Reset(void) { uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD}; W25Qx_Enable(); /* Send the reset command */ HAL_SPI_Transmit(&hspi2, cmd, 2, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); } /** * @brief Reads current status of the W25Q128FV. * @retval W25Q128FV memory status */ static uint8_t BSP_W25Qx_GetStatus(void) { uint8_t cmd[] = {READ_STATUS_REG1_CMD}; uint8_t status; W25Qx_Enable(); /* Send the read status command */ HAL_SPI_Transmit(&hspi2, cmd, 1, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ HAL_SPI_Receive(&hspi2,&status, 1, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); /* Check the value of the register */ if((status & W25Q128FV_FSR_BUSY) != 0) { return W25Qx_BUSY; } else { return W25Qx_OK; } } /** * @brief This function send a Write Enable and wait it is effective. * @retval None */ uint8_t BSP_W25Qx_WriteEnable(void) { uint8_t cmd[] = {WRITE_ENABLE_CMD}; uint32_t tickstart = HAL_GetTick(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi2, cmd, 1, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /** * @brief Read Manufacture/Device ID. * @param return value address * @retval None */ void BSP_W25Qx_Read_ID(uint8_t *ID) { uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00}; W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi2, cmd, 4, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ HAL_SPI_Receive(&hspi2,ID, 2, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); } /** * @brief Reads an amount of data from the QSPI memory. * @param pData: Pointer to data to be read * @param ReadAddr: Read start address * @param Size: Size of data to read * @retval QSPI memory status */ uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) { uint8_t cmd[4]; /* Configure the command */ cmd[0] = READ_CMD; cmd[1] = (uint8_t)(ReadAddr >> 16); cmd[2] = (uint8_t)(ReadAddr >> 8); cmd[3] = (uint8_t)(ReadAddr); W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi2, cmd, 4, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ if (HAL_SPI_Receive(&hspi2, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } W25Qx_Disable(); return W25Qx_OK; } /** * @brief Writes an amount of data to the QSPI memory. * @param pData: Pointer to data to be written * @param WriteAddr: Write start address * @param Size: Size of data to write,No more than 256byte. * @retval QSPI memory status */ uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) { uint8_t cmd[4]; uint32_t end_addr, current_size, current_addr; uint32_t tickstart = HAL_GetTick(); /* Calculation of the size between the write address and the end of the page */ current_addr = 0; while (current_addr <= WriteAddr) { current_addr += W25Q128FV_PAGE_SIZE; } current_size = current_addr - WriteAddr; /* Check if the size of the data is less than the remaining place in the page */ if (current_size > Size) { current_size = Size; } /* Initialize the adress variables */ current_addr = WriteAddr; end_addr = WriteAddr + Size; /* Perform the write page by page */ do { /* Configure the command */ cmd[0] = PAGE_PROG_CMD; cmd[1] = (uint8_t)(current_addr >> 16); cmd[2] = (uint8_t)(current_addr >> 8); cmd[3] = (uint8_t)(current_addr); /* Enable write operations */ BSP_W25Qx_WriteEnable(); W25Qx_Enable(); /* Send the command */ if (HAL_SPI_Transmit(&hspi2,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } /* Transmission of the data */ if (HAL_SPI_Transmit(&hspi2, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE) { return W25Qx_TIMEOUT; } } /* Update the address and size variables for next page programming */ current_addr += current_size; pData += current_size; current_size = ((current_addr + W25Q128FV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25Q128FV_PAGE_SIZE; } while (current_addr < end_addr); return W25Qx_OK; } /** * @brief Erases the specified block of the QSPI memory. * @param BlockAddress: Block address to erase * @retval QSPI memory status */ uint8_t BSP_W25Qx_Erase_Block(uint32_t Address) { uint8_t cmd[4]; uint32_t tickstart = HAL_GetTick(); cmd[0] = SECTOR_ERASE_CMD; cmd[1] = (uint8_t)(Address >> 16); cmd[2] = (uint8_t)(Address >> 8); cmd[3] = (uint8_t)(Address); /* Enable write operations */ BSP_W25Qx_WriteEnable(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi2, cmd, 4, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Q128FV_SECTOR_ERASE_MAX_TIME) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /** * @brief Erases the entire QSPI memory.This function will take a very long time. * @retval QSPI memory status */ uint8_t BSP_W25Qx_Erase_Chip(void) { uint8_t cmd[4]; uint32_t tickstart = HAL_GetTick(); cmd[0] = SECTOR_ERASE_CMD; /* Enable write operations */ BSP_W25Qx_WriteEnable(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi2, cmd, 1, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() != W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Q128FV_BULK_ERASE_MAX_TIME) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /********************************************************************************************************* * * File : W25Qx.h * Hardware Environment: * Build Environment : RealView MDK-ARM Version: 5.15 * Version : V1.0 * By : * * (c) Copyright 2005-2015, WaveShare * http://www.waveshare.net * All Rights Reserved * *********************************************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __W25QXX_H #define __W25QXX_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx.h" #include "spi.h" /** @addtogroup BSP * @{ */ /** @addtogroup Components * @{ */ /** @addtogroup W25Q128FV * @{ */ /** @defgroup W25Q128FV_Exported_Types * @{ */ /** * @} */ /** @defgroup W25Q128FV_Exported_Constants * @{ */ /** * @brief W25Q128FV Configuration */ #define W25Q128FV_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ #define W25Q128FV_SECTOR_SIZE 0x10000 /* 256 sectors of 64KBytes */ #define W25Q128FV_SUBSECTOR_SIZE 0x1000 /* 4096 subsectors of 4kBytes */ #define W25Q128FV_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ #define W25Q128FV_DUMMY_CYCLES_READ 4 #define W25Q128FV_DUMMY_CYCLES_READ_QUAD 10 #define W25Q128FV_BULK_ERASE_MAX_TIME 250000 #define W25Q128FV_SECTOR_ERASE_MAX_TIME 3000 #define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME 800 #define W25Qx_TIMEOUT_VALUE 1000 /** * @brief W25Q128FV Commands */ /* Reset Operations */ #define RESET_ENABLE_CMD 0x66 #define RESET_MEMORY_CMD 0x99 #define ENTER_QPI_MODE_CMD 0x38 #define EXIT_QPI_MODE_CMD 0xFF /* Identification Operations */ #define READ_ID_CMD 0x90 #define DUAL_READ_ID_CMD 0x92 #define QUAD_READ_ID_CMD 0x94 #define READ_JEDEC_ID_CMD 0x9F /* Read Operations */ #define READ_CMD 0x03 #define FAST_READ_CMD 0x0B #define DUAL_OUT_FAST_READ_CMD 0x3B #define DUAL_INOUT_FAST_READ_CMD 0xBB #define QUAD_OUT_FAST_READ_CMD 0x6B #define QUAD_INOUT_FAST_READ_CMD 0xEB /* Write Operations */ #define WRITE_ENABLE_CMD 0x06 #define WRITE_DISABLE_CMD 0x04 /* Register Operations */ #define READ_STATUS_REG1_CMD 0x05 #define READ_STATUS_REG2_CMD 0x35 #define READ_STATUS_REG3_CMD 0x15 #define WRITE_STATUS_REG1_CMD 0x01 #define WRITE_STATUS_REG2_CMD 0x31 #define WRITE_STATUS_REG3_CMD 0x11 /* Program Operations */ #define PAGE_PROG_CMD 0x02 #define QUAD_INPUT_PAGE_PROG_CMD 0x32 /* Erase Operations */ #define SECTOR_ERASE_CMD 0x20 #define CHIP_ERASE_CMD 0xC7 #define PROG_ERASE_RESUME_CMD 0x7A #define PROG_ERASE_SUSPEND_CMD 0x75 /* Flag Status Register */ #define W25Q128FV_FSR_BUSY ((uint8_t)0x01) /*!< busy */ #define W25Q128FV_FSR_WREN ((uint8_t)0x02) /*!< write enable */ #define W25Q128FV_FSR_QE ((uint8_t)0x02) /*!< quad enable */ #define W25Qx_Enable() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET) #define W25Qx_Disable() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET) #define W25Qx_OK ((uint8_t)0x00) #define W25Qx_ERROR ((uint8_t)0x01) #define W25Qx_BUSY ((uint8_t)0x02) #define W25Qx_TIMEOUT ((uint8_t)0x03) uint8_t BSP_W25Qx_Init(void); static void BSP_W25Qx_Reset(void); static uint8_t BSP_W25Qx_GetStatus(void); uint8_t BSP_W25Qx_WriteEnable(void); void BSP_W25Qx_Read_ID(uint8_t *ID); uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size); uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size); uint8_t BSP_W25Qx_Erase_Block(uint32_t Address); uint8_t BSP_W25Qx_Erase_Chip(void); /** * @} */ /** @defgroup W25Q128FV_Exported_Functions * @{ */ /** * @} */ /** * @} */ /** * @} */ /** * @} */ #ifdef __cplusplus } #endif #endif /* __W25Qx_H */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "spi.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stm32f1xx_hal.h" #include <stdio.h> #include <string.h> #include "W25QXX.h" uint8_t wData[0x100]; uint8_t rData[0x100]; uint32_t i; uint8_t ID[2]; extern UART_HandleTypeDef huart1; //声明串口 /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /** * 函数功能: 重定向c库函数printf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } /** * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart1, &ch, 1, 0xffff); return ch; } /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI2_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ printf("\r\n SPI-W25Qxxx Example \r\n\r\n"); /*##-1- Read the device ID ########################*/ BSP_W25Qx_Init(); BSP_W25Qx_Read_ID(ID); printf(" W25Qxxx ID is : 0x%02X 0x%02X \r\n\r\n",ID[0],ID[1]); /*##-2- Erase Block ##################################*/ if(BSP_W25Qx_Erase_Block(0) == W25Qx_OK) printf(" SPI Erase Block ok\r\n"); else Error_Handler(); /*##-3- Written to the flash ########################*/ /* fill buffer */ for(i =0;i<0x100;i ++) { wData[i] = i; rData[i] = 0; } if(BSP_W25Qx_Write(wData,0x00,0x100)== W25Qx_OK) printf(" SPI Write ok\r\n"); else Error_Handler(); /*##-4- Read the flash ########################*/ if(BSP_W25Qx_Read(rData,0x00,0x100)== W25Qx_OK) printf(" SPI Read ok\r\n\r\n"); else Error_Handler(); printf("SPI Read Data : \r\n"); for(i =0;i<0x100;i++) printf("0x%02X ",rData[i]); printf("\r\n\r\n"); /*##-5- check date ########################*/ if(memcmp(wData,rData,0x100) == 0 ) printf(" W25Q128FV SPI Test OK\r\n"); else printf(" W25Q128FV SPI Test False\r\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* 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(); } } /* 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 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file gpio.c * @brief This file provides code for the configuration * of all used GPIO pins. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "gpio.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /*----------------------------------------------------------------------------*/ /* Configure GPIO */ /*----------------------------------------------------------------------------*/ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : PtPin */ GPIO_InitStruct.Pin = SPI2_CS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SPI2_CS_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file spi.c * @brief This file provides code for the configuration * of the SPI instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "spi.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ SPI_HandleTypeDef hspi2; /* SPI2 init function */ void MX_SPI2_Init(void) { /* USER CODE BEGIN SPI2_Init 0 */ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1 */ /* USER CODE END SPI2_Init 1 */ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */ } void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(spiHandle->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspInit 0 */ /* USER CODE END SPI2_MspInit 0 */ /* SPI2 clock enable */ __HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**SPI2 GPIO Configuration PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */ } } void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) { if(spiHandle->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspDeInit 0 */ /* USER CODE END SPI2_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_SPI2_CLK_DISABLE(); /**SPI2 GPIO Configuration PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15); /* USER CODE BEGIN SPI2_MspDeInit 1 */ /* USER CODE END SPI2_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 *//* USER CODE BEGIN Header */ /** ****************************************************************************** * @file usart.c * @brief This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ 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 */ } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file usart.c * @brief This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ 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 */ } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file usart.c * @brief This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ 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 */ } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_it.c * @brief Interrupt Service Routines. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "stm32f1xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* 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 */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /******************************************************************************/ /* Cortex-M3 Processor Interruption and Exception Handlers */ /******************************************************************************/ /** * @brief This function handles Non maskable interrupt. */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ while (1) { } /* USER CODE END NonMaskableInt_IRQn 1 */ } /** * @brief This function handles Hard fault interrupt. */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn 0 */ /* USER CODE END W1_HardFault_IRQn 0 */ } } /** * @brief This function handles Memory management fault. */ void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ /* USER CODE END W1_MemoryManagement_IRQn 0 */ } } /** * @brief This function handles Prefetch fault, memory access fault. */ void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_BusFault_IRQn 0 */ /* USER CODE END W1_BusFault_IRQn 0 */ } } /** * @brief This function handles Undefined instruction or illegal state. */ void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ /* USER CODE END W1_UsageFault_IRQn 0 */ } } /** * @brief This function handles System service call via SWI instruction. */ void SVC_Handler(void) { /* USER CODE BEGIN SVCall_IRQn 0 */ /* USER CODE END SVCall_IRQn 0 */ /* USER CODE BEGIN SVCall_IRQn 1 */ /* USER CODE END SVCall_IRQn 1 */ } /** * @brief This function handles Debug monitor. */ void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ /* USER CODE END DebugMonitor_IRQn 0 */ /* USER CODE BEGIN DebugMonitor_IRQn 1 */ /* USER CODE END DebugMonitor_IRQn 1 */ } /** * @brief This function handles Pendable request for system service. */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ } /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } /******************************************************************************/ /* STM32F1xx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ /* For the available peripheral interrupt handler names, */ /* please refer to the startup file (startup_stm32f1xx.s). */ /******************************************************************************/ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_hal_msp.c * @brief This file provides code for the MSP Initialization * and de-Initialization codes. ****************************************************************************** * @attention * * Copyright (c) 2025 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" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN Define */ /* USER CODE END Define */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN Macro */ /* USER CODE END Macro */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* External functions --------------------------------------------------------*/ /* USER CODE BEGIN ExternalFunctions */ /* USER CODE END ExternalFunctions */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * Initializes the Global MSP. */ void HAL_MspInit(void) { /* USER CODE BEGIN MspInit 0 */ /* USER CODE END MspInit 0 */ __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); /* System interrupt init*/ /** NOJTAG: JTAG-DP Disabled and SW-DP Enabled */ __HAL_AFIO_REMAP_SWJ_NOJTAG(); /* USER CODE BEGIN MspInit 1 */ /* USER CODE END MspInit 1 */ } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */

/* 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" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* 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 ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; I2C_HandleTypeDef hi2c2; UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); static void MX_I2C2_Init(void); static void MX_USART1_UART_Init(void); static void MX_I2C1_Init(void); /* USER CODE BEGIN PFP */ static void VL6180X_Init(void); //write one byte to VL6180X static HAL_StatusTypeDef VL6180X_WriteByte(uint16_t regAddress, uint8_t data); //read one byte from VL6180X static HAL_StatusTypeDef VL6180X_ReadByte(uint16_t regAddress, uint8_t* data); //get id of VL6180X static uint8_t VL6180X_GetID(void); //get the range from VL6180X static uint8_t VL6180X_GetRange(void); //redirect printf to UART2 int fputc(int ch, FILE* f); void TCS34725_ENABLE(void); uint16_t TCS34725_Get_RawData(I2C_HandleTypeDef *hi2c,uint16_t MemAddress); void Send_RAWData_To_UART(char RGBC, uint16_t RawData); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint8_t buffers; uint8_t buffer[10]={0}; uint16_t Rawdata = 0; /* 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_USART2_UART_Init(); MX_I2C2_Init(); MX_USART1_UART_Init(); MX_I2C1_Init(); /* USER CODE BEGIN 2 */ TCS34725_ENABLE(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ if(VL6180X_GetID()==VL6180X_DEFAULT_ID) VL6180X_Init(); while (1) { HAL_Delay(5000); //¶ÁÈ¡RGBC valid״̬£¬¿´»ý·ÖÊÇ·ñÍê³É HAL_I2C_Mem_Read(&hi2c1,I2C_TCS34725_ADDR<<1|I2C_READ,TCS34725_STATUS_ADDR|TCS34725_CMD_MASK,1,buffer,1,3000); if(buffer[0]&TCS34725__STATUS_AVALID) { //RGBC Valid //Get Clear RAW data Rawdata = TCS34725_Get_RawData(&hi2c1,TCS34725_CDATA_ADDR|TCS34725_CMD_MASK); //Send Clear RAW data to UART Send_RAWData_To_UART('C',Rawdata); //Get RED RAW data Rawdata = TCS34725_Get_RawData(&hi2c1,TCS34725_RDATA_ADDR|TCS34725_CMD_MASK); //Send RED RAW data to UART Send_RAWData_To_UART('R',Rawdata); //Get Green RAW data Rawdata = TCS34725_Get_RawData(&hi2c1,TCS34725_GDATA_ADDR|TCS34725_CMD_MASK); //Send Green RAW data to UART Send_RAWData_To_UART('G',Rawdata); //Get Blue RAW data Rawdata = TCS34725_Get_RawData(&hi2c1,TCS34725_BDATA_ADDR|TCS34725_CMD_MASK); //Send Blue RAW data to UART Send_RAWData_To_UART('B',Rawdata); } while (1) { //get range buffers = VL6180X_GetRange(); printf("Range: %d mm \r\n", buffers); HAL_Delay(3000); /* 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_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 16; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /** * @brief I2C1 Initialization Function * @param None * @retval None */ static void MX_I2C1_Init(void) { /* USER CODE BEGIN I2C1_Init 0 */ /* USER CODE END I2C1_Init 0 */ /* USER CODE BEGIN I2C1_Init 1 */ /* USER CODE END I2C1_Init 1 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ } /** * @brief I2C2 Initialization Function * @param None * @retval None */ static void MX_I2C2_Init(void) { /* USER CODE BEGIN I2C2_Init 0 */ /* USER CODE END I2C2_Init 0 */ /* USER CODE BEGIN I2C2_Init 1 */ /* USER CODE END I2C2_Init 1 */ hi2c2.Instance = I2C2; hi2c2.Init.ClockSpeed = 100000; hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c2.Init.OwnAddress1 = 0; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c2.Init.OwnAddress2 = 0; hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C2_Init 2 */ /* USER CODE END I2C2_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 USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : LD2_Pin */ GPIO_InitStruct.Pin = LD2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /** * @brief Init Vl1680x * @param None * @retval None */ void VL6180X_Init(void) { uint8_t data=0; VL6180X_ReadByte(0x016,&data); if(data ==1) { VL6180X_WriteByte(0x0207, 0x01); VL6180X_WriteByte(0x0208, 0x01); VL6180X_WriteByte(0x0096, 0x00); VL6180X_WriteByte(0x0097, 0xfd); VL6180X_WriteByte(0x00e3, 0x01); VL6180X_WriteByte(0x00e4, 0x03); VL6180X_WriteByte(0x00e5, 0x02); VL6180X_WriteByte(0x00e6, 0x01); VL6180X_WriteByte(0x00e7, 0x03); VL6180X_WriteByte(0x00f5, 0x02); VL6180X_WriteByte(0x00d9, 0x05); VL6180X_WriteByte(0x00db, 0xce); VL6180X_WriteByte(0x00dc, 0x03); VL6180X_WriteByte(0x00dd, 0xf8); VL6180X_WriteByte(0x009f, 0x00); VL6180X_WriteByte(0x00a3, 0x3c); VL6180X_WriteByte(0x00b7, 0x00); VL6180X_WriteByte(0x00bb, 0x3c); VL6180X_WriteByte(0x00b2, 0x09); VL6180X_WriteByte(0x00ca, 0x09); VL6180X_WriteByte(0x0198, 0x01); VL6180X_WriteByte(0x01b0, 0x17); VL6180X_WriteByte(0x01ad, 0x00); VL6180X_WriteByte(0x00ff, 0x05); VL6180X_WriteByte(0x0100, 0x05); VL6180X_WriteByte(0x0199, 0x05); VL6180X_WriteByte(0x01a6, 0x1b); VL6180X_WriteByte(0x01ac, 0x3e); VL6180X_WriteByte(0x01a7, 0x1f); VL6180X_WriteByte(0x0030, 0x00); // Recommended : Public registers - See data sheet for more detail VL6180X_WriteByte(0x0011, 0x10); // Enables polling for new Sample ready when measurement completes VL6180X_WriteByte(0x010a, 0x30); // Set the averaging sample period (compromise between lower noise and increased execution time) VL6180X_WriteByte(0x003f, 0x46); // Sets the light and dark gain (upper nibble). Dark gain should not be changed. VL6180X_WriteByte(0x0031, 0xFF); // sets the # of range measurements after which auto calibration of system is performed VL6180X_WriteByte(0x0040, 0x63); // Set ALS integration time to 100ms VL6180X_WriteByte(0x002e, 0x01); // perform a single temperature calibration of the ranging sensor //Optional: Public registers - See data sheet for more detail VL6180X_WriteByte(0x001b, 0x09); // Set default ranging inter-measurement period to 100ms VL6180X_WriteByte(0x003e, 0x31); // Set default ALS inter-measurement period to 500ms VL6180X_WriteByte(0x0014, 0x24); // Configures interrupt on new Sample Ready threshold event? VL6180X_WriteByte(0x0016, 0x00); } } /** * @brief Read one byte to Vl1680x * @param regAddress: Address to Read * @param data: Point to the memory for data * @retval HAL_StatusTypeDef */ HAL_StatusTypeDef VL6180X_ReadByte(uint16_t regAddress, uint8_t* data) { uint16_t DevAddress=0; DevAddress = (VL6180X_DEFAULT_I2C_ADDR<<1)|1; return HAL_I2C_Mem_Read(&hi2c2, DevAddress, regAddress, VL6180X_REG_ADDRESS_SIZE, data,1,30); } /** * @brief Write one byte to Vl1680x * @param regAddress: Address to write * @param data: Data to be writed * @retval HAL_StatusTypeDef */ HAL_StatusTypeDef VL6180X_WriteByte(uint16_t regAddress, uint8_t data) { uint16_t DevAddress=0; DevAddress = (VL6180X_DEFAULT_I2C_ADDR<<1)&0xFE; return HAL_I2C_Mem_Write(&hi2c2, DevAddress, regAddress, VL6180X_REG_ADDRESS_SIZE, &data,1,30); } /** * @brief Get ID of Vl1680x * @param None * @retval Vl1680x's ID */ uint8_t VL6180X_GetID(void) { uint8_t ID; if(VL6180X_ReadByte( VL6180X_REG_ID, &ID)) ID =0;//get fail, return 0 return ID; } /** * @brief Get result of range * @param None * @retval Result of range */ uint8_t VL6180X_GetRange(void) { uint8_t status,range; //get status VL6180X_ReadByte( VL6180X_REG_RESULT_RANGE_STATUS, &status); while(!(status&0x01)) { //Not ready VL6180X_ReadByte( VL6180X_REG_RESULT_RANGE_STATUS, &status); HAL_Delay(10); } //start range by write 0x01 to SYSRANGE_START Register(0x18) range=1; VL6180X_WriteByte(VL6180X_REG_SYSRANGE_START,range); //Wait for ranging completion VL6180X_ReadByte( VL6180X_REG_RESULT_INTERRUPT_STATUS, &status); while(!(status&0x04)) { VL6180X_ReadByte( VL6180X_REG_RESULT_INTERRUPT_STATUS, &status); HAL_Delay(100); } //get range VL6180X_ReadByte(VL6180X_REG_RESULT_RANGE_VAL,&range); //clear interrupt status VL6180X_WriteByte(VL6180X_REG_SYSTERM_INTERRUPT_CLEAR,0x07); return range; } /** * @brief Redirect fpuc Function to UART2 * @param ch: Data to be send * @param f: Not used * @retval None */ int fputc(int ch, FILE* f) { //HAL¿âÐÎʽ //HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff); //UART register begin while( (huart1.Instance->SR & 0x40) == 0 ); huart1.Instance->DR = ch; //UART register end return ch; } /* 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 */

/********************************************************************************************************* * * File : W25Qx.h * Hardware Environment: * Build Environment : RealView MDK-ARM Version: 5.15 * Version : V1.0 * By : * * (c) Copyright 2005-2015, WaveShare * http://www.waveshare.net * All Rights Reserved * *********************************************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __W25QXX_H #define __W25QXX_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx.h" #include "spi.h" /** @addtogroup BSP * @{ */ /** @addtogroup Components * @{ */ /** @addtogroup W25Q128FV * @{ */ /** @defgroup W25Q128FV_Exported_Types * @{ */ /** * @} */ /** @defgroup W25Q128FV_Exported_Constants * @{ */ /** * @brief W25Q128FV Configuration */ #define W25Q128FV_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ #define W25Q128FV_SECTOR_SIZE 0x10000 /* 256 sectors of 64KBytes */ #define W25Q128FV_SUBSECTOR_SIZE 0x1000 /* 4096 subsectors of 4kBytes */ #define W25Q128FV_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ #define W25Q128FV_DUMMY_CYCLES_READ 4 #define W25Q128FV_DUMMY_CYCLES_READ_QUAD 10 #define W25Q128FV_BULK_ERASE_MAX_TIME 250000 #define W25Q128FV_SECTOR_ERASE_MAX_TIME 3000 #define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME 800 #define W25Qx_TIMEOUT_VALUE 1000 /** * @brief W25Q128FV Commands */ /* Reset Operations */ #define RESET_ENABLE_CMD 0x66 #define RESET_MEMORY_CMD 0x99 #define ENTER_QPI_MODE_CMD 0x38 #define EXIT_QPI_MODE_CMD 0xFF /* Identification Operations */ #define READ_ID_CMD 0x90 #define DUAL_READ_ID_CMD 0x92 #define QUAD_READ_ID_CMD 0x94 #define READ_JEDEC_ID_CMD 0x9F /* Read Operations */ #define READ_CMD 0x03 #define FAST_READ_CMD 0x0B #define DUAL_OUT_FAST_READ_CMD 0x3B #define DUAL_INOUT_FAST_READ_CMD 0xBB #define QUAD_OUT_FAST_READ_CMD 0x6B #define QUAD_INOUT_FAST_READ_CMD 0xEB /* Write Operations */ #define WRITE_ENABLE_CMD 0x06 #define WRITE_DISABLE_CMD 0x04 /* Register Operations */ #define READ_STATUS_REG1_CMD 0x05 #define READ_STATUS_REG2_CMD 0x35 #define READ_STATUS_REG3_CMD 0x15 #define WRITE_STATUS_REG1_CMD 0x01 #define WRITE_STATUS_REG2_CMD 0x31 #define WRITE_STATUS_REG3_CMD 0x11 /* Program Operations */ #define PAGE_PROG_CMD 0x02 #define QUAD_INPUT_PAGE_PROG_CMD 0x32 /* Erase Operations */ #define SECTOR_ERASE_CMD 0x20 #define CHIP_ERASE_CMD 0xC7 #define PROG_ERASE_RESUME_CMD 0x7A #define PROG_ERASE_SUSPEND_CMD 0x75 /* Flag Status Register */ #define W25Q128FV_FSR_BUSY ((uint8_t)0x01) /*!< busy */ #define W25Q128FV_FSR_WREN ((uint8_t)0x02) /*!< write enable */ #define W25Q128FV_FSR_QE ((uint8_t)0x02) /*!< quad enable */ #define W25Qx_Enable() HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET) #define W25Qx_Disable() HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET) #define W25Qx_OK ((uint8_t)0x00) #define W25Qx_ERROR ((uint8_t)0x01) #define W25Qx_BUSY ((uint8_t)0x02) #define W25Qx_TIMEOUT ((uint8_t)0x03) uint8_t BSP_W25Qx_Init(void); static void BSP_W25Qx_Reset(void); static uint8_t BSP_W25Qx_GetStatus(void); uint8_t BSP_W25Qx_WriteEnable(void); void BSP_W25Qx_Read_ID(uint8_t *ID); uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size); uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size); uint8_t BSP_W25Qx_Erase_Block(uint32_t Address); uint8_t BSP_W25Qx_Erase_Chip(void); /** * @} */ /** @defgroup W25Q128FV_Exported_Functions * @{ */ /** * @} */ /** * @} */ /** * @} */ /** * @} */ #ifdef __cplusplus } #endif #endif /* __W25Qx_H */ /********************************************************************************************************* * * File : ws_W25Qx.c * Hardware Environment: * Build Environment : RealView MDK-ARM Version: 4.20 * Version : V1.0 * By : * * (c) Copyright 2005-2011, WaveShare * http://www.waveshare.net * All Rights Reserved * *********************************************************************************************************/ #include "W25QXX.h" /** * @brief Initializes the W25Q128FV interface. * @retval None */ uint8_t BSP_W25Qx_Init(void) { /* Reset W25Qxxx */ BSP_W25Qx_Reset(); return BSP_W25Qx_GetStatus(); } /** * @brief This function reset the W25Qx. * @retval None */ static void BSP_W25Qx_Reset(void) { uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD}; W25Qx_Enable(); /* Send the reset command */ HAL_SPI_Transmit(&hspi1, cmd, 2, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); } /** * @brief Reads current status of the W25Q128FV. * @retval W25Q128FV memory status */ static uint8_t BSP_W25Qx_GetStatus(void) { uint8_t cmd[] = {READ_STATUS_REG1_CMD}; uint8_t status; W25Qx_Enable(); /* Send the read status command */ HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ HAL_SPI_Receive(&hspi1,&status, 1, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); /* Check the value of the register */ if((status & W25Q128FV_FSR_BUSY) != 0) { return W25Qx_BUSY; } else { return W25Qx_OK; } } /** * @brief This function send a Write Enable and wait it is effective. * @retval None */ uint8_t BSP_W25Qx_WriteEnable(void) { uint8_t cmd[] = {WRITE_ENABLE_CMD}; uint32_t tickstart = HAL_GetTick(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /** * @brief Read Manufacture/Device ID. * @param return value address * @retval None */ void BSP_W25Qx_Read_ID(uint8_t *ID) { uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00}; W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ HAL_SPI_Receive(&hspi1,ID, 2, W25Qx_TIMEOUT_VALUE); W25Qx_Disable(); } /** * @brief Reads an amount of data from the QSPI memory. * @param pData: Pointer to data to be read * @param ReadAddr: Read start address * @param Size: Size of data to read * @retval QSPI memory status */ uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) { uint8_t cmd[4]; /* Configure the command */ cmd[0] = READ_CMD; cmd[1] = (uint8_t)(ReadAddr >> 16); cmd[2] = (uint8_t)(ReadAddr >> 8); cmd[3] = (uint8_t)(ReadAddr); W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE); /* Reception of the data */ if (HAL_SPI_Receive(&hspi1, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } W25Qx_Disable(); return W25Qx_OK; } /** * @brief Writes an amount of data to the QSPI memory. * @param pData: Pointer to data to be written * @param WriteAddr: Write start address * @param Size: Size of data to write,No more than 256byte. * @retval QSPI memory status */ uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) { uint8_t cmd[4]; uint32_t end_addr, current_size, current_addr; uint32_t tickstart = HAL_GetTick(); /* Calculation of the size between the write address and the end of the page */ current_addr = 0; while (current_addr <= WriteAddr) { current_addr += W25Q128FV_PAGE_SIZE; } current_size = current_addr - WriteAddr; /* Check if the size of the data is less than the remaining place in the page */ if (current_size > Size) { current_size = Size; } /* Initialize the adress variables */ current_addr = WriteAddr; end_addr = WriteAddr + Size; /* Perform the write page by page */ do { /* Configure the command */ cmd[0] = PAGE_PROG_CMD; cmd[1] = (uint8_t)(current_addr >> 16); cmd[2] = (uint8_t)(current_addr >> 8); cmd[3] = (uint8_t)(current_addr); /* Enable write operations */ BSP_W25Qx_WriteEnable(); W25Qx_Enable(); /* Send the command */ if (HAL_SPI_Transmit(&hspi1,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } /* Transmission of the data */ if (HAL_SPI_Transmit(&hspi1, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK) { return W25Qx_ERROR; } W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE) { return W25Qx_TIMEOUT; } } /* Update the address and size variables for next page programming */ current_addr += current_size; pData += current_size; current_size = ((current_addr + W25Q128FV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25Q128FV_PAGE_SIZE; } while (current_addr < end_addr); return W25Qx_OK; } /** * @brief Erases the specified block of the QSPI memory. * @param BlockAddress: Block address to erase * @retval QSPI memory status */ uint8_t BSP_W25Qx_Erase_Block(uint32_t Address) { uint8_t cmd[4]; uint32_t tickstart = HAL_GetTick(); cmd[0] = SECTOR_ERASE_CMD; cmd[1] = (uint8_t)(Address >> 16); cmd[2] = (uint8_t)(Address >> 8); cmd[3] = (uint8_t)(Address); /* Enable write operations */ BSP_W25Qx_WriteEnable(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() == W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Q128FV_SECTOR_ERASE_MAX_TIME) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /** * @brief Erases the entire QSPI memory.This function will take a very long time. * @retval QSPI memory status */ uint8_t BSP_W25Qx_Erase_Chip(void) { uint8_t cmd[4]; uint32_t tickstart = HAL_GetTick(); cmd[0] = SECTOR_ERASE_CMD; /* Enable write operations */ BSP_W25Qx_WriteEnable(); /*Select the FLASH: Chip Select low */ W25Qx_Enable(); /* Send the read ID command */ HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE); /*Deselect the FLASH: Chip Select high */ W25Qx_Disable(); /* Wait the end of Flash writing */ while(BSP_W25Qx_GetStatus() != W25Qx_BUSY); { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > W25Q128FV_BULK_ERASE_MAX_TIME) { return W25Qx_TIMEOUT; } } return W25Qx_OK; } /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "spi.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stm32f1xx_hal.h" #include <stdio.h> #include <string.h> #include "W25QXX.h" uint8_t wData[0x100]; uint8_t rData[0x100]; uint32_t i; uint8_t ID[2]; extern UART_HandleTypeDef huart1; //声明串口 /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /** * 函数功能: 重定向c库函数printf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; } /** * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart1, &ch, 1, 0xffff); return ch; } /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); MX_SPI1_Init(); /* USER CODE BEGIN 2 */ printf("\r\n SPI-W25Qxxx Example \r\n\r\n"); /*##-1- Read the device ID ########################*/ BSP_W25Qx_Init(); BSP_W25Qx_Read_ID(ID); printf(" W25Qxxx ID is : 0x%02X 0x%02X \r\n\r\n",ID[0],ID[1]); /*##-2- Erase Block ##################################*/ if(BSP_W25Qx_Erase_Block(0) == W25Qx_OK) printf(" SPI Erase Block ok\r\n"); else Error_Handler(); /*##-3- Written to the flash ########################*/ /* fill buffer */ for(i =0;i<0x100;i ++) { wData[i] = i; rData[i] = 0; } if(BSP_W25Qx_Write(wData,0x00,0x100)== W25Qx_OK) printf(" SPI Write ok\r\n"); else Error_Handler(); /*##-4- Read the flash ########################*/ if(BSP_W25Qx_Read(rData,0x00,0x100)== W25Qx_OK) printf(" SPI Read ok\r\n\r\n"); else Error_Handler(); printf("SPI Read Data : \r\n"); for(i =0;i<0x100;i++) printf("0x%02X ",rData[i]); printf("\r\n\r\n"); /*##-5- check date ########################*/ if(memcmp(wData,rData,0x100) == 0 ) printf(" W25Q128FV SPI Test OK\r\n"); else printf(" W25Q128FV SPI Test False\r\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* 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(); } } /* 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 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file gpio.c * @brief This file provides code for the configuration * of all used GPIO pins. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "gpio.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /*----------------------------------------------------------------------------*/ /* Configure GPIO */ /*----------------------------------------------------------------------------*/ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : PtPin */ GPIO_InitStruct.Pin = SPI1_CS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SPI1_CS_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file spi.c * @brief This file provides code for the configuration * of the SPI instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "spi.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ SPI_HandleTypeDef hspi1; /* SPI1 init function */ void MX_SPI1_Init(void) { /* USER CODE BEGIN SPI1_Init 0 */ /* USER CODE END SPI1_Init 0 */ /* USER CODE BEGIN SPI1_Init 1 */ /* USER CODE END SPI1_Init 1 */ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI1_Init 2 */ /* USER CODE END SPI1_Init 2 */ } void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(spiHandle->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspInit 0 */ /* USER CODE END SPI1_MspInit 0 */ /* SPI1 clock enable */ __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA6 ------> SPI1_MISO PA7 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ } } void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) { if(spiHandle->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspDeInit 0 */ /* USER CODE END SPI1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_SPI1_CLK_DISABLE(); /**SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA6 ------> SPI1_MISO PA7 ------> SPI1_MOSI */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); /* USER CODE BEGIN SPI1_MspDeInit 1 */ /* USER CODE END SPI1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file usart.c * @brief This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ 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 */ } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_it.c * @brief Interrupt Service Routines. ****************************************************************************** * @attention * * Copyright (c) 2025 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 "stm32f1xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* 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 */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /******************************************************************************/ /* Cortex-M3 Processor Interruption and Exception Handlers */ /******************************************************************************/ /** * @brief This function handles Non maskable interrupt. */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ while (1) { } /* USER CODE END NonMaskableInt_IRQn 1 */ } /** * @brief This function handles Hard fault interrupt. */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn 0 */ /* USER CODE END W1_HardFault_IRQn 0 */ } } /** * @brief This function handles Memory management fault. */ void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ /* USER CODE END W1_MemoryManagement_IRQn 0 */ } } /** * @brief This function handles Prefetch fault, memory access fault. */ void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_BusFault_IRQn 0 */ /* USER CODE END W1_BusFault_IRQn 0 */ } } /** * @brief This function handles Undefined instruction or illegal state. */ void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ /* USER CODE END W1_UsageFault_IRQn 0 */ } } /** * @brief This function handles System service call via SWI instruction. */ void SVC_Handler(void) { /* USER CODE BEGIN SVCall_IRQn 0 */ /* USER CODE END SVCall_IRQn 0 */ /* USER CODE BEGIN SVCall_IRQn 1 */ /* USER CODE END SVCall_IRQn 1 */ } /** * @brief This function handles Debug monitor. */ void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ /* USER CODE END DebugMonitor_IRQn 0 */ /* USER CODE BEGIN DebugMonitor_IRQn 1 */ /* USER CODE END DebugMonitor_IRQn 1 */ } /** * @brief This function handles Pendable request for system service. */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ } /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } /******************************************************************************/ /* STM32F1xx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ /* For the available peripheral interrupt handler names, */ /* please refer to the startup file (startup_stm32f1xx.s). */ /******************************************************************************/ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_hal_msp.c * @brief This file provides code for the MSP Initialization * and de-Initialization codes. ****************************************************************************** * @attention * * Copyright (c) 2025 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" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN Define */ /* USER CODE END Define */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN Macro */ /* USER CODE END Macro */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* External functions --------------------------------------------------------*/ /* USER CODE BEGIN ExternalFunctions */ /* USER CODE END ExternalFunctions */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * Initializes the Global MSP. */ void HAL_MspInit(void) { /* USER CODE BEGIN MspInit 0 */ /* USER CODE END MspInit 0 */ __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); /* System interrupt init*/ /** NOJTAG: JTAG-DP Disabled and SW-DP Enabled */ __HAL_AFIO_REMAP_SWJ_NOJTAG(); /* USER CODE BEGIN MspInit 1 */ /* USER CODE END MspInit 1 */ } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ 这段代码串口打印出来的都是0x00,是什么原因,要怎么改,使用的芯片为stm32f103rct6,cpol设置为low cpha设置为1Edge,SPI1_sck、SPI1_miso、SPI1_mosi分别对应的引脚为PA5、PA6、PA7

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "tim.h" #include "usart.h" #include "gpio.h" #include "string.h" #include "stdlib.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ uint8_t rx_buf[128]; uint8_t rx_len = 0; uint8_t brightness = 56; uint8_t flag_1s = 0; uint8_t flag_30s = 0; uint8_t flag_rx = 0; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define END_FRAME_MARKER 0x0A /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ void UART_SendString(uint8_t *str) { uint16_t len = strlen((char*)str); HAL_UART_Transmit(&huart1, str, len, 100); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (rx_len < sizeof(rx_buf) - 1) { rx_buf[rx_len++] = *huart->pRxBuffPtr; } HAL_UART_Receive_IT(&huart1, &rx_buf[rx_len], 1); if (rx_buf[rx_len-1] == END_FRAME_MARKER || rx_len >= sizeof(rx_buf)-1) { flag_rx = 1; } } } void HAL_SYSTICK_Callback(void) { static uint32_t tick_1s = 0; static uint32_t tick_30s = 0; tick_1s++; tick_30s++; if (tick_1s >= 1000) { flag_1s = 1; tick_1s = 0; } if (tick_30s >= 30000) { flag_30s = 1; tick_30s = 0; } } void ProcessUARTData(void) { rx_buf[rx_len] = '\0'; if (strstr((char*)rx_buf, "$PFEC,pireq*43") != NULL) { UART_SendString((uint8_t*)"$PFEC,pidat,0,MU-190*69\r\n"); UART_SendString((uint8_t*)"$PFEC,musts,1,306,29,1,2,60,64.0,1,4124,,,4661,,*71\r\n"); UART_SendString((uint8_t*)"$PFEC,pidat,1,2651020-01.03*56\r\n"); UART_SendString((uint8_t*)"$PFEC,pidat,3,001822*6E\r\n"); } else if (strstr((char*)rx_buf, "$ECDDC") != NULL) { char *start = strstr((char*)rx_buf, ",,") + 2; if (start != NULL) { uint8_t new_brightness = atoi(start); if (new_brightness >= 1 && new_brightness <= 99) { brightness = new_brightness; __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, brightness * 10); char resp[32]; sprintf(resp, "$IIDDC,,%02d,,R*12\r\n", brightness); UART_SendString((uint8_t*)resp); } } } rx_len = 0; flag_rx = 0; memset(rx_buf, 0, sizeof(rx_buf)); } /* 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_TIM2_Init(); MX_USART1_UART_Init(); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, brightness * 10); HAL_UART_Receive_IT(&huart1, rx_buf, 1); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ if (flag_1s) { UART_SendString((uint8_t*)"$PFEC,musts,1,306,29,1,2,60,64.0,1,4124,,,4661,,*71\r\n"); flag_1s = 0; } if (flag_30s) { char resp[32]; sprintf(resp, "$IIDDC,,%02d,,R*12\r\n", brightness); UART_SendString((uint8_t*)resp); flag_30s = 0; } if (flag_rx) { ProcessUARTData(); } HAL_Delay(10); } /* 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(); } } /* 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 */ 这是完整代码,我要你根据代码解决问题,为什么发送$PFEC,pireq*43\r\n没有回复

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *
© Copyright (c) 2025 STMicroelectronics. * All rights reserved.
* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "can.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "Can_receive.h" #include "motor.h" #include "ano.h" #include "pid.h" #include "bsq_can.h" /* 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 ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ // uint32_t run_cnt = 0; uint8_t i; //电机速度pid环 PID_Typedef pid_speed[4]; //电机位置pid环 PID_Typedef pid_position[4]; //各个电机数据 const motor_measure_t *motor_data[4]; //pid初始化,电机参数设为默认参数 for(int di=0;di < 4;di++) { // pid_init(&pid_speed[di]); pid_init(&pid_position[di]); //对模式,最大输出,最大积分,死区,最大差距,目标值,kp,ki,kd初始化 pid_speed[di].f_param_init(&pid_speed[di],POSITION_PID,10000,2015,0,0,0,0.220f,0.0f,0.f); pid_position[di].f_param_init(&pid_position[di],POSITION_PID,10000,1000,0,0,0,0.2f,0.f,0.f); } //初始化期望位置,速度,电流为0 float set_position[4] = {0}; \ /* 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_CAN1_Init(); MX_USART2_UART_Init(); MX_TIM3_Init(); MX_TIM4_Init(); /* USER CODE BEGIN 2 */ can_filter_init(); //配置CAN滤波器 HAL_CAN_Start(&hcan1); //配置CAN总开关 HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); //获取各电机的状态值 motor_data[0] = get_chassis_motor_measure_point(0);//获取ID为1号的电机数据指针 motor_data[1] = get_chassis_motor_measure_point(1);//获取ID为2号的电机数据指针 motor_data[2] = get_chassis_motor_measure_point(2);//获取ID为3号的电机数据指针 motor_data[3] = get_chassis_motor_measure_point(3);//获取ID为4号的电机数据指针 float num=313; set_position[0]=num*8192; set_position[2]=-num*8192; /*********************************Tim*********************************/ //开启定时器中断 HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_3); HAL_TIM_PWM_Start_IT(&htim4,TIM_CHANNEL_4); //开启定时器3的pwm输出(用于舵机旋转) HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2); //拉高dir1_pin引脚 //dir1_pin对应的是PA1引脚,dir2_pin对应的是PA4引脚 HAL_GPIO_WritePin(dir1_pin_GPIO_Port,dir1_pin_Pin , GPIO_PIN_RESET); HAL_GPIO_WritePin(dir2_pin_GPIO_Port,dir2_pin_Pin , GPIO_PIN_SET); /*********************判断参数声明***********************/ //左边爪子的判断参数 volatile int left_turn = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ for(i=0;i<=2;i++) { //位置环 //计算出期望转速 pid_calc(&pid_position[i],motor_data[i]->total_angle,set_position[i]); //速度环 //计算出期望电流 pid_calc(&pid_speed[i],motor_data[i]->speed_rpm,pid_position[i].output); CAN_cmd_chassis(pid_speed[0].output,pid_speed[1].output,pid_speed[2].output,pid_speed[3].output); } Data_send(motor_data[2]->total_angle,motor_data[2]->speed_rpm,set_position[2],left_turn); /***************舵机*************/ //Angle对应的是舵机旋转的角度 //40是两边爪子抓紧箱子的角度,随角度变大,爪子张角变大 float Angle_left_down = 80 ; __HAL_TIM_SET_COMPARE (&htim3,TIM_CHANNEL_1,Angle_left_down/180*2000+500); //目前85度左右时两边爪子正好对准板上箱子的角度,175度是爪子旋转后放下的角度 float Angle_left_up = 175 ; __HAL_TIM_SET_COMPARE (&htim3,TIM_CHANNEL_2,Angle_left_up/180*2000+500); } /* 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 = 4; RCC_OscInitStruct.PLL.PLLN = 168; 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(); } } /* USER CODE BEGIN 4 */ //17.7是中间那个爪子跑完全程对应的电机所转的圈数 //Stepper_Motor意为步进电机 float Stepper_Motor_PWM_count3 = 0,Stepper_Motor_PWM_count4 = 0 ; //n表示步进电机的圈数 float n = 0.1; void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { //TIM4的通道3 //一开始cube中pulse参数设置了250才转动 if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) { if(Stepper_Motor_PWM_count3 <800*n) { Stepper_Motor_PWM_count3++; } else { //停止定时器 htim4的通道3的 PWM 输出并禁用相关中断 //必须开启tim_4 global interuption HAL_TIM_PWM_Stop_IT(&htim4, TIM_CHANNEL_3); //define 1 抓取箱子 left_turn = 1; Stepper_Motor_PWM_count3 = 0; } } //TIM4的通道4 if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) { if(Stepper_Motor_PWM_count4 <800*n) { Stepper_Motor_PWM_count4++; } else { //停止定时器 htim4的通道4的 PWM 输出并禁用相关中断 //必须开启tim_4 global interuption HAL_TIM_PWM_Stop_IT(&htim4, TIM_CHANNEL_4); Stepper_Motor_PWM_count4 = 0; } } } /* 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 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 为什么lest_turn = 1;这一行有问题

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *
© Copyright (c) 2022 CSTX. * All rights reserved.
* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "usart.h" #include "gpio.h" #include "dht11.h" #include "adc.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include "string.h" #include "oled.h" /* 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 ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ #define SDATA "ToggleLED\r\n" unsigned char cscxReg[3]={0xC1,0x00,0x09}; //发送查询数据 unsigned char csrevReg[12]={0xC1 ,0x00 ,0x09 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF, 0xFF ,0xFF ,0xFF}; unsigned char key=0; unsigned char disOLED[24]; char disUART[128]; float adcValue = 0; int main(void) { /* USER CODE BEGIN 1 */ uint16_t ADC_Value = 0; /* USER CODE END 1 */ int i ; /* 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_USART2_UART_Init(); MX_ADC1_Init(); /* USER CODE BEGIN 2 */ USART_Interupt_Enable(); //使能串口接收中断和空闲中断 HAL_ADCEx_Calibration_Start(&hadc1); //AD校准 printf("\r\n ############ http://www.csgsm.com/ ############\r\n ############("__DATE__ " - " __TIME__ ")############\r\n"); printf("LORA Board LED OK\r\n"); CS_OLED_Init(); OLED_Clear(); OLED_ShowString(16,0,"LoRa"); OLED_ShowCHinese(48,0,7);OLED_ShowCHinese(64,0,8);OLED_ShowCHinese(80,0,9); printf("LORA Board LCD OK\r\n"); /* USER CODE END 2 */ OLED_ShowString(100,0,"[A]"); cstxInitialize(); //初始化LED 闪烁下 if(HAL_GPIO_ReadPin(M1_GPIO_Port, M1_Pin) == 1) //M1 是高电平才开始读取模块的寄存器 { printf("\r\n M1 = 1 ; M0 = 0 Register mode \r\n"); CS_Reg_Send_Data(cscxReg,3);//发送3个字节 HAL_Delay(300); //等待延迟 printf("\r\n\r\nLORA REG CODE %d UART2->",regConut); for(i=0;i<12;i++) { printf("%02X",USART2_RX_BUF[i]); printf(" "); } cstx_reg_Receive_Data(csrevReg,&key); printf("\r\n\r\nLORA REG CODE %d REG->",key); memset(disOLED,0,24); for(i=0;i<12;i++) { printf("%02X",csrevReg[i]); printf(" "); } OLED_ShowString(0,2,"Addr:"); for(i=3;i<5;i++) //显示 { sprintf((char *)disOLED,"%02X",csrevReg[i]); printf("disOLED=%s,",disOLED); OLED_ShowString(i*16-4,2,disOLED); } OLED_ShowString(82,2,"Ch:"); sprintf((char *)disOLED,"%02X",csrevReg[8]); printf("disOLED=%s\r\n",disOLED); OLED_ShowString(104,2,disOLED); } else { printf("\r\n M1 = 0; M0 = 0 Transparent mode \r\n"); } /* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_GPIO_WritePin(M1_GPIO_Port, M1_Pin, GPIO_PIN_RESET); //使能模块运行 PA1 OLED_ShowString(0,6,"Read DHT11 ....."); if(DHT11_READ_DATA() == 1) { printf("\r\n ***Read DHT11 Succeed*** \r\n"); OLED_ShowString(0,6,"Read DHT11 [OK]."); } else { printf("\r\n ***Read DHT11 failure*** \r\n"); OLED_ShowString(0,6,"Read DHT11 [NO]."); } while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ OLED_ShowString(0,4,"Send data ......"); HAL_ADC_Start(&hadc1); //启动ADC转换 HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,时间为50ms if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) { ADC_Value = HAL_ADC_GetValue(&hadc1); //获取AD值 //printf("读取电压为 : %.1f V\r\n",ADC_Value*3.3f/4096); memset(disOLED,0,24); adcValue = (float)ADC_Value*3.3f/4096; sprintf((char *)disOLED,"ADCPA4:%d,%.1f",ADC_Value,adcValue); OLED_ShowString(0,2," "); OLED_ShowString(0,2,disOLED); } if(DHT11_READ_DATA() == 1) { printf("\r\n Read DHT11 Succeed \r\n"); //A,56.0,19.9,3.3 USART2_printf("1,%d.%d%,%d.%d,%.1f",Dht11data[0],Dht11data[1],Dht11data[2],Dht11data[3],adcValue); memset(disOLED,0,24); sprintf((char *)disOLED,"T:%d.%dC H:%d.%d",Dht11data[2],Dht11data[3],Dht11data[0],Dht11data[1]); OLED_ShowString(0,6," "); OLED_ShowString(0,6,disOLED); printf("\r\n ***Send DHT11: %s *** \r\n", disOLED); OLED_ShowString(0,4,"Send data [OK].."); HAL_Delay(1000); } //LORA发送过来的数据 if(USART2_RX_STA == REC_OK) { OLED_ShowString(0,6,"Wait data [OK].."); printf("\r\n<--Receive Date: %s \r\n\r\n",USART2_RX_BUF); //通过电脑来接收 memset(USART2_RX_BUF,0,USART_REC_LEN); USART2_RX_STA = 0; } } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 8; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; 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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } /** Initializes the peripherals clocks */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* 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 */ /************************ (C) COPYRIGHT CSTX *****END OF FILE****/ 通过uart1在电脑的串口助手上打印与oled上一样的内容

根据以下程序,分别概括成几个模块的软件设计:#include "stm32f10x.h" #include "1602.h" #include "math.h" typedef unsigned char u8_t; typedef signed char s8_t; typedef unsigned short u16_t; typedef signed short s16_t; typedef unsigned long u32_t; typedef signed long s32_t; //位带操作,实现51类似的GPIO控制功能 //具体实现思想,参考<<CM3权威指南>>第五章(87页~92页). //IO口操作宏定义 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只对单一的IO口! //确保n的值小于16! #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入 #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入 #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入 //以下为汇编函数 void WFI_SET(void); //执行WFI指令 void INTX_DISABLE(void);//关闭所有中断 void INTX_ENABLE(void); //开启所有中断 void MSR_MSP(u32 addr); //设置堆栈地址 #define EnableINT() INTX_ENABLE() #define DisableINT() INTX_DISABLE() static u8 fac_us=0; //us延时倍乘数 static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数 void delay_init() { #if SYSTEM_SUPPORT_OS //如果需要支持OS. u32 reload; #endif SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 #if SYSTEM_SUPPORT_OS //如果需要支持OS. reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为M reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间 //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK #else fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 #endif } //延时nus //nus为要延时的us数. void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //时间加载 SysTick->VAL=0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void USART1_init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO , ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //USART1 USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); USART_ClearITPendingBit(USART1, USART_IT_RXNE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_ITConfig(USART1, USART_IT_PE, ENABLE); USART_ITConfig(USART1, USART_IT_ERR, ENABLE); USART1->DR = (0X55 & (uint16_t)0x01FF); while((USART1->SR&0X40)==0); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void UsartSendData1(unsigned char *send_buff,unsigned long int length) { unsigned long int i = 0; delay_ms(1); for(i = 0;i < length;i ++) { USART1->DR = (send_buff[i] & (uint16_t)0x01FF); while((USART1->SR&0X40)==0); } delay_ms(1); } int GQ=0;//保存光强 int LX=0;//光类型 0白光 1黄光 2混合光 int DW=0;//档位 0~5档 int LPWM=0;//亮度 0~100 int moshi=0;//0手动 1自动 2声控 #define LED_B PBout(8) #define LED_H PBout(7) #define C_YR PBin(6) void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //ENABLEPBCLK GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //Disable jtag RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //LCD1602 管脚 D0~D7 双向I/O GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOA, &GPIO_InitStructure); //ADC GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); //LCD1602 管脚 控制 推挽模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |GPIO_Pin_13|GPIO_Pin_14; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); //按键 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); //LED灯 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* ADC配置 */ void ADC_Set(unsigned char ch) { ADC_InitTypeDef ADC_InitStructure;//ADC结构体变量//注意在一个语句快内变量的声明要放在可执行语句的前面,否则出错,因此要放在ADC1_GPIO_Config();前面 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //使能扫描 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在连续模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制转换,不使用外部触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1;//转换通道为1 ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC if(ch == ADC_Channel_7) { ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_239Cycles5); } if(ch == ADC_Channel_6) { ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_239Cycles5); } ADC_Cmd(ADC1, ENABLE);//使能ADC1 ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } #define ADC_TIMES 10 #define ADCLOST 2 unsigned int GetADC(unsigned char ch) { unsigned int i, j; unsigned int buf[ADC_TIMES]; unsigned long int sum; long int temp; static long int XQ = 0; ADC_Set(ch); for(i=0; i < ADC_TIMES; i++) { buf[i] = ADC_GetConversionValue(ADC1);; delay_ms(10); } for(i = 0; i < ADC_TIMES - 1; i++) { for(j = i + 1; j < ADC_TIMES; j++) { if(buf[i] > buf[j]) { temp = buf[i]; } } } sum = 0; for(i = ADCLOST; i < ADC_TIMES - ADCLOST; i++) { sum += buf[i]; } temp = sum / (ADC_TIMES - 2 * ADCLOST); if( (XQ>=temp && (XQ-temp)<=1 ) || (XQ<temp && (temp-XQ)<=1)) { temp = XQ; } else { XQ = temp; } return (unsigned int)(temp>>4); } void Display_1(int T1,int T2,int T3,int T4,int T5) { char xx=0,yy=0; //光强 WrByte1602(yy,xx++,'G'); //. WrByte1602(yy,xx++,'Q'); WrByte1602(yy,xx++,'='); WrByte1602(yy,xx++,T1%1000/100+'0'); WrByte1602(yy,xx++,T1%100/10+'0'); WrByte1602(yy,xx++,T1%10+'0'); WrByte1602(yy,xx++,' '); //光类型 WrByte1602(yy,xx++,'T'); //. WrByte1602(yy,xx++,'Y'); WrByte1602(yy,xx++,'P'); WrByte1602(yy,xx++,'E'); WrByte1602(yy,xx++,'-'); if(T2==0)//0混合 1白光 2黄光 { WrByte1602(yy,xx++,'B'); WrByte1602(yy,xx++,'H'); } else if(T2==1)//0混合 1白光 2黄光 { WrByte1602(yy,xx++,'B'); WrByte1602(yy,xx++,' '); } else if(T2==2)//0混合 1白光 2黄光 { WrByte1602(yy,xx++,'H'); WrByte1602(yy,xx++,' '); } WrByte1602(yy,xx++,' '); xx=0,yy=1; //档位 WrByte1602(yy,xx++,'D'); //. WrByte1602(yy,xx++,'W'); WrByte1602(yy,xx++,'='); WrByte1602(yy,xx++,T3%10+'0'); WrByte1602(yy,xx++,' '); //亮度 WrByte1602(yy,xx++,'L'); //. WrByte1602(yy,xx++,'D'); WrByte1602(yy,xx++,'='); WrByte1602(yy,xx++,T4%1000/100+'0'); WrByte1602 if(T5==0)//0手动 1自动 2声控 { WrByte1602(yy,xx++,'S'); WrByte1602(yy,xx++,'D'); } else if(T5==1)//0手动 1自动 2声控 { WrByte1602(yy,xx++,'Z'); WrByte1602(yy,xx++,'D'); } else if(T5==2)//0手动 1自动 2声控 { WrByte1602(yy,xx++,'S'); WrByte1602(yy,xx++,'K'); } WrByte1602(yy,xx++,' '); } //int GQ=0;//保存光强 //int LX=0;//光类型 0白光 1黄光 2混合光 //int DW=0;//档位 0~5档 //int LPWM=0;//亮度 0~100 //int moshi=0;//0手动 1自动 2声控 void anjiansaom(void) { static uchar K1,K2,K3; static uchar K1Flag=0,K2Flag=0,K3Flag=0; K1 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_9); K2 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_11); K3 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_10); //手动/自动 if(K1==0) { K1Flag = 1; } else { if(K1Flag) { K1Flag = 0; if(moshi==1||moshi==2)//0手动 1自动 2声控 { moshi=0; } else { moshi=1; } } } //亮度 if(K2==0) { K2Flag = 1; } else { if(K2Flag) { K2Flag = 0; if(moshi==0)//0手动 1自动 2声控 { DW++; if(DW>5) { DW=0; } LPWM=DW*20; } } } { if(K3Flag) { K3Flag = 0; //光类型 0白光 1黄光 2混合光 LX++; if(LX>2) { LX=0; } } } } void TimerConfig(TIM_TypeDef* TIMx,unsigned long int time) { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2,ENABLE); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3,ENABLE); TIM_DeInit(TIMx); TIM_TimeBaseStructure.TIM_Period = time * 2; /* 自动重装载寄存器周期的值(计数值) */ /* 累计 TIM_Period个频率后产生一个更新或者中断 */ TIM_TimeBaseStructure.TIM_Prescaler= (1000- 1); /* 时钟预分频数 例如:时钟频率=72MHZ/(时钟预分频+1) */ TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */ TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */ TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); TIM_ClearFlag(TIMx, TIM_FLAG_Update); /* 清除溢出中断标志 */ TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStr NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief 关闭或者开启指定定时器 * @param TIMx: where x can be 1 to 17 to select the TIM peripheral * @param NewState: new state of the TIMx peripheral. * This parameter can be: ENABLE or DISABLE. * @retval None */ void TimerSW( TIM_TypeDef* TIMx, FunctionalState NewState ) { TIM_SetCounter(TIMx,0); TIM_Cmd(TIMx,NewState); } int main(void) { float temp; SystemInit(); SystemCoreClockUpdate(); delay_init(); //引脚配置 GPIO_Configuration(); //关闭LED灯 LED_B=0; LED_H=0; delay_ms(1000); //初始化LCD1602 Init1602(); TimerConfig(TIM2,1); TimerSW(TIM2, ENABLE); //串口初始化 USART1_init(); while (1) { delay_ms(20); //读取ADC的值,然后计算光强 ADC_Set(0); //光强 //先读取ADC值 GQ =(255-GetADC(0))/2-60; if(GQ<0) { GQ=0; } GQ = GQ*2; if(GQ>100) { GQ = 100; } //按键扫描 anjiansaom(); //光强 光类型 档位 亮度 模式 Display_1(GQ,LX,DW,LPWM,moshi); //自动模式光强控制 //首先得有人才会亮 if(moshi==1) { if(C_YR==1 )//传感器输出高电平代表有人 { //根据亮度计算光亮 //越暗 越亮 LPWM=100-GQ; } else { LPWM=0;//关灯 } } } } /** * @brief 定时器2中断服务函数 * @param TIMx: where x can be 1 to 17 to select the TIM peripheral * @param NewState: new state of the TIMx peripheral. * This parameter can be: ENABLE or DISABLE. * @retval None */ void TIM2_IRQHandler(void) { static int i=0; if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) { TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); // PCout(13)=~PCout(13); //这里实现PWM 波形的产生 i++; if(i<=LPWM) { //开灯 //暖光 还是白光 还是混合 if(LX==0)//0混合 1白光 2黄光 { } } else { //关灯 LED_B=0;LED_H=0; } //不能超过100 if(i>100) { i=0; } } } //串口1接收中断 void USART1_IRQHandler(void) { char shuju=0; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_RXNE); //保存收到的数据 shuju=USART_ReceiveData(USART1); //读取接收到的数据 //收到数据1 //你好小灯 唤醒 if(shuju==1)//进入声控模式 { moshi=2; } if(moshi==2) { //收到数据2 //开灯 if(shuju==2)//开灯 { if(LPWM==0) { DW=3; LPWM=DW*20; } } else if(shuju==3)//关灯 { DW=0; LPWM=DW*20; } else if(shuju==4)//亮一点 { DW++; if(DW>5) } } } if(USART_GetITStatus(USART1, USART_IT_PE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_PE); } if (USART_GetFlagStatus(USART1, USART_IT_LBD) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_LBD); } if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) { USART_ReceiveData(USART1); USART_ClearFlag(USART1, USART_FLAG_ORE); } if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET) { USART_ClearFlag(USART1, USART_FLAG_NE); } if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET) { USART_ClearFlag(USART1, USART_FLAG_FE); } if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET) { USART_ClearFlag(USART1, USART_FLAG_PE); } if (USART_GetITStatus(USART1, USART_IT_TC) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_TC); } } #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 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) */ /* Infinite loop */ while (1) {} } #endif /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ #include "stm32f10x.h" #include "1602.h" #define uchar unsigned char #define uint unsigned int uchar ASCII[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//2 /* PA8~PA15为数据口 */ #define LCD1602_RS_0 GPIO_ResetBits(GPIOB , GPIO_Pin_12) #define LCD1602_RS_1 GPIO_SetBits(GPIOB , GPIO_Pin_12) #define LCD1602_RW_0 GPIO_ResetBits(GPIOB , GPIO_Pin_13) #define LCD1602_RW_1 GPIO_SetBits(GPIOB , GPIO_Pin_13) #define LCD1602_EN_0 GPIO_ResetBits(GPIOB , GPIO_Pin_14) #define LCD1602_EN_1 GPIO_SetBits(GPIOB , GPIO_Pin_14) #define LCD1602_D0_0 GPIO_ResetBits(GPIOB , GPIO_Pin_15) #define LCD1602_D0_1 GPIO_SetBits(GPIOB , GPIO_Pin_15) #define LCD1602_D1_0 GPIO_ResetBits(GPIOA , GPIO_Pin_8) #define LCD1602_D1_1 GPIO_SetBits(GPIOA , GPIO_Pin_8) #define LCD1602_D2_0 GPIO_ResetBits(GPIOA , GPIO_Pin_11) #define LCD1602_D2_1 GPIO_SetBits(GPIOA , GPIO_Pin_11) #define LCD1602_D3_0 GPIO_ResetBits(GPIOA , GPIO_Pin_12) #define LCD1602_D3_1 GPIO_SetBits(GPIOA , GPIO_Pin_12) #define LCD1602_D4_0 GPIO_ResetBits(GPIOA , GPIO_Pin_15) #define LCD1602_D4_1 GPIO_SetBits(G #define LCD1602_D6_0 GPIO_ResetBits(GPIOB , GPIO_Pin_4) #define LCD1602_D6_1 GPIO_SetBits(GPIOB , GPIO_Pin_4) #define LCD1602_D7_0 GPIO_ResetBits(GPIOB , GPIO_Pin_5) #define LCD1602_D7_1 GPIO_SetBits(GPIOB , GPIO_Pin_5) #define GET_LCD1602_D0 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_15) #define GET_LCD1602_D1 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_8) #define GET_LCD1602_D2 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_11) #define GET_LCD1602_D3 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_12) #define GET_LCD1602_D4 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_15) #define GET_LCD1602_ void SetLCD1602DValue(unsigned char value) { if(value&0x01) { LCD1602_D0_1; } else { LCD1602_D0_0; } if(value&0x02) { LCD1602_D1_1; } { LCD1602_D2_1; } else { LCD1602_D2_0; } if(value&0x08) { LCD1602_D3_1; } else { LCD1602_D3_0; } if(value&0x10) { LCD1602_D4_1; } else { LCD1602_D4_0; } if(value&0x20) { LCD1602_D5_1; } else { LCD1602_D5_0; } if(value&0x40) if(value&0x80) { LCD1602_D7_1; } else { LCD1602_D7_0; } } unsigned char GetLCD1602DValue(void) { unsigned char dat; dat = 0x00; if(GET_LCD1602_D0) { dat = dat |0x01; } if(GET_LCD1602_D1) { dat = dat |0x02; } if(GET_LCD1602_D2) { dat = dat |0x04; } if(GET_LCD1602_D3) { dat = dat |0x08; } if(GET_LCD1602_D4) { dat = dat |0x10; } if(GET_LCD1602_D5) { dat = dat |0x20; } if(GET_LCD1602_D6) { dat = dat |0x40; } if(GET_LCD1602_D7) { dat = dat |0x80; } return(dat); } /*******************通用延时子程序**************************/ void mDelay(uint i) { for (;i>0;i--) {uchar j=10;while(--j);} } void LCD1602DTest(void) { LCD1602_RS_1; LCD1602_RW_1; LCD1602_EN_1; SetLCD1602DValue(0x00); mDelay(100); mDelay(100); LCD1602_EN_0; SetLCD1602DValue(0xFF); mDelay(100); mDelay(100); LCD1602_RS_0; LCD1602_RW_0; LCD1602_EN_0; SetLCD1602DValue(0x00); } /************************************************************* 函数名称:读忙状态子函数 全局变量:无 参数说明:无 返回说明:无 版 本:1.0 说 明:读取LCD1602忙状态 **************************************************************/ void Read1602() //读忙状态 { long int i=90000; //建一个循环变量避免器件发生故障停在这里 SetLCD1602DValue(0xff); LCD1602_RS_0; LCD1602_RW_1; //设置LCD为读取数据状态 LCD1602_EN_1; //使能LCD,高电平 while ((i--)&&(GetLCD1602DValue()&0x80)); //检测数据口最高位状态,为0则空闲 LCD1602_EN_0; //关闭使能 } /************************************************************** 函数名称:写操作子函数 全局变量:无 参数说明:Dat为数据,command为指令(1为写数据,0为写指令) 返回说明:无 版 本:1.0 说 明:往LCD1602写入数据、指令 ***************************************************************/ void Write1602(uchar Dat,unsigned char command) { Read1602(); SetLCD1602DValue(Dat); if(command) { LCD1602_RS_1; //RS为1写数据、为0写指令 } else { LCD1602_RS_0; } LCD1602_RW_0; //RW为低,进行写操作 LCD1602_EN_1; LCD1602_EN_0; //E端控制一个高脉冲 } /*************************************************************** 函数名称:LCD1602初始化子函数 全局变量:无 参数说明:无 返回说明:无 版 本:1.0 说 明:设置工作模式、清屏、开显示 ***************************************************************/ void Init1602(void) { LCD1602DTest(); mDelay(10); mDelay(10); Write1602(0x38,0); //8位点阵方式 mDelay(10); Write1602(0x38,0); mDelay(10); Write1602(0x38,0); mDelay(10); Write1602(0x38,0); mDelay(10); Write1602(0x01,0); //清屏 mDelay(10); Write1602(0x0c,0); //开显示,光标不显示 } void WrByte1602_EX(uchar x,uchar y,uchar dat) { Write1602(0x80+(x<<6)+y,0); //合并生成地址 Write1602(dat,1); //写入数据 } void WrByte1602(uchar x,uchar y,uchar dat) { Write1602(0x80+(x<<6)+y,0); //合并生成地址 Write1602(dat,1); //写入数据 } /*************************************************************** 函数名称:LCD1602整行字符串写入子函数 全局变量:无 参数说明:x为写入的行(0或1),*p为写入的字符串数组 返回说明:无 版 本:1.0 说 明:在LCD1602任意行写入字符串 ****************************************************************/ void LCD_Write_String(uchar x1,uchar x,uchar *p) { x1 = 1; Write1602(0x80+(x<<6),0); //合并生成行首地址 while(*p) {Write1602(*p,1);p++;} //逐个字符写入 } #include "stm32f10x.h" #include "1602.h" #define uchar unsigned char #define uint unsigned int uchar ASCII[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//2 /* PA8~PA15为数据口 */ #define LCD1602_RS_0 GPIO_ResetBits(GPIOB , GPIO_Pin_12) #define LCD1602_RS_1 GPIO_SetBits(GPIOB , GPIO_Pin_12) #define LCD1602_RW_0 GPIO_ResetBits(GPIOB , GPIO_Pin_13) #define LCD1602_RW_1 GPIO_SetBits(GPIOB , GPIO_Pin_13) #define LCD1602_EN_0 GPIO_ResetBits(GPIOB , GPIO_Pin_14) #define LCD1602_EN_1 GPIO_SetBits(GPIOB , GPIO_Pin_14) #define LCD1602_D0_0 GPIO_ResetBits(GPIOB , GPIO_Pin_15) #define LCD1602_D0_1 GPIO_SetBits(GPIOB , GPIO_Pin_15) #define LCD1602_D1_0 GPIO_ResetBits(GPIOA , GPIO_Pin_8) #define LCD1602_D1_1 GPIO_SetBits(GPIOA , GPIO_Pin_8) #define LCD1602_D2_0 GPIO_ResetBits(GPIOA , GPIO_Pin_11) #define LCD1602_D2_1 GPIO_SetBits(GPIOA , GPIO_Pin_11) #define LCD1602_D3_0 GPIO_ResetBits(GPIOA , GPIO_Pin_12) #define LCD1602_D3_1 GPIO_SetBits(GPIOA , GPIO_Pin_12) #define LCD1602_D4_0 GPIO_ResetBits(GPIOA , GPIO_Pin_15) #define LCD1602_D4_1 GPIO_SetBits(GPIOA , GPIO_Pin_15) #define LCD1602_D5_0 GPIO_ResetBits(GPIOB , GPIO_Pin_3) #define LCD1602_D5_1 GPIO_SetBits(GPIOB , GPIO_Pin_3) #define LCD1602_D6_0 GPIO_ResetBits(GPIOB , GPIO_Pin_4) #define LCD1602_D6_1 GPIO_SetBits(GPIOB , GPIO_Pin_4) #define LCD1602_D7_0 GPIO_ResetBits(GPIOB , GPIO_Pin_5) #define LCD1602_D7_1 GPIO_SetBits(GPIOB , GPIO_Pin_5) #define GET_LCD1602_D0 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_15) #define GET_LCD1602_D1 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_8) #define GET_LCD1602_D2 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_11) #define GET_LCD1602_D3 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_12) #define GET_LCD1602_D4 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_15) #define GET_LCD1602_D5 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_3) #define GET_LCD1602_D6 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_4) #define GET_LCD1602_D7 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_5) void SetLCD1602DValue(unsigned char value) { if(value&0x01) { LCD1602_D0_1; } else { LCD1602_D0_0; } if(value&0x02) { LCD1602_D1_1; } else { LCD1602_D1_0; } if(value&0x04) { LCD1602_D2_1; } else { LCD1602_D2_0; } if(value&0x08) { LCD1602_D3_1; } else { LCD1602_D3_0; } if(value&0x10) { LCD1602_D4_1; } else { LCD1602_D4_0; } if(value&0x20) { LCD1602_D5_1; } else { LCD1602_D5_0; } if(value&0x40) { LCD1602_D6_1; } else { LCD1602_D6_0; } if(value&0x80) { LCD1602_D7_1; } else { LCD1602_D7_0; } } unsigned char GetLCD1602DValue(void) { unsigned char dat; dat = 0x00; if(GET_LCD1602_D0) { dat = dat |0x01; } if(GET_LCD1602_D1) { dat = dat |0x02; } if(GET_LCD1602_D2) { dat = dat |0x04; } if(GET_LCD1602_D3) { dat = dat |0x08; } if(GET_LCD1602_D4) { dat = dat |0x10; } if(GET_LCD1602_D5) { dat = dat |0x20; } if(GET_LCD1602_D6) { dat = dat |0x40; } if(GET_LCD1602_D7) { dat = dat |0x80; } return(dat); } /*******************通用延时子程序**************************/ void mDelay(uint i) { for (;i>0;i--) {uchar j=10;while(--j);} } void LCD1602DTest(void) { LCD1602_RS_1; LCD1602_RW_1; LCD1602_EN_1; SetLCD1602DValue(0x00); mDelay(100); mDelay(100); LCD1602_RS_0; LCD1602_RW_0; LCD1602_EN_0; SetLCD1602DValue(0xFF); mDelay(100); mDelay(100); LCD1602_RS_0; LCD1602_RW_0; LCD1602_EN_0; SetLCD1602DValue(0x00); } /************************************************************* 函数名称:读忙状态子函数 全局变量:无 参数说明:无 返回说明:无 版 本:1.0 说 明:读取LCD1602忙状态 **************************************************************/ void Read1602() //读忙状态 { long int i=90000; //建一个循环变量避免器件发生故障停在这里 SetLCD1602DValue(0xff); LCD1602_RS_0; LCD1602_RW_1; //设置LCD为读取数据状态 LCD1602_EN_1; //使能LCD,高电平 while ((i--)&&(GetLCD1602DValue()&0x80)); //检测数据口最高位状态,为0则空闲 LCD1602_EN_0; //关闭使能 } /************************************************************** 函数名称:写操作子函数 全局变量:无 参数说明:Dat为数据,command为指令(1为写数据,0为写指令) 返回说明:无 版 本:1.0 说 明:往LCD1602写入数据、指令 ***************************************************************/ void Write1602(uchar Dat,unsigned char command) { Read1602(); SetLCD1602DValue(Dat); if(command) { LCD1602_RS_1; //RS为1写数据、为0写指令 } else { LCD1602_RS_0; } LCD1602_RW_0; //RW为低,进行写操作 LCD1602_EN_1; LCD1602_EN_0; //E端控制一个高脉冲 } /*************************************************************** 函数名称:LCD1602初始化子函数 全局变量:无 参数说明:无 返回说明:无 版 本:1.0 说 明:设置工作模式、清屏、开显示 ***************************************************************/ void Init1602(void) { LCD1602DTest(); mDelay(10); mDelay(10); Write1602(0x38,0); //8位点阵方式 mDelay(10); Write1602(0x38,0); mDelay(10); mDelay(10); Write1602(0x01,0); //清屏 mDelay(10); Write1602(0x0c,0); //开显示,光标不显示 } void WrByte1602_EX(uchar x,uchar y,uchar dat) { Write1602(0x80+(x<<6)+y,0); //合并生成地址 Write1602(dat,1); //写入数据 } void WrByte1602(uchar x,uchar y,uchar dat) { Write1602(0x80+(x<<6)+y,0); //合并生成地址 Write1602(dat,1); //写入数据 } /*************************************************************** 函数名称:LCD1602整行字符串写入子函数 全局变量:无 参数说明:x为写入的行(0或1),*p为写入的字符串数组 返回说明:无 版 本:1.0 说 明:在LCD1602任意行写入字符串 ****************************************************************/ void LCD_Write_String(uchar x1,uchar x,uchar *p) { x1 = 1; Write1602(0x80+(x<<6),0); //合并生成行首地址 while(*p) {Write1602(*p,1);p++;} //逐个字符写入 }

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "adc.h" #include "dac.h" #include "dma.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "arm_math.h" #include "arm_const_structs.h" #include <stdio.h> #include "stm32f4xx_hal.h" // 包含HAL库头文件 /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define FFT_LENGTH 1024 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ __IO uint8_t AdcConvEnd = 0; uint16_t adcBuff[FFT_LENGTH];//存放ADC采集的数据 float fft_inputbuf[FFT_LENGTH * 2]; //输入时域信号 float fft_outputbuf[FFT_LENGTH]; //输出频域信号 /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_DAC_Init(); MX_TIM6_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ //HAL_ADCEx_Calibration_Start(&hadc1);//ADC采集部分 HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adcBuff, FFT_LENGTH); HAL_TIM_Base_Start(&htim6); printf("123456\n"); //printf("FFT Result:\r\n");//打印结果 while (!AdcConvEnd) //等待转换完毕 ; for (int i = 0; i < FFT_LENGTH; i++)//进行傅里叶变换 { fft_inputbuf[i * 2] = adcBuff[i] * 3.3 / 4096;//实部赋值,* 3.3 / 4096是为了将ADC采集到的值转换成实际电压 fft_inputbuf[i * 2 + 1] = 0;//虚部赋值,固定为0. } arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_inputbuf, 0, 1);//进行傅里叶变换,0正变换,1反变换 arm_cmplx_mag_f32(fft_inputbuf, fft_outputbuf, FFT_LENGTH); //输入信号转换成输出信号 fft_outputbuf[0] /= 1024;//处理变换结果 for (int i = 1; i < FFT_LENGTH; i++)//输出各次谐波幅值 { fft_outputbuf[i] /= 512; } //printf("FFT Result:\r\n");//打印结果 for (int i = 0; i < FFT_LENGTH; i++)//输出各次谐波幅值 { // printf("%d:\t%.2f\r\n", i, fft_outputbuf[i]); printf("%f\n",fft_outputbuf[i]); } /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* 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_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 168; 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE BEGIN 4 */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc == &hadc1) { AdcConvEnd = 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 */ 上面代码在VOFA+没有波形怎么回事

/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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 "adc.h" #include "dma.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include <string.h> #include "OLED.h" #include "arm_math.h" /* 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 ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ #define FFT_LENGTH 256 arm_cfft_radix4_instance_f32 scfft; float FFT_InputBuf[FFT_LENGTH*2]; float FFT_OutputBuf[FFT_LENGTH]; uint16_t ADC_1_Value_DMA[256] = {0}; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); HAL_TIM_Base_Start_IT(&htim3); uint32_t x=20230; uint32_t y=4020527; OLED_ShowNum(1,1,x,5); OLED_ShowNum(1,6,y,7); arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_ADC_Start_DMA(&hadc, (uint32_t*)ADC_1_Value_DMA, FFT_LENGTH); HAL_TIM_Base_Start(&htim3); // //加汉宁窗 // #define PI 3.1415926f // for(int i=0; i < FFT_LENGTH; i++) { // float hann = 0.5f - 0.5f * arm_cos_f32(2*PI*i/(FFT_LENGTH-1)); // FFT_InputBuf[2*i] = (ADC_1_Value_DMA[i] - 2048) * hann; // FFT_InputBuf[2*i+1] = 0; // } for(int i=0; i < FFT_LENGTH; i++) { FFT_InputBuf[2*i]=ADC_1_Value_DMA[i]; FFT_InputBuf[2*i+1]=0; } arm_cfft_radix4_f32(&scfft,FFT_InputBuf); arm_cmplx_mag_f32(FFT_InputBuf,FFT_OutputBuf,FFT_LENGTH); FFT_OutputBuf[0] /= FFT_LENGTH; for (int i = 1; i < FFT_LENGTH; i++) { FFT_OutputBuf[i] /= (FFT_LENGTH / 2); } uint32_t max_index = 0; float32_t max_value = 0; for(uint32_t i=1; i<FFT_LENGTH/4; i++) { if(FFT_OutputBuf[i] > max_value) { max_value = FFT_OutputBuf[i]; max_index = i; } } float32_t delta = 0.0f; if(max_index > 1 && max_index < FFT_LENGTH-1) { delta = 0.5f * (FFT_OutputBuf[max_index+1] - FFT_OutputBuf[max_index-1]); delta /= (FFT_OutputBuf[max_index] - 0.5f * (FFT_OutputBuf[max_index-1] + FFT_OutputBuf[max_index+1])); } float32_t sampling_frequency = 48000.0f; // 48kHz float32_t frequency = (max_index + delta) * sampling_frequency / FFT_LENGTH; float32_t threshold = 0.1f * FFT_OutputBuf[0]; if(max_value < threshold || max_index == 0) { frequency = 0.0f; } char freq_str[20]; if(frequency > 50 && frequency < 20000) { sprintf(freq_str, "F:%5.1fHz", frequency); } else { strcpy(freq_str, "F: --- "); } OLED_ShowString(2, 1, freq_str); // printf("Index: %3lu, Freq: %6.1fHz, Value: %.2f\n", // max_index, frequency, max_value); // HAL_Delay(200); // 打印频谱数据(仅前128点) for(int i = 0; i < 128; i++) { printf("%.4f,%6.1f\r\n", FFT_OutputBuf[i],frequency); } // /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSI14State = RCC_HSI14_ON; RCC_OscInitStruct.HSI14CalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; 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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* 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 */ 做到这一步怎么去在vofa上显示频谱

最新推荐

recommend-type

学籍管理系统C语言实训报告.doc

学籍管理系统C语言实训报告.doc
recommend-type

东北大学2021年9月《计算机基础》作业考核试题及答案参考17.docx

东北大学2021年9月《计算机基础》作业考核试题及答案参考17.docx
recommend-type

如何做好软件销售及企业管理软件销售就业机会.doc

如何做好软件销售及企业管理软件销售就业机会.doc
recommend-type

基于单片机的恒流开关电源-新.doc

基于单片机的恒流开关电源-新.doc
recommend-type

基石油长输管道SCADA系统设计与研究的开题报告.docx

基石油长输管道SCADA系统设计与研究的开题报告.docx
recommend-type

全面解析SOAP库包功能与应用

从给定的文件信息中,我们可以提取到的核心知识点主要集中在“SOAP”这一项技术上,由于提供的信息量有限,这里将尽可能详细地解释SOAP相关的知识。 首先,SOAP代表简单对象访问协议(Simple Object Access Protocol),是一种基于XML的消息传递协议。它主要用于在网络上不同应用程序之间的通信。SOAP定义了如何通过HTTP和XML格式来构造消息,并规定了消息的格式应遵循XML模式。这种消息格式使得两个不同平台或不同编程语言的应用程序之间能够进行松耦合的服务交互。 在分布式计算环境中,SOAP作为一种中间件技术,可以被看作是应用程序之间的一种远程过程调用(RPC)机制。它通常与Web服务结合使用,Web服务是使用特定标准实现的软件系统,它公开了可以通过网络(通常是互联网)访问的API。当客户端与服务端通过SOAP进行通信时,客户端可以调用服务端上特定的方法,而不需要关心该服务是如何实现的,或者是运行在什么类型的服务器上。 SOAP协议的特点主要包括: 1. **平台无关性**:SOAP基于XML,XML是一种跨平台的标准化数据格式,因此SOAP能够跨越不同的操作系统和编程语言平台进行通信。 2. **HTTP协议绑定**:虽然SOAP协议本身独立于传输协议,但是它通常与HTTP协议绑定,这使得SOAP能够利用HTTP的普及性和无需额外配置的优势。 3. **消息模型**:SOAP消息是交换信息的载体,遵循严格的结构,包含三个主要部分:信封(Envelope)、标题(Header)和正文(Body)。信封是消息的外壳,定义了消息的开始和结束;标题可以包含各种可选属性,如安全性信息;正文则是实际的消息内容。 4. **错误处理**:SOAP提供了详细的错误处理机制,可以通过错误码和错误信息来描述消息处理过程中的错误情况。 5. **安全性和事务支持**:SOAP协议可以集成各种安全性标准,如WS-Security,以确保消息传输过程中的安全性和完整性。同时,SOAP消息可以包含事务信息,以便于服务端处理事务性的业务逻辑。 在描述中提到的“所有库包”,这可能意味着包含了SOAP协议的实现、相关工具集或库等。由于信息不足,这里的“库包”具体指的是什么并不清楚,但可以理解为与SOAP相关的软件开发工具包(SDK)或框架,它们使得开发者可以更加方便地创建SOAP消息,处理SOAP请求和响应,以及实现Web服务。 至于“压缩包子文件的文件名称列表”中只有一个单词“soap”,这可能表明实际文件内容仅有一个与SOAP相关的文件,或者是一个压缩包文件的名称为“soap”。由于缺乏更详尽的文件列表,无法进一步分析其可能的内容。 综上所述,SOAP作为一种实现Web服务的技术标准,通过HTTP和XML实现系统间的通信。它支持跨平台、跨语言的服务调用,并具备强大的安全性和错误处理机制。在具体应用中,开发者可能需要用到与之相关的库包或工具集来开发和部署Web服务。
recommend-type

编程语言选择指南:为不同项目量身定制的编程语言策略

# 摘要 选择合适的编程语言对于软件项目的成功至关重要。本文首先探讨了编程语言选择的重要性,并对不同分类和特点的编程语言进行了详尽分析,重点介绍了静态与动态类型、解释型与编译型、面向对象与函数式编程语言的区别和应用场景。接着,文章根据项目需求详细讨论了如何选择适合的编程语言,包括功能需求、性能考量、开发效率和团队技能等关键因素。通过实践案例分析,本文进一步探讨了不同
recommend-type

手写vue2的插件vue-router

<think>我们正在手写一个简化版的vue-router插件,用于Vue2。主要步骤:1.定义一个类VueRouter,包含路由映射、当前路由状态等。2.实现install方法,用于Vue.use()安装插件,在install方法中:-混入beforeCreate生命周期钩子,在组件创建时初始化router。-全局注册router-view和router-link组件。3.实现路由映射:将路由配置转换为路径与组件的映射表。4.监听hashchange事件(或者使用history模式,这里以hash模式为例)来响应路由变化。5.实现router-view组件,根据当前路由渲染对应组件。6.实现
recommend-type

《软件工程:实践者的方法》第6版课件解析

根据提供的文件信息,我们可以推断出以下知识点: 1. 课程名称:“SOFTWARE ENGINEERING A practitioner's approach 6e”,表明这是关于软件工程的课程教材,第6版,针对实践者的教学方法。 2. 版本信息:由于标题中明确指出是第6版(6e),我们知道这是一系列教科书或课件的最新版本,这意味着内容已经根据最新的软件工程理论和实践进行了更新和改进。 3. 课程类型:课程是针对“practitioner”,即实践者的,这表明教材旨在教授学生如何将理论知识应用于实际工作中,注重解决实际问题和案例学习,可能包含大量的项目管理、需求分析、系统设计和测试等方面的内容。 4. 适用范围:文件描述中提到了“仅供校园内使用”,说明这个教材是专为教育机构内部学习而设计的,可能含有某些版权保护的内容,不允许未经授权的外部使用。 5. 标签:“SOFTWARE ENGINEERING A practitioner's approach 6e 软件工程”提供了关于这门课程的直接标签信息。标签不仅重复了课程名称,还强化了这是关于软件工程的知识。软件工程作为一门学科,涉及软件开发的整个生命周期,从需求收集、设计、编码、测试到维护和退役,因此课程内容可能涵盖了这些方面。 6. 文件命名:压缩包文件名“SftEng”是“SOFTWARE ENGINEERING”的缩写,表明该压缩包包含的是软件工程相关的教材或资料。 7. 关键知识点:根据标题和描述,我们可以推测课件中可能包含的知识点有: - 软件工程基础理论:包括软件工程的定义、目标、原则和软件开发生命周期的模型。 - 需求分析:学习如何获取、分析、记录和管理软件需求。 - 系统设计:涉及软件架构设计、数据库设计、界面设计等,以及如何将需求转化为设计文档。 - 实现与编码:包括编程语言的选择、代码编写规范、版本控制等。 - 测试:软件测试的原则、方法和测试用例的设计。 - 项目管理:时间管理、团队协作、风险管理、成本估算等与软件项目成功相关的管理活动。 - 质量保证:软件质量模型、质量度量和质量控制措施。 - 维护和演化:软件部署后如何进行持续维护、升级和系统退役。 - 软件工程的新兴领域:包括敏捷开发方法、DevOps、用户体验设计等现代软件开发趋势。 8. 版权和使用限制:由于是专供校园内使用的教材,课件可能包含版权声明和使用限制,要求用户在没有授权的情况下不得对外传播和用于商业用途。 综上所述,这门课程的课件是为校园内的学生和教职员工设计的,关于软件工程的全面教育材料,覆盖了理论知识和实践技巧,并且在版权方面有所限制。由于是最新版的教材,它很可能包含了最新的软件工程技术和方法论。
recommend-type

QUARTUS II 13.0全攻略:新手到专家的10个必备技能

# 摘要 本文旨在详细介绍QUARTUS II 13.0软件的使用,包括其安装、FPGA基础、项目设置、设计流程、高级功能应用