#define _DAT_H /* ------------------------------------------------------------- */ /* ----------------- Declaration of System Constants ----------- */ /* ------------------------------------------------------------- */ /* Local System Constant SIGQLY_FROZEN */ /* SIGQLY_FROZEN Typ=uint16 */ #ifndef SIGQLY_FROZEN #define SIGQLY_FROZEN (32L) #elif (SIGQLY_FROZEN != (32L)) #error >>>> 'SIGQLY_FROZEN' multiple defined #endif /* Local System Constant SIGQLY_INIT */ /* SIGQLY_INIT Typ=uint16 */ #ifndef SIGQLY_INIT #define SIGQLY_INIT (2L) #elif (SIGQLY_INIT != (2L)) #error >>>> 'SIGQLY_INIT' multiple defined #endif #undef _DAT_H

时间: 2025-05-31 07:50:07 浏览: 20
### 宏定义的用途及重复定义检查逻辑 #### 1. 宏定义的作用 宏定义是一种预处理器指令,主要用于在编译前替换代码中的某些标识符或表达式。它的主要作用包括但不限于简化复杂表达式的书写、提高代码可读性和一致性以及控制条件编译等[^3]。 例如,可以通过简单的宏定义来表示常量数值: ```c #define PI 3.1415926 ``` 这样在整个程序中都可以使用 `PI` 而不必每次都输入完整的圆周率近似值。 更进一步地说,还可以创建带参数的宏以便模拟小型函数的行为: ```c #define SQUARE(x) ((x)*(x)) ``` 需要注意的是,尽管看起来像常规方法调用,但实际上它们只是简单文本替代,并不具备真正的运行期行为特性如类型安全验证等功能[^4]。 #### 2. 防止重复定义的方法——头文件卫士 为了避免在一个项目里不同地方分别包含相同头文件所造成的实体多重声明问题(即所谓的“重复定义”),一般采用所谓“include guards”技术,也就是常说的“头文件保护”。具体做法是在每一个`.h`文件顶部加入如下形式的一组语句: ```c #ifndef SIGQLY_FROZEN #define SIGQLY_FROZEN // 此处放置实际要保护起来的内容... #endif /* SIGQLY_FROZEN */ ``` 这里的`SIGQLY_FROZEN`是一个独一无二的名字空间内的标记名,确保即使该头文件被多个源文件间接引用也不会再次展开其中心体部分[^5]。 同样地,对于另一个例子`SIGQLY_INIT`,也可以按照这种方式来进行预防性的包裹处理: ```c #ifndef SIGQLY_INIT #define SIGQLY_INIT // 这里的内容只会被执行一次... #endif /* SIGQLY_INIT */ ``` 以上机制依靠C/C++预处理器的功能实现了基本却非常有效的防重措施。只要遵循这一模式编写所有的公共头部文档,就可以大大降低遭遇此类错误的风险。 --- ### 示例代码片段说明 下面给出一段综合应用了上述概念的小型示范案例: 假设有一个名为`config.h`的配置头文件,里面含有若干全局设定项;另外还有一个辅助工具类库对应的接口描述文件叫做`utils.h`. #### config.h ```c #ifndef CONFIG_H_ #define CONFIG_H_ #define MAX_CONNECTIONS 1024 // 最大连接数限制 #define DEFAULT_TIMEOUT 30 // 默认超时时间(秒) #endif /* CONFIG_H_ */ ``` #### utils.h ```c #ifndef UTILS_H_ #define UTILS_H_ #include "config.h" void initialize_system(); bool is_connection_valid(int conn_id); #endif /* UTILS_H_ */ ``` 在这个场景下,无论多少个.cpp/.cc文件最终都需要牵涉到这两个头文件之一甚至两者皆有之情形下,都不会因为单纯增加额外的`#include`行而导致任何冲突现象出现。 ---
阅读全文

相关推荐

******************************************************************************* * 函 数 名 : KEY_Init * 函数功能 : 按键初始化 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin=KEY1_PIN|KEY2_PIN|KEY3_PIN|KEY4_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入 GPIO_Init(KEY_PORT,&GPIO_InitStructure); }将这段代码加入到/* 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 "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #define KEY1_PIN GPIO_Pin_6 #define KEY2_PIN GPIO_Pin_7 #define KEY3_PIN GPIO_Pin_8 #define KEY4_PIN GPIO_Pin_9 #define KEY_PORT GPIOB //使用位操作定义 #define KEY1 PBin(6) #define KEY2 PBin(7) #define KEY3 PBin(8) #define KEY4 PBin(9) //定义各个按键值 #define KEY1_PRESS 1 #define KEY2_PRESS 2 #define KEY3_PRESS 3 #define KEY4_PRESS 4 //矩阵按键端口 #define KEY_MATRIX_PORT_OUT(dat) GPIO_Write(GPIOA,dat) #define KEY_MATRIX_PORT_READ GPIO_ReadInputData(GPIOA) /* 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 */ float accumulator = 0.0; // 累加器,用于存储计算结果 float currentNumber = 0.0; // 当前输入的数字 char operation = '\0'; // 当前操作符 int decimalPointPressed = 0; // 小数点按键状态 char displayBuffer[16]; // 显示缓冲区 /* 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(); /* USER CODE BEGIN 2 */ /* 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_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_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; 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_1) != 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 : 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 "gpio.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 */ #define SCL_H HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_SET); #define SCL_L HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_RESET); #define SDA_H HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_SET); #define SDA_L HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_RESET); #define SDA_R HAL_GPIO_ReadPin(SDA_GPIO_Port,SDA_Pin) #define IIC_DELAY HAL_Delay(1); #define OLED_CMD 0 #define OLED_DATA 1 #define LCD_ADDR 0x78 #define CMD_WRITE 0x00 #define DATA_WRITE 0x40 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ void iicack() { SDA_L SCL_H IIC_DELAY SCL_L SDA_H } void iicwaitack(void) { SDA_H IIC_DELAY SCL_H IIC_DELAY SCL_L IIC_DELAY } //start void iicstart() { SDA_H SCL_H IIC_DELAY SDA_L IIC_DELAY SDA_L IIC_DELAY } //stop void iicstop() { SDA_L SCL_H IIC_DELAY SDA_H IIC_DELAY } //fashuju void iicfashuju(uint8_t byte) { for(int i=0;i<8;i++) { if(byte & 0x80) { SDA_H } else { SDA_L } SCL_H IIC_DELAY; SCL_L byte <<=1; } iicwaitack(); } //dushuju uint8_t iccdushuju() { uint8_t i,byte = 0; for(i=0;i<8;i++) { byte<<=1; SCL_H if(SDA_R) { byte|=0x01; } IIC_DELAY SCL_L } return byte; } void oled_wr_byte(uint8_t dat,uint8_t mode) { iicstart(); iicfashuju(0x78); iicwaitack(); if(mode) { iicfashuju(0x40); }else{ iicfashuju(0x00); } iicwaitack(); iicfashuju(dat); iicwaitack(); iicstop(); } void OLDE_lint(void) { oled_wr_byte(0XAE,OLED_CMD); oled_wr_byte(0X00,OLED_CMD); oled_wr_byte(0X10,OLED_CMD); oled_wr_byte(0X40,OLED_CMD); oled_wr_byte(0X81,OLED_CMD); oled_wr_byte(0XCF,OLED_CMD); oled_wr_byte(0XA1,OLED_CMD); oled_wr_byte(0XC8,OLED_CMD); oled_wr_byte(0XA6,OLED_CMD); oled_wr_byte(0XA8,OLED_CMD); oled_wr_byte(0X3F,OLED_CMD); oled_wr_byte(0XD3,OLED_CMD); oled_wr_byte(0X00,OLED_CMD); oled_wr_byte(0XD5,OLED_CMD); oled_wr_byte(0X80,OLED_CMD); oled_wr_byte(0XD9,OLED_CMD); oled_wr_byte(0XF1,OLED_CMD); oled_wr_byte(0XDA,OLED_CMD); oled_wr_byte(0X12,OLED_CMD); oled_wr_byte(0XDB,OLED_CMD); oled_wr_byte(0X30,OLED_CMD); oled_wr_byte(0X20,OLED_CMD); oled_wr_byte(0X02,OLED_CMD); oled_wr_byte(0X8D,OLED_CMD); oled_wr_byte(0X14,OLED_CMD); oled_wr_byte(0XAF,OLED_CMD); } void LCD_Write_Cmd(uint8_t cmd) { iicstart(); iicfashuju(LCD_ADDR); iicfashuju(cmd); iicstop(); } // ???? void LCD_Write_Data(uint8_t data) { iicstart(); iicfashuju(LCD_ADDR); iicfashuju(DATA_WRITE); iicfashuju(data); iicstop(); } void LCD_Init() { HAL_Delay(50); LCD_Write_Cmd(0xE2); HAL_Delay(10); LCD_Write_Cmd(0xA2); LCD_Write_Cmd(0x89); LCD_Write_Cmd(0xC0); LCD_Write_Cmd(0x2F); LCD_Write_Cmd(0xF8); LCD_Write_Cmd(0x00); LCD_Write_Cmd(0x27); LCD_Write_Cmd(0x5C); LCD_Write_Cmd(0xAC); LCD_Write_Cmd(0x01); LCD_Write_Cmd(0xAF); HAL_Delay(100); } /* 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(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ // HAL_Init(); // SystemClock_Config(); // MX_GPIO_Init(); // LCD_Init(); OLDE_lint(); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ // iicstart(); // iicfashuju(0X78); // iicfashuju(0X40); // iicfashuju(0XAF); // //iicfashuju(0XA5); // iicstop(); // // oled_wr_byte(0XAF,OLED_CMD); 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}; /** 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 = 72; 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_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 */

#include "main.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* 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 */ uint8_t Tx_str1[]="Hello world!\r\n"; uint8_t Tx_str2[]="LED1 Open!\r\n"; uint8_t Tx_str3[]="LED1 Close!\r\n"; uint8_t Rx_dat=0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1) { if(Rx_dat==0xa1) { HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET); HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),10000); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_RESET); HAL_UART_Receive_IT(&huart1,&Rx_dat,1); } else if(Rx_dat==0xa2) { HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET); HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),10000); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_RESET); HAL_UART_Receive_IT(&huart1,&Rx_dat,1); } } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),10000); HAL_UART_Receive_IT(&huart1,&Rx_dat,1); // HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET); // // HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET); // // HAL_UART_Receive_IT(&huart1,&Rx_dat,1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } 为什么上述代码无法实现接收功能?

#include "zf_common_headfile.h" // *************************** 例程测试说明 *************************** // 1.久久派与主板使用54pin排线连接 再将久久派插到主板上面 主板使用电池供电 下载本例程 // // 2.打开终端可以看到: // read_u16_dat = 1234567 // read_float_dat = 1.234560 // // 3.按下按键即可看到不同的输出状态 // // **************************** 代码区域 **************************** // 对于linux来说,一切皆文件,所以存储参数,也是通过文件的。 // 这里我们只是简单的演示下,如何使用。 #define FILENAME_U16 "parameter_u16.txt" #define FILENAME_FLOAT "parameter_float.txt" uint32 write_u16_dat = 1234567; float write_float_dat = 1.23456; uint32 read_u16_dat = 0; float read_float_dat = 0; int main(int, char**) { // ---------- 写入并读取整数 ---------- // // 设置临时buffer char buffer[100] = {0}; // 将需要写入的数组,以字符串的方式存放到数组中 sprintf(buffer, "%d", write_u16_dat); // 文件写 file_write_string(FILENAME_U16, buffer); // 清空buffer memset(buffer, 0, sizeof(buffer)); // 读取字符串 file_read_string(FILENAME_U16, buffer); // 这里的atoi是将字符转化为整数。 // 如果是浮点数需要使用atof read_u16_dat = atoi(buffer); printf("read_u16_dat = %d\r\n", read_u16_dat); // ---------- 写入并读取整数 ---------- // // ---------- 写入并读取浮点数 ---------- // // 将需要写入的数组,以字符串的方式存放到数组中 sprintf(buffer, "%f", write_float_dat); // 文件写 file_write_string(FILENAME_FLOAT, buffer); // 清空buffer memset(buffer, 0, sizeof(buffer)); // 读取字符串 file_read_string(FILENAME_FLOAT, buffer); // 这里的atof是将字符转化为浮点数。 // 如果是整数需要使用atoi read_float_dat = atof(buffer); printf("read_float_dat = %f\r\n", read_float_dat); // ---------- 写入并读取浮点数 ---------- // }

/******************************************************************************* _________ __________ __ \_ ___ \ / _____/ \ / \ / \ \// \ __\ \/\/ / \ \___\ \_\ \ / \______ /\______ /\__/\ / \/ \/ \/ 修订历史: - V1.0 (2024):初版 *******************************************************************************/ #ifndef __RF_TX_H_GF__ #define __RF_TX_H_GF__ /******************************************************************************* 头文件*/ #include "config.h" /******************************************************************************* * * * * * * * 私有 * * * * * * * *******************************************************************************/ /******************************************************************************* 端口*/ #define RFDAT PB4 /******************************************************************************* RF-1527兼容协议配置,不要修改!*/ #if(__TIME_MODE==0) //100us #define RFLOGIC_LOW 4 //逻辑信号下限,400us #define RFLOGIC_HIGH 12 //逻辑信号上限,1200us #define RFSTART 110 //起始信号,11ms #elif(__TIME_MODE==1) //50us #define RFLOGIC_LOW 8 //逻辑信号下限,400us #define RFLOGIC_HIGH 24 //逻辑信号上限,1200us #define RFSTART 220 //起始信号,11ms #elif(__TIME_MODE==2) //40us #define RFLOGIC_LOW 10 //逻辑信号下限,400us #define RFLOGIC_HIGH 30 //逻辑信号上限,1200us #define RFSTART 254 //起始信号,10.16ms #endif /******************************************************************************* 端口低电平*/ inline void rf_gpio_low(void) { RFDAT = 0; } /******************************************************************************* 端口高电平*/ inline void rf_gpio_high(void) { RFDAT = 1; } /******************************************************************************* *功能描述:发送1字节 *输入参数:dat - 要发送的数据 *输出参数:发送完毕返回1,否则返回0 *全局变量:空 *******************************************************************************/ uint8_t rf_send_byte(uint8_t dat) { static uint8_t sw = 0; //状态 static uint8_t i = 0; //时序宽度 static uint8_t bit_num = 0; //位置 uint8_t temp; i++; temp = dat << bit_num; switch (sw) { case 0: //前 rf_gpio_high(); if (temp & 0x80) { if (i >= RFLOGIC_HIGH) { //宽 i = 0; sw = 1; } } else if (i >= RFLOGIC_LOW) { //窄 i = 0; sw = 1; } break; case 1: //后 rf_gpio_low(); if (temp & 0x80) { if (i >= RFLOGIC_LOW) { //窄 i = 0; sw = 0; bit_num++; } } else if (i >= RFLOGIC_HIGH) { //宽 i = 0; sw = 0; bit_num++; } break; } if (bit_num > 7) { bit_num = 0; return 1; } return 0; } /******************************************************************************* * * * * * * * 接口 * * * * * * * *******************************************************************************/ /******************************************************************************* *功能描述:发送一帧RF1527数据,非阻塞式 *输入参数:addr1 - 地址1,addr2 - 地址2,dat - 数据 *输出参数:进行中返回0,完成返回1 *全局变量:空 *******************************************************************************/ uint8_t rf_tx(uint8_t addr1, uint8_t addr2, uint8_t dat) { static uint8_t sw = 0; static uint8_t i = 0; uint8_t rf_ok = 0; switch (sw) { case 0: rf_gpio_high(); if (++i > RF_LOGIC_LOW) { i = 0; sw = 1; } break; case 1: rf_gpio_low(); if (++i > RF_LOGIC_LOW) { i = 0; sw = 2; } break; case 2: rf_gpio_high(); if (++i > RF_LOGIC_LOW) { i = 0; sw = 3; } break; case 3: rf_gpio_low(); if (++i >= RF_START) { i = 0; sw = 4; } break; case 4: if (rf_send_byte(addr1)) sw = 5; break; case 5: if (rf_send_byte(addr2)) sw = 6; break; case 6: if (rf_send_byte(dat)) sw = 7; break; case 7: rf_gpio_high(); sw = 0; rf_ok = 1; break; } return rf_ok; } #endif // !__RF_TX_H_GF__ 你还有更好的实现吗?代码占用要尽可能的小

/************************ 头文件与宏定义 ************************/ #include <REG51.H> // 8051 核心寄存器定义 #include <intrins.h> // 用于 _nop_() 延时(可选) // --------- 硬件引脚宏定义(需与原理图严格对应!)--------- #define SEG_PORT P0 // 数码管段选口(D0~D7) #define KEY_PORT P3 // 按键输入口(假设 K1=P3^2, K2=P3^3) #define K1_PIN 2 // K1 对应 P3 引脚位 #define K2_PIN 3 // K2 对应 P3 引脚位 // --------- 6264 RAM 控制宏定义(需与硬件原理图对应!)--------- #define RAM_WR P3^6 // 6264 写控制(WR) #define RAM_RD P3^7 // 6264 读控制(RD) #define RAM_CS P2^7 // 6264 片选(CS),示例用 P2^7 作为片选 #define RAM_ADDR_H P2 // 6264 高 8 位地址(A8~A15),低 8 位与 P0 复用 #define RAM_ADDR_L P0 // 6264 低 8 位地址(A0~A7),与数据口复用 // --------- 数码管段码表(共阴/共阳需调整!)--------- // 0~9 段码,假设数码管为共阴:0x3f=0, 0x06=1... (共阳则取反:0xc0=0 等) unsigned char code SEG_TABLE[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; /************************ 全局变量 ************************/ unsigned char num = 0; // 存储设置的两位数(0~99) bit is_tens = 1; // 标记当前修改十位(1)或个位(0),初始十位 /************************ 函数声明 ************************/ void Delay_ms(unsigned int ms); // 毫秒级延时(简单实现) void Display_Num(void); // 数码管显示当前 num void Key_Scan(void); // 按键扫描与处理 void Write_RAM(unsigned int addr, unsigned char dat); // 写 6264 RAM /************************ 主函数 ************************/ void main(void) { SEG_PORT = 0x00; // 初始化数码管全灭 while(1) { // 主循环 Key_Scan(); // 扫描按键 Display_Num(); // 持续显示当前数值 } } /************************ 函数实现 ************************/ /** * @brief 简单延时函数(软件延时,精度依赖编译器与晶振) * @param ms: 延时毫秒数(建议结合实际晶振调整循环次数) */ void Delay_ms(unsigned int ms) { unsigned int i, j; for(i=0; i<ms; i++) { for(j=0; j<120; j++) { // 约 1ms@12MHz(需根据实际晶振校准) _nop_(); } } } /** * @brief 数码管显示当前 num(两位数:十位+个位) * @note 假设数码管为静态显示(或需改为动态扫描,根据硬件调整) */ void Display_Num(void) { unsigned char tens, units; tens = num / 10; // 拆分十位 units = num % 10; // 拆分个位 // 若为多位数码管动态扫描,需分时选通位选口,此处简化为静态(假设硬件直接驱动两位) SEG_PORT = SEG_TABLE[tens]; // 输出十位段码 Delay_ms(1); // 短暂延时保持显示(动态扫描需更复杂逻辑) SEG_PORT = SEG_TABLE[units]; // 输出个位段码 Delay_ms(1); } /** * @brief 按键扫描与处理逻辑 * K1:切换十位/个位,递增数值(0~9 循环) * K2:触发写入 6264 RAM */ void Key_Scan(void) { static bit key1_flag = 0, key2_flag = 0; // 消抖标志 // --------- K1 处理:调整数值 --------- if((KEY_PORT & (1<<K1_PIN)) == 0) { // K1 按下(低电平有效,需看硬件上拉/下拉) if(key1_flag == 0) { // 首次检测到按键 key1_flag = 1; Delay_ms(20); // 消抖延时 if((KEY_PORT & (1<<K1_PIN)) == 0) { // 确认按下 if(is_tens) { // 修改十位 num = (num / 10 + 1) % 10 * 10 + (num % 10); } else { // 修改个位 num = (num / 10) * 10 + (num % 10 + 1) % 10; } is_tens = !is_tens; // 切换十位/个位标记 } } } else { key1_flag = 0; // 按键释放,清除标志 } // --------- K2 处理:写入 6264 --------- if((KEY_PORT & (1<<K2_PIN)) == 0) { // K2 按下 if(key2_flag == 0) { key2_flag = 1; Delay_ms(20); // 消抖延时 if((KEY_PORT & (1<<K2_PIN)) == 0) { // 写入 6264:地址 0x2000,数据为 num Write_RAM(0x2000, num); } } } else { key2_flag = 0; } } /** * @brief 向 6264 RAM 指定地址写入数据 * @param addr: 16 位地址(0x0000~0xFFFF,需看 6264 实际寻址范围) * @param dat: 要写入的数据(0~255) * @note 6264 为 8K×8 RAM,地址范围一般 0x0000~0x1FFF(需与硬件片选配合) */ void Write_RAM(unsigned int addr, unsigned char dat) { // 1. 设置地址 RAM_ADDR_H = (addr >> 8) & 0xFF; // 高 8 位地址(A8~A15) RAM_ADDR_L = addr & 0xFF; // 低 8 位地址(A0~A7),与数据口复用 // 2. 使能片选、写信号 RAM_CS = 0; // 选通 6264 RAM_WR = 0; // 触发写操作 // 3. 输出数据到 P0(因 6264 数据口与 P0 复用) SEG_PORT = dat; // 数据送 P0 // 4. 延时保持写时序(根据 6264 时序要求调整,简单延时即可) Delay_ms(1); // 5. 释放控制信号 RAM_WR = 1; // 结束写操作 RAM_CS = 1; // 取消片选 SEG_PORT = 0xFF; // 释放数据口(可选) }把代码改为功能要求:通过其中一个按键操作,完成一个两位数的设置,并将该数值在数码管上显示出来;按下另一个按键时,将数码管上显示的两位数数据存储到6264存储芯片的任意一个存储单元中。

检查以下代码能否生成hex文件:/*---------------------------------- 硬件连接宏定义 ----------------------------------*/ #include <reg52.h> #include <intrins.h> #define SDA P2_0 // I²C数据线 #define SCL P2_1 // I²C时钟线 #define LCD_RS P2_5 // LCD寄存器选择 #define LCD_RW P2_6 // LCD读写选择 #define LCD_E P2_7 // LCD使能端 #define LCD_DB P0 // LCD数据总线 /*---------------------------------- GY-906-BCC传感器驱动 ----------------------------------*/ // I²C起始信号 void I2C_Start() { SDA = 1; _nop_(); SCL = 1; _nop_(); SDA = 0; _nop_(); SCL = 0; _nop_(); } // 读取温度原始数据(16位) unsigned int MLX90614_Read() { unsigned int temp = 0; I2C_Start(); // 发送设备地址+写命令(0x5A<<1|0) I2C_SendByte(0xB4); // 发送读取温度指令(0x07) I2C_SendByte(0x07); I2C_Start(); // 发送设备地址+读命令(0x5A<<1|1) I2C_SendByte(0xB5); temp = I2C_RecvByte() << 8; // 高字节 I2C_Ack(); temp |= I2C_RecvByte(); // 低字节 I2C_NAck(); I2C_Stop(); return temp; } /*---------------------------------- 温度计算处理 ----------------------------------*/ float Temp_Convert(unsigned int raw) { float temp = raw * 0.02 - 273.15; // 原始数据转摄氏度 // 温度补偿公式(示例) temp += (25 - ReadAmbientTemp()) * 0.1; return temp; } /*---------------------------------- 1602液晶显示驱动 ----------------------------------*/ // LCD写命令函数 void LCD_WriteCmd(unsigned char cmd) { LCD_RS = 0; LCD_RW = 0; LCD_DB = cmd; LCD_E = 1; Delay(5); LCD_E = 0; } // 显示温度值 void LCD_DisplayTemp(float temp) { unsigned char str[16]; sprintf(str, "Temp:%6.2f\xDFC", temp); LCD_SetCursor(0, 0); LCD_WriteString(str); } /*---------------------------------- 主程序框架 ----------------------------------*/ void main() { LCD_Init(); // 液晶初始化 I2C_Init(); // I²C初始化 while(1) { unsigned int raw = MLX90614_Read(); float temp = Temp_Convert(raw); if(temp < -50 || temp > 400) { // 异常值过滤 LCD_DisplayError(); } else { LCD_DisplayTemp(temp); } Delay(1000); // 1秒刷新周期 } }

/*************************************************************************************************** * * 人机交互 UART4 业务处理模块 * * * ****************************************************************************************************/ /*********************** Includes ***************************/ #include "sys.h" #include "task_hmi_uart4.h" #include "board.h" #include "crc16.h" #include "task_disp.h" #include "modules_param.h" //#include "modules_fault.h" //#include "bsp_uart4.h" //#include "bsp_dgusii.h" //#include <stdio.h> //#include "modules_fault.h" /*********************** Private types ***************************/ /*********************** Private macros ***************************/ #define UART_FRAME_STX 0xAA /* Monitor is Slave, Panel is Master */ #define UART_SLAVE_2_MASTER 0x5A //从机->主机 /* Monitor is Slave, Panel is Master */ #define UART_MASTER_2_SLAVE 0xA5 //主机->从机 #define UART_FRAME_SIZE_MAX 64 /*********************** Private constants ***************************/ //定义状态机(准备,开始,结束),按阶段处理数据帧 typedef enum{ UART_RECV_PRE, UART_RECV_START, UART_RECV_DONE, }ENUM_UART_RECV_STATUS; //帧结构索引(帧起始,方向,长度,编号,地址,功能码,数据) typedef enum{ FRAME_INDX_STX, FRAME_INDX_DIR, FRAME_INDX_LEN, FRAME_INDX_NUM, FRAME_INDX_ADDR, FRAME_INDX_FUNC, FRAME_INDX_DAT, }ENUM_FRAME_INDX; /* 串行通信协议 功能码 (区分数据帧的业务类型)*/ typedef enum{ FRAME_ASK = 0x03, //查询 FRAME_SET = 0x10, //设置 FRAME_CTRL = 0x0F, //控制 }ENUM_FRAME_FUNC; /* 串行通信协议 查询指令 */ typedef enum{ ASK_ASK_ALL = 0x00, //查询所有数据 /* 当前输入电压(三相) */ ASK_CUR_3PHASE_IN_U = 0x0502, /* 当前输入电流(三相) */ ASK_CUR_3PHASE_IN_I = 0x0504, /* 当前输出电压(三相) */ ASK_CUR_3PHASE_OUT_U = 0x0506, /* 当前输出电流(三相) */ ASK_CUR_3PHASE_OUT_I = 0x0508, /* 当前输入、输出频率 */ ASK_CUR_FREQ = 0x0509, /* 输出设定值(电压、电流、频率)查询 */ ASK_SET_OUT = 0x050A, /* 输出阈值(过压、过流、过温)查询 */ ASK_OVER_OUT = 0x050B, /* 历史信息查询 */ ASK_FAULT_HISTORY = 0x050D, /* 状态查询 */ ASK_SYS_STATUS = 0x050E, }ENUM_ASK_ORDER; /* 串行通信协议 参数设置指令 */ typedef enum{ /* 设置输出电压 */ SET_OUT_U = 0x0301, /* 设置输出电流 */ SET_OUT_I = 0x0302, /* 设置输出频率 */ SET_U_FREQ = 0x0303, /* 设置输出电压阈值(过压) */ SET_U_OVER_OUT = 0x0304, /* 设置输出电流阈值(过流) */ SET_I_OVER_OUT = 0x0305, /* 设置温度阈值(过温) */ SET_TEMP_OVER_OUT = 0x0306, }ENUM_SET_ORDER; /* 串行通信协议 控制指令 */ typedef enum{ CTRL_S250K_SWITCH = 0x0A01, //250k开关控制 }ENUM_CTRL_ORDER; typedef enum{ SWITCH_ON = 0xAA, //开关打开 SWITCH_OFF = 0x55, //开关关闭 }ENUM_SWITCH_TYPE; u16 GetSwitch(ENUM_SWITCH_TYPE id); // 获取当前值(编辑中返回临时值) /*********************** Private variables ***************************/ #if UART4_ENABLE static struct UartFrameData Uart4_Frame; //UART4帧数据结构(存储解析中的帧结构) extern struct Uart_Type_t Uart4; //UART4设备结构体 #endif /*********************** Functions ***************************/ static void AskOrderPro(const u8* frame){ const u16 order = (frame[FRAME_INDX_DAT]<<8)|frame[FRAME_INDX_DAT+1]; //代码从FRAME_INDEX_DAT位置读取2字节数据,组合成16位的order指令码 switch(order){ /* 解析当前输入电压(三相) */ case ASK_CUR_3PHASE_IN_U: { Set_DisplayVal(DISP_ADDR_IN_U_A, (frame[FRAME_INDX_DAT+2]<<8)|frame[FRAME_INDX_DAT+3]); Set_DisplayVal(DISP_ADDR_IN_U_B, (frame[FRAME_INDX_DAT+4]<<8)|frame[FRAME_INDX_DAT+5]); Set_DisplayVal(DISP_ADDR_IN_U_C, (frame[FRAME_INDX_DAT+6]<<8)|frame[FRAME_INDX_DAT+7]); }break; /* 解析当前输入电流(三相) */ case ASK_CUR_3PHASE_IN_I: { Set_DisplayVal(DISP_ADDR_IN_I_A, (frame[FRAME_INDX_DAT+2]<<8)|frame[FRAME_INDX_DAT+3]); Set_DisplayVal(DISP_ADDR_IN_I_B, (frame[FRAME_INDX_DAT+4]<<8)|frame[FRAME_INDX_DAT+5]); Set_DisplayVal(DISP_ADDR_IN_I_C, (frame[FRAME_INDX_DAT+6]<<8)|frame[FRAME_INDX_DAT+7]); }break; /* 解析当前输出电压(三相) */ case ASK_CUR_3PHASE_OUT_U: { Set_DisplayVal(DISP_ADDR_OUT_U_A, (frame[FRAME_INDX_DAT+2]<<8)|frame[FRAME_INDX_DAT+3]); Set_DisplayVal(DISP_ADDR_OUT_U_B, (frame[FRAME_INDX_DAT+4]<<8)|frame[FRAME_INDX_DAT+5]); Set_DisplayVal(DISP_ADDR_OUT_U_C, (frame[FRAME_INDX_DAT+6]<<8)|frame[FRAME_INDX_DAT+7]); }break; /* 解析当前输出电流(三相) */ case ASK_CUR_3PHASE_OUT_I: { Set_DisplayVal(DISP_ADDR_OUT_I_A, (frame[FRAME_INDX_DAT+2]<<8)|frame[FRAME_INDX_DAT+3]); Set_DisplayVal(DISP_ADDR_OUT_I_B, (frame[FRAME_INDX_DAT+4]<<8)|frame[FRAME_INDX_DAT+5]); Set_DisplayVal(DISP_ADDR_OUT_I_C, (frame[FRAME_INDX_DAT+6]<<8)|frame[FRAME_INDX_DAT+7]); }break; /* 解析当前输入、输出频率 */ case ASK_CUR_FREQ: { Set_DisplayVal(DISP_ADDR_IN_FREQ, (frame[FRAME_INDX_DAT+2]<<8)|frame[FRAME_INDX_DAT+3]); Set_DisplayVal(DISP_ADDR_OUT_FREQ, (frame[FRAME_INDX_DAT+4]<<8)|frame[FRAME_INDX_DAT+5]); }break; /* 输出设定值(电压、电流、频率)查询 */ case ASK_SET_OUT: { }break; /* 输出阈值(过压、过流、过温)查询 */ case ASK_OVER_OUT: { }break; /* 历史信息查询 */ case ASK_FAULT_HISTORY: { }break; /* 状态查询 */ case ASK_SYS_STATUS: { }break; } } static void SetOrderPro(const u8* frame){ const u16 order = (frame[FRAME_INDX_DAT]<<8)|frame[FRAME_INDX_DAT+1]; switch(order){ /* 设置输出电压 */ case SET_OUT_U: { }break; /* 设置输出电流 */ case SET_OUT_I: { }break; /* 设置输出频率 */ case SET_U_FREQ: { }break; /* 设置输出电压阈值(过压) */ case SET_U_OVER_OUT: { }break; /* 设置输出电流阈值(过流) */ case SET_I_OVER_OUT: { }break; /* 设置温度阈值(过温) */ case SET_TEMP_OVER_OUT: { }break; } } //根据接收到的功能码,将数据分发到不同的业务处理函数中 static void HmiRecvPro(const u8* frame){ switch(frame[FRAME_INDX_FUNC]){ //根据功能码分发到不同处理函数 case FRAME_ASK: { AskOrderPro(frame); //处理查询指令 }break; case FRAME_SET: { }break; case FRAME_CTRL: { }break; } } static void Uart_FrameParsing(P_S_UART Uart_number, P_D_UART Uart_data, const u16 Uart_buff_lenth){ u8 byte; u16 i = 0, Crc = 0; while( ((*Uart_number).Rx_Write - (*Uart_number).Rx_Read + Uart_buff_lenth) % Uart_buff_lenth){ //循环处理接收缓冲区中的数据 /*读取数据*/ EA = 0; byte = (*Uart_number).Rx_Buffer[(*Uart_number).Rx_Read++]; (*Uart_number).Rx_Read %= Uart_buff_lenth; (*Uart_number).Rx_Busy = 0; EA = 1; //三阶段状态机:等待帧起始;校验方向,读取帧长度;接收完数据,校验CRC /*开始接收帧数据(等待帧起始标志)*/ if((*Uart_number).Rx_Flag == UART_RECV_PRE){ ResetFrame(Uart_number, Uart_data); if(byte == UART_FRAME_STX) { (*Uart_number).Rx_Flag = UART_RECV_START; (*Uart_data).varData[(*Uart_data).varIndex++] = byte; } continue; } /* 传输方向判断 */ if(FRAME_INDX_DIR == (*Uart_data).varIndex){ if(UART_SLAVE_2_MASTER == byte && UART_RECV_START == (*Uart_number).Rx_Flag){ //方向正确,继续接受 } else{ //方向错误,重置接收状态 ResetFrame(Uart_number, Uart_data); (*Uart_number).Rx_Flag = UART_RECV_PRE; continue; } } /* 帧总长度 */ if(FRAME_INDX_LEN == (*Uart_data).varIndex){ (*Uart_data).dataLen = byte; } //存储数据到缓冲区 (*Uart_data).varData[(*Uart_data).varIndex++] = byte; /*已检测到变量地址低位(是否接收完所有数据)*/ if((*Uart_data).varIndex == (*Uart_data).dataLen){ (*Uart_number).Rx_Flag = UART_RECV_DONE; break; } //防止缓冲区溢出 if(UART_FRAME_SIZE_MAX <= (*Uart_data).varIndex){ //当接收数据超过定下的UART_FRAME_SIZE_MAX时重置接收状态 ResetFrame(Uart_number, Uart_data); } } /*处理一帧数据(CRC校验)*/ if((*Uart_number).Rx_Flag == UART_RECV_DONE){ //提取接收到的CRC值 const u16 crc = (u16)((*Uart_data).varData[(*Uart_data).dataLen - 2] << 8) | (*Uart_data).varData[(*Uart_data).dataLen - 1]; if(crc == GetCrc16((*Uart_data).varData, (*Uart_data).dataLen - 2)){ //使用GetCrc16计算数据区CRC并与帧尾CRC比较校验 HmiRecvPro((*Uart_data).varData); //校验通过,分发处理 } ResetFrame(Uart_number, Uart_data); //重置帧缓冲区 } } // 解析HMI指令帧(包含帧头校验、指令分发) static void ParseHmiFrame(u8 *frame, u16 frame_len) { if (frame_len < 2) return; // 至少需要帧头 if (frame[0] != HMI_FRAME_HEAD1 || frame[1] != HMI_FRAME_HEAD2) { //帧头必须为0x5A或者0xA5 return; // 帧头错误,丢弃 } unsigned char cmd = frame[2]; // 提取指令类型 switch (cmd) { // ------------------------- // 1. 页面切换指令处理 // ------------------------- case HMI_CMD_SWITCH_PAGE: { if (frame_len < sizeof(CmdSwitchPage) + 9) return; // 帧头+指令共12字节 CmdSwitchPage *cmd_sw = (CmdSwitchPage*)&frame[4]; if (cmd_sw->target == 0) { // 跳转到【参数设置页】 Dgus_PageChange(PAGE_PARAM); // 更新参数页显示:读取当前参数并写入DGUS Dgus_WriteWord(DGUS_ADDR_OUTPUT_FREQ, Param_GetCurrentValue(PARAM_OUTPUT_FREQ)); Dgus_WriteWord(DGUS_ADDR_OUTPUT_VOLT, Param_GetCurrentValue(PARAM_OUTPUT_VOLT)); Dgus_WriteWord(DGUS_ADDR_VOLT_PROT, Param_GetCurrentValue(PARAM_VOLT_PROT)); Dgus_WriteWord(DGUS_ADDR_CURR_PROT, Param_GetCurrentValue(PARAM_CURR_PROT)); Dgus_WriteWord(DGUS_ADDR_TEMP_PROT, Param_GetCurrentValue(PARAM_TEMP_PROT)); } else if (cmd_sw->target == 1) { // 跳转到【历史故障页】 Dgus_PageChange(PAGE_FAULT); // 更新历史页显示:获取当前页记录并写入DGUS FaultRecord page_buf[FAULT_PER_PAGE] = {0}; Fault_GetPageRecords(g_current_fault_page, page_buf); for (u8 i = 0; i < FAULT_PER_PAGE; i++) { u16 addr = DGUS_FAULT_PAGE_BASE + i * 16; Dgus_WriteWord(addr + 0, page_buf[i].fault_code); // 故障代码 Dgus_WriteString(addr + 2, page_buf[i].fault_type); // 故障类型 // Dgus_WriteString(addr + 22, page_buf[i].detail); // 故障明细 // Dgus_WriteWord(addr + 72, page_buf[i].time_stamp); // 时间戳 Dgus_WriteWord(addr + 76, page_buf[i].level); // 故障等级 } Dgus_WriteWord(DGUS_FAULT_PAGE_NUM, Fault_GetCurrentPage()); // 页码 } else if (cmd_sw->target == 2) { // 【关机】 //用RS232发送指令,AA开机,55关机 // Dgus_WriteWord(0xFFFF, 0x00); // 假设息屏寄存器为0xFFFF,值0x00表示息屏 // u16 GetSwitch(ENUM_SWITCH_TYPE id); // 获取当前值(编辑中返回临时值) } break; } // ------------------------- // 2. 参数编辑:开始编辑 // ------------------------- case HMI_CMD_EDIT_START: { if (frame_len < sizeof(CmdEditStart) + 4) return; CmdEditStart *cmd_edit = (CmdEditStart*)&frame[4]; ParamID id = (ParamID)cmd_edit->param_id; if (id < PARAM_MAX) { Param_StartEdit(id); // 标记为编辑状态 // 向DGUS发送初始值(供键盘显示) u32 init_val = Param_GetCurrentValue(id); //根据参数ID更新对应显示地址 switch (id) { case PARAM_OUTPUT_FREQ: Dgus_WriteWord(DGUS_ADDR_OUTPUT_FREQ, init_val); break; case PARAM_OUTPUT_VOLT: Dgus_WriteWord(DGUS_ADDR_OUTPUT_VOLT, init_val); break; case PARAM_VOLT_PROT: Dgus_WriteWord(DGUS_ADDR_VOLT_PROT, init_val); break; case PARAM_CURR_PROT: Dgus_WriteWord(DGUS_ADDR_CURR_PROT, init_val); break; case PARAM_TEMP_PROT: Dgus_WriteWord(DGUS_ADDR_TEMP_PROT, init_val); break; default: break; } } break; } // ------------------------- // 3. 参数编辑:更新临时值 // ------------------------- case HMI_CMD_EDIT_UPDATE: { if (frame_len < sizeof(CmdEditUpdate) + 4) return; CmdEditUpdate *cmd_update = (CmdEditUpdate*)&frame[4]; ParamID id = (ParamID)cmd_update->param_id; if (id == g_param_edit.editing_id) { // 仅处理当前编辑的参数 Param_UpdateTemp(cmd_update->new_val); // 更新临时值 // 实时更新DGUS显示(临时值) switch (id) { case PARAM_OUTPUT_FREQ: Dgus_WriteWord(DGUS_ADDR_OUTPUT_FREQ, cmd_update->new_val); break; case PARAM_OUTPUT_VOLT: Dgus_WriteWord(DGUS_ADDR_OUTPUT_VOLT, cmd_update->new_val); break; case PARAM_VOLT_PROT: Dgus_WriteWord(DGUS_ADDR_VOLT_PROT, cmd_update->new_val); break; case PARAM_CURR_PROT: Dgus_WriteWord(DGUS_ADDR_CURR_PROT, cmd_update->new_val); break; case PARAM_TEMP_PROT: Dgus_WriteWord(DGUS_ADDR_TEMP_PROT, cmd_update->new_val); break; default: break; } } break; } // ------------------------- // 4. 参数编辑:确认修改 // ------------------------- case HMI_CMD_EDIT_CONFIRM: { if (frame_len < sizeof(CmdEditConfirm) + 2) return; CmdEditConfirm *cmd_confirm = (CmdEditConfirm*)&frame[2]; ParamID id = (ParamID)cmd_confirm->param_id; if (id == g_param_edit.editing_id) { // 仅处理当前编辑的参数 Param_ConfirmEdit(); // 保存临时值到系统参数 // 确认后,DGUS显示系统值(即新值) u32 new_val = Param_GetCurrentValue(id); switch (id) { case PARAM_OUTPUT_FREQ: Dgus_WriteWord(DGUS_ADDR_OUTPUT_FREQ, new_val); break; case PARAM_OUTPUT_VOLT: Dgus_WriteWord(DGUS_ADDR_OUTPUT_VOLT, new_val); break; case PARAM_VOLT_PROT: Dgus_WriteWord(DGUS_ADDR_VOLT_PROT, new_val); break; case PARAM_CURR_PROT: Dgus_WriteWord(DGUS_ADDR_CURR_PROT, new_val); break; case PARAM_TEMP_PROT: Dgus_WriteWord(DGUS_ADDR_TEMP_PROT, new_val); break; default: break; } } break; } // ------------------------- // 5. 历史故障翻页 // ------------------------- case HMI_CMD_FAULT_PAGE: { if (frame_len < sizeof(CmdFaultPage) + 2) return; CmdFaultPage *cmd_fault = (CmdFaultPage*)&frame[2]; FaultPageOp op = (FaultPageOp)cmd_fault->op; Fault_PageOperation(op); // 执行翻页 // 更新历史页显示 FaultRecord page_buf[FAULT_PER_PAGE] = {0}; Fault_GetPageRecords(g_current_fault_page, page_buf); for (u8 i = 0; i < FAULT_PER_PAGE; i++) { u16 addr = DGUS_FAULT_PAGE_BASE + i * 16; Dgus_WriteWord(addr + 0, page_buf[i].fault_code); Dgus_WriteString(addr + 2, page_buf[i].fault_type); // Dgus_WriteString(addr + 22, page_buf[i].detail); //故障明细 // Dgus_WriteWord(addr + 72, page_buf[i].time_stamp); //时间戳 Dgus_WriteWord(addr + 76, page_buf[i].level); } Dgus_WriteWord(DGUS_FAULT_PAGE_NUM, Fault_GetCurrentPage()); break; } default: break; // 未知指令,忽略 } } // HMI 主任务:循环处理UART4接收的数据 void Task_Hmi_Uart(void) { if (Uart4.Rx_Flag) { // 检测到未处理的数据 u16 frame_len = Uart4.Rx_Write; // 获取数据长度 if (frame_len > 0) { u8 frame_buf[UART4_RX_LEN] = {0}; memcpy(frame_buf, Uart4.Rx_Buffer, frame_len); // 复制数据到临时缓冲区 ParseHmiFrame(frame_buf, frame_len); // 解析指令 // 清空缓冲区 Uart4.Rx_Write = 0; Uart4.Rx_Flag = 0; } } } void Task_Hmi_Uart(){ #if UART4_ENABLE /* 响应用户业务需求 */ Uart_FrameParsing(&Uart4, &Uart4_Frame, UART4_RX_LEN); #endif } 理解这段代码,在keil上显示unsigned char cmd = frame[2];这段代码报错1_App\task_hmi_uart4.c(383): error C141: syntax error near 'unsigned', expected '__asm',该怎么解决

#include<STC8G.h> #include<stdio.h> #include<intrins.h> #define ADC_Power 0x80 //使能ADC模块 打开ADC 将ADC引脚设置到 #define ADC_Start 0x40 //开始ADC转换 #define ADC_Flag 0x20 //转换完成标志位 #define ADC_SYS 0x2f //将ADC系统时钟设定为SYSclk/2/16 //****************************************** //延时ms函数,参数:ms //使用条件:晶振/系统频率30.000MHz //****************************************** void delay(int ms){ unsigned char data i, j; while(ms){ i = 30; j = 43; do { while (--j); } while (--i); ms--; } } //****************************************** //函数说明:串口初始化 //****************************************** void Serial_begin() //[email protected] { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x40; //定时器时钟1T模式 AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //设置定时器模式 TL1 = 0xF3; //设置定时初始值 TH1 = 0xFC; //设置定时初始值 ET1 = 0; //禁止定时器中断 TR1 = 1; //定时器1开始计时 } void Sendbyte(unsigned char dat){//发送8位数据到串口 SBUF = dat; while(!TI); TI=0; } char putchar(char c){//重定义printf()函数,用于串口打印信息 Sendbyte(c); return c; } //****************************************** //函数说明:读取指定ADC引脚值。参数:ADC引脚编号(编号见上单片机引脚图) //****************************************** unsigned int analogRead(unsigned char ADC_Pin){ ADC_CONTR = ADC_Power + ADC_Pin; //使能ADC,向寄存器写入将要读的ADC引脚 ADCCFG = ADC_SYS; //将ADC系统时钟设定为SYSclk/2/16 ADC_CONTR |= ADC_Start; //开始ADC转换 _nop_(); _nop_(); while(!(ADC_CONTR & ADC_Flag)); //等待完成 ADC_CONTR &=~ ADC_Flag; //清除完成标志位 return (ADC_RES<<8) | ADC_RESL; //合并高8位低8位,返回合并后结果 } //****************************************** //主程序 //****************************************** void main(){ Serial_begin();//初始化串口 while(1){ printf(((899 - analogRead(5)) / 279 * 100));//读取ADC5的值并打印到串口输出 delay(1000);//延时1秒 } } 这是代码 assembling STARTUP.A51... compiling main.c... main.c(77): error C214: illegal pointer conversion Target not created

/* 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 "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* 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(); /* USER CODE BEGIN 2 */ /* 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_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_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; 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_1) != 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 */ /* 作者:嗨小易(QQVIP群2:570487280) B站:https://space.bilibili.com/444388619/video 版权:本教程版权归嗨小易所有,未经授权不得转载、摘编或用于其他商业用途!!! 一经发现,后果自负!!! */ #include "key.h" #include "SysTick.h" /******************************************************************************* * 函 数 名 : KEY_Init * 函数功能 : 按键初始化 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin=KEY1_PIN|KEY2_PIN|KEY3_PIN|KEY4_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入 GPIO_Init(KEY_PORT,&GPIO_InitStructure); } /******************************************************************************* * 函 数 名 : KEY_Scan * 函数功能 : 按键扫描检测 * 输 入 : mode=0:单次按下按键 mode=1:连续按下按键 * 输 出 : 0:未有按键按下 KEY_UP_PRESS:KEY_UP键按下 KEY0_PRESS:KEY0键按下 KEY1_PRESS:KEY1键按下 KEY2_PRESS:KEY2键按下 *******************************************************************************/ u8 KEY_Scan(u8 mode) { static u8 key=1; if(mode==1) //连续按键按下 key=1; if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)) //任意一个按键按下 { delay_ms(1); //消抖 key=0; if(KEY1==0) return KEY1_PRESS; else if(KEY2==0) return KEY2_PRESS; else if(KEY3==0) return KEY3_PRESS; else if(KEY4==0) return KEY4_PRESS; } else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下 key=1; return 0; } //矩阵按键端口初始化 void key_matrix_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOA,&GPIO_InitStructure); } /******************************************************************************* * 函 数 名 : key_matrix_flip_scan * 函数功能 : 使用线翻转扫描方法,检测矩阵按键是否按下,按下则返回对应键值 * 输 入 : 无 * 输 出 : key_value:1-16,对应S1-S16键, 0:按键未按下 *******************************************************************************/ u8 key_matrix_flip_scan(void) { static u8 key_value=0; KEY_MATRIX_PORT_OUT(0x0f);//给所有行赋值0,列全为1 if(KEY_MATRIX_PORT_READ!=0x0f)//判断按键是否按下 { delay_10us(1000);//消抖 if(KEY_MATRIX_PORT_READ!=0x0f) { //测试列 KEY_MATRIX_PORT_OUT(0x0f); switch(KEY_MATRIX_PORT_READ)//保存行为0,按键按下后的列值 { case 0x07: key_value=1;break; case 0x0b: key_value=2;break; case 0x0d: key_value=3;break; case 0x0e: key_value=4;break; } //测试行 KEY_MATRIX_PORT_OUT(0xf0); switch(KEY_MATRIX_PORT_READ)//保存列为0,按键按下后的键值 { case 0x70: key_value=key_value;break; case 0xb0: key_value=key_value+4;break; case 0xd0: key_value=key_value+8;break; case 0xe0: key_value=key_value+12;break; } while(KEY_MATRIX_PORT_READ!=0xf0);//等待按键松开 } } else key_value=0; return key_value; } /* 作者:嗨小易(QQVIP群2:570487280) B站:https://space.bilibili.com/444388619/video 版权:本教程版权归嗨小易所有,未经授权不得转载、摘编或用于其他商业用途!!! 一经发现,后果自负!!! */ #include "smg.h" #include "SysTick.h" //共阴极数码管显示0~F的段码数据 u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //数码管端口初始化 void smg_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LSA_PORT_RCC,ENABLE); RCC_APB2PeriphClockCmd(LSB_PORT_RCC,ENABLE); RCC_APB2PeriphClockCmd(LSC_PORT_RCC,ENABLE); RCC_APB2PeriphClockCmd(SMG_DATAPORT_PORT_RCC,ENABLE); GPIO_InitStructure.GPIO_Pin=LSA_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(LSA_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=LSB_PIN; GPIO_Init(LSB_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=LSC_PIN; GPIO_Init(LSC_PORT,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=SMG_DATAPORT_PIN; GPIO_Init(SMG_DATAPORT_PORT,&GPIO_InitStructure); } /******************************************************************************* * 函 数 名 : smg_display * 函数功能 : 动态数码管显示 * 输 入 : dat:要显示的数据 pos:从左开始第几个位置开始显示,范围1-8 * 输 出 : 无 *******************************************************************************/ void smg_display(u8 dat[],u8 pos) { u8 i=0; u8 pos_temp=pos-1; for(i=pos_temp;i<8;i++) { switch(i)//位选 { case 0: LSC=1;LSB=1;LSA=1;break; case 1: LSC=1;LSB=1;LSA=0;break; case 2: LSC=1;LSB=0;LSA=1;break; case 3: LSC=1;LSB=0;LSA=0;break; case 4: LSC=0;LSB=1;LSA=1;break; case 5: LSC=0;LSB=1;LSA=0;break; case 6: LSC=0;LSB=0;LSA=1;break; case 7: LSC=0;LSB=0;LSA=0;break; } SMG_DATAPORT(dat[i-pos_temp]);//传送段选数据 delay_10us(100);//延时一段时间,等待显示稳定 // SMG_DATAPORT(0x00);//消音 } } /* 作者:嗨小易(QQVIP群2:570487280) B站:https://space.bilibili.com/444388619/video 版权:本教程版权归嗨小易所有,未经授权不得转载、摘编或用于其他商业用途!!! 一经发现,后果自负!!! */ #include "beep.h" #include "SysTick.h" /******************************************************************************* * 函 数 名 : BEEP_Init * 函数功能 : 蜂鸣器初始化 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void BEEP_Init(void) //端口初始化 { GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量,用来初始化GPIO RCC_APB2PeriphClockCmd(BEEP_PORT_RCC,ENABLE); /* 开启GPIO时钟 */ /* 配置GPIO的模式和IO口 */ GPIO_InitStructure.GPIO_Pin=BEEP_PIN; //选择你要设置的IO口 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(BEEP_PORT,&GPIO_InitStructure); /* 初始化GPIO */ GPIO_SetBits(BEEP_PORT,BEEP_PIN); } /******************************************************************************* * 函 数 名 : beep_alarm * 函数功能 : 蜂鸣器报警函数 * 输 入 : time:报警持续时间 fre:报警频率 * 输 出 : 无 *******************************************************************************/ void beep_alarm(u16 time,u16 fre) { while(time--) { BEEP=!BEEP; delay_10us(fre); } BEEP=1; } 将这些代码整合到上述工程中,以实现简易计算器,主要功能如下: 1、加减乘除运算 2、小数显示 3、按键提示音 4、数码管显示

#include "ADC_Config.h" #define ADCIP_CTRL (*(uint32_t*)(0x40020800+0x60)) /* ADC时钟: 14MHZ 声音范围:20Hz~20KHz TIME触发ADC:TIM频率 128K ADC采样时间 = (71.5 +12.5)/14 采样频率:128K 采样个数: 125ms=8HZ 128K/8Hz=16000次, 512K/8HZ=64000 64000/256=250 BUFF0大小256 BUFF1大小128,DMA HT中断,即要中断16000/128=125次 每125次求和 PA1:ADC_IN1 30-70DB PA2: ADC_IN2 70-100DB PA3:ADC_IN3 100-130DB 采样125ms: 共要计算 16000组数据 采样1s: 共要计算 16000*8=128000组数据 设置DMA BUFF大小 256组 HT中断 中断时间1ms 中断程序耗费8.8us 那么 采样125ms就需要中断 125000/1=125次 9K的信号能采样14组 那么 采样1s就需要中断 125*8=1000次 DMA_MEM 从开始到计算结束 用时140us 不会超过一次ADC DMA中断时间 数据不会被覆盖 */ ADC_BUFF Noise_Data; DMA_InitType DMA_InitStructure, DMA_InitStructure_MEM; u8 USB_Busy ; ADC_InitType ADC_InitStructure; extern uint16_t DMA_Test_Value[5], DMA_Test_Value1[5]; void TIM2_ETR_Config(void) { TIM_TimeBaseInitType TIM_TimeBaseStructure; OCInitType TIM_OCInitStructure; RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE); TIM_TimeBaseStructure.Period = TRG_FREQ_USER - 1; //64k TIM_TimeBaseStructure.Prescaler = 0; TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1; TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP; TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.OcMode = TIM_OCMODE_PWM1; TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.Pulse = TRG_FREQ_USER / 2 - 1; TIM_OCInitStructure.OcPolarity = TIM_OC_POLARITY_LOW; TIM_InitOc2(TIM2, &TIM_OCInitStructure); TIM_ConfigInt(TIM2, TIM_INT_CC2, ENABLE); /* TIM2 enable counter */ TIM_Enable(TIM2, ENABLE); TIM_EnableCtrlPwmOutputs(TIM2, ENABLE); } /** * @brief Configures the different system clocks. */ void RCC_Configuration(void) { /* Enable peripheral clocks ------------------------------------------------*/ /* Enable DMA clocks */ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE); /* Enable GPIOC clocks */ RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); /* Enable ADC clocks */ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE); /* RCC_ADCHCLK_DIV16*/ ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV2);//96/2=48M RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV12); //selsect HSE as RCC ADC1M CLK Source } /** * @brief Configures the different GPIO ports. */ void GPIO_Configuration(void) { GPIO_InitType GPIO_InitStructure; GPIO_InitStruct(&GPIO_InitStructure); /* Configure GPIO_PIN_WIFI_RST GPIO_PIN_WIFI_CEN GPIO_PIN_WIFI_RX GPIO_PIN_WIFI_TX as analog input ---------*/ GPIO_InitStructure.Pin = GPIO_PIN_WIFI_RST | GPIO_PIN_WIFI_CEN | GPIO_PIN_WIFI_RX | GPIO_PIN_WIFI_TX | GPIO_PIN_BATT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Analog; GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure); } //配置DMA中断 void NVIC_DMA_Config(void) { NVIC_InitType NVIC_InitStructure; //DMA通道6中断设置 NVIC_InitStructure.NVIC_IRQChannel = DMA_Channel1_IRQn;// DMA1_Channel2_3_IRQn NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 NVIC_Init(&NVIC_InitStructure); } void Change_Addr_MEM(MEA_GROUP_TypeDef MeaGroup) { DMA_EnableChannel(DMA_CH6, DISABLE); switch(MeaGroup) { case GROUP0: DMA_InitStructure_MEM.PeriphAddr = (uint32_t)Noise_Data.Buff0; break; case GROUP1: DMA_InitStructure_MEM.PeriphAddr = (uint32_t)(&Noise_Data.Buff0[DMA_BUFF_SIZE / 2]); break; } DMA_Init(DMA_CH6, &DMA_InitStructure_MEM); if(USB_Busy == 0) //对EEPROM数据进行释放锁后才去打开DMA3 { DMA_EnableChannel(DMA_CH6, ENABLE ); } else { DMA_EnableChannel(DMA_CH6, DISABLE ); } } void ADC_DMA_Cfg(void) { SysData.DMA_Group = 0; /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); NVIC_DMA_Config(); /* DMA channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA_CH1); DMA_InitStructure.PeriphAddr = (uint32_t)&ADC->DAT; DMA_InitStructure.MemAddr = (uint32_t)Noise_Data.Buff0; DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC; DMA_InitStructure.BufSize = DMA_BUFF_SIZE; DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE; DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD; DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;//DMA_MODE_CIRCULAR; DMA_InitStructure.Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE; DMA_Init(DMA_CH1, &DMA_InitStructure); DMA_RequestRemap(DMA_REMAP_ADC1, DMA, DMA_CH1, ENABLE); DMA_ClrIntPendingBit(DMA_INT_TXC1, DMA); // DMA_ClrIntPendingBit(DMA_INT_HTX1,DMA); DMA_ConfigInt(DMA_CH1, DMA_INT_TXC, ENABLE); // DMA_ConfigInt(DMA_CH1,DMA_INT_HTX,ENABLE); /* Enable DMA channel1 */ DMA_EnableChannel(DMA_CH1, ENABLE); ADC_DeInit(ADC); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.MultiChEn = ENABLE; ADC_InitStructure.ContinueConvEn = DISABLE; ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_T2_CC2; ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; ADC_InitStructure.ChsNumber = 4; ADC_Init(ADC, &ADC_InitStructure); ADCIP_CTRL = 0x28; //在ADC使能前配置这个 ADC_EnableTempSensorVrefint( ENABLE); /* ADC1 regular channel13 configuration */ ADC_ConfigRegularChannel(ADC, ADC_CH_1_PA0, 1, ADC_SampleTime_User);//WIFI_RST ADC_ConfigRegularChannel(ADC, ADC_CH_2_PA1, 2, ADC_SampleTime_User);//WIFI_CEN ADC_ConfigRegularChannel(ADC, ADC_CH_3_PA2, 3, ADC_SampleTime_User);//WIFI_RX ADC_ConfigRegularChannel(ADC, ADC_CH_4_PA3, 4, ADC_SampleTime_User);//WIFI_TX ADC_EnableExternalTrigConv(ADC, ENABLE); ADC_ConfigInt(ADC, ADC_INT_ENDC, ENABLE); /* Enable ADC DMA */ ADC_EnableDMA(ADC, ENABLE); /* Enable ADC */ ADC_Enable(ADC, ENABLE); /* Check ADC Ready */ while(ADC_GetFlagStatusNew(ADC, ADC_FLAG_RDY) == RESET); /* Start ADC1 calibration */ ADC_StartCalibration(ADC); /* Check the end of ADC1 calibration */ while (ADC_GetCalibrationStatus(ADC)); } #ifndef __ADC_CONFIG_H #define __ADC_CONFIG_H #include "main.h" #define ADC1_DR_Address 0x40012440 #define TRG_FREQ_1M 72 #define TRG_FREQ_500K 144 #define TRG_FREQ_600K 120 #define TRG_FREQ_300K 240 #define TRG_FREQ_50K 1440 //#define TRG_FREQ_64K 1125 //#define TRG_FREQ_32K 1125*2 #define TRG_FREQ_128K 1125 #define TRG_FREQ_64K 750 #define TRG_FREQ_USER TRG_FREQ_64K #define ADC_SampleTime_User ADC_SAMP_TIME_71CYCLES5 //要求大于 64*4=256K 48/(71.5+12.5+16)=480K >256K #define DMA_CAL_BUFF_SIZE 3200 //125ms*64*4=32000=3200*10= DMA_CAL_BUFF_SIZE*SMP_DMA_CNT 3200/64=50ms 中断一次 #define DMA_BUFF_SIZE DMA_CAL_BUFF_SIZE typedef enum { GROUP0 = 0x00, GROUP1 = 0x01, } MEA_GROUP_TypeDef; typedef struct { //ADC DMA 用 u16 Buff0[DMA_CAL_BUFF_SIZE]; u16 Buff1[DMA_CAL_BUFF_SIZE]; } ADC_BUFF; extern ADC_BUFF Noise_Data; void ADC_Config(MEA_RANGE_TypeDef MeaRange); void DMA_Config(void); void NVIC_DMA_Config(void); void DMA_Config_MEM(void); void TIM2_ETR_Config(void); void Change_Addr_MEM(MEA_GROUP_TypeDef MeaGroup); void ADC_DMA_Cfg(void); #endif /***************************************************************************** * Copyright (c) 2022, Nations Technologies Inc. * * All rights reserved. * **************************************************************************** * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Nations' name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /** * @file n32g43x_it.c * @author Nations * @version v1.2.0 * * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved. */ #include "n32g43x_it.h" #include "n32g43x.h" #include "main.h" #include "usb_istr.h" /** @addtogroup N32G43X_StdPeriph_Template * @{ */ extern __IO uint32_t CurrDataCounterEnd; /******************************************************************************/ /* Cortex-M4 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles Memory Manage exception. */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. */ void SVC_Handler(void) { } /** * @brief This function handles Debug Monitor exception. */ void DebugMon_Handler(void) { } /** * @brief This function handles DMA interrupt request defined in main.h . */ void DMA_IRQ_HANDLER(void) { } /** * @brief This function handles USB_LP_IRQHandler Handler. */ void USB_LP_IRQHandler(void) { USB_Istr(); } /** * @brief This function handles USB WakeUp interrupt request. */ void USBWakeUp_IRQHandler(void) { EXTI_ClrITPendBit(EXTI_LINE17); } void DMA_Channel1_IRQHandler(void) { //国民芯片在一个DMA通道里面 配置另一个DMA通道会导致当前通道顺序异常 //这里配置 2us完成 ADC 一次的时间是15.4us 足够赶上下一次ADC完成 if(DMA_GetIntStatus(DMA_INT_TXC1, DMA) != RESET) //全传输完 { DMA_ClrIntPendingBit(DMA_INT_TXC1, DMA); //国民芯片 建议传输完成 重新配置TXNUM 否则可能出现顺序错乱 DMA_CH1->CHCFG &= (uint16_t)(~DMA_CHCFG1_CHEN); DMA_CH1->TXNUM = DMA_BUFF_SIZE; SysData.DMA_Group = !SysData.DMA_Group; DMA_CH1->MADDR = (uint32_t)Noise_Data.Buff0; if(SysData.DMA_Group != 0) { DMA_CH1->MADDR = (uint32_t)Noise_Data.Buff1; } DMA_CH1->CHCFG |= DMA_CHCFG1_CHEN; SysFlag.DMA_OK = 1; } } void DMA_Channel6_IRQHandler(void) { if(DMA_GetIntStatus(DMA_INT_TXC6, DMA) != RESET) { DMA_ClrIntPendingBit(DMA_INT_TXC6, DMA); // Get_AD_SUM(); } } void ADC_IRQHandler(void) { if(ADC_GetIntStatus(ADC, ADC_INT_ENDC) != RESET) { ADC_ClearIntPendingBit(ADC, ADC_INT_ENDC); // LED1_Turn(); } } void TIM2_IRQHandler(void) { if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC2) == SET) { TIM_ClearFlag(TIM2, TIM_FLAG_CC2); // LED1_Turn(); // test1++; } } void TIM3_IRQHandler(void) { if(TIM_GetFlagStatus(TIM3, TIM_FLAG_UPDATE) == SET) { TIM_ClearFlag(TIM3, TIM_FLAG_UPDATE); // Clock_150++; // Clock_500++; // Clock_750++; // SysClock++; // // Buzzer_Process(); } } void TIM4_IRQHandler(void) { if(TIM_GetFlagStatus(TIM4, TIM_FLAG_UPDATE) == SET) { TIM_ClearFlag(TIM4, TIM_FLAG_UPDATE); Clock_150++; Clock_500++; Clock_750++; SysClock++; LED1_Turn(); Buzzer_Process(); } } void EXTI9_5_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_LINE8) != RESET) { EXTI_ClrITPendBit(EXTI_LINE8); SysFlag.PWD = 1; Clock_500 = 0; if((SysFlag.EraseDoing) && (SysInfo.PWRON_Erase == 0)) { SysInfo.PWRON_Erase = 1; Save_Param(&SysInfo.PWRON_Erase, sizeof(SysInfo.PWRON_Erase)); } } } /** * @brief This function handles SysTick Handler. */ u32 Time_1ms = 0; void SysTick_Handler(void) { Time_1ms++; } /******************************************************************************/ /* N32G43X 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_n32g43x.s). */ /******************************************************************************/ /** * @brief This function handles PPP interrupt request. */ /*void PPP_IRQHandler(void) { }*/ /** * @} */ void Get_AD_SUM(void) { uint64_t Sum[3] = {0, 0, 0}; //这里有3种计算,分别是sum[0],sum[1],sum[2] u8 Ratio; u16 loopi, *Data; u32 Temp; Data = Noise_Data.Buff1;//将DMA移过来的地址给Data if(SysData.DMA_Group != 0) Data = Noise_Data.Buff0;//将DMA移过来的地址给Data SysData.BattCnt = 0; //sum[0] for(loopi = 0; loopi < DMA_CAL_BUFF_SIZE; loopi += 4) //循环480/3=150次 { Temp = (u32)(*Data); //将Noise_Data.Buff1的值给Temp Data++;//地址++ if(Temp > ADC_HLimit) SysData.OverCntt[0]++; //如果Temp>2482,数据溢出的标志位++,这个数据溢出的标志位也有3种,用数组来表示 Temp = Temp + (s32)SysInfo.Cal_Adc[0];// 这个应该是存放校准后的ADC if(Temp > 0x80000000)Temp = 0; Temp = Temp * Temp; //不知道平方一次是用来干啥的 Sum[0] += (uint64_t)Temp; //计算总和,存到sum[0] //sum[1] Temp = (u32)(*Data); Data++; if(Temp > ADC_HLimit_H) SysData.OverCntt[1]++; Temp = Temp + (s32)SysInfo.Cal_Adc[1]; if(Temp > 0x80000000)Temp = 0; Temp = Temp * Temp; Sum[1] += (uint64_t)Temp; //计算总和,存到sum[1] //sum[2] Temp = (u32)(*Data); Data++; Temp = Temp + (s32)SysInfo.Cal_Adc[2]; if(Temp > 0x80000000) Temp = 0; Temp = Temp * Temp; Sum[2] += (uint64_t)Temp; //计算总和,存到sum[2] if(SysData.BattCnt < 64) { SysData.BattBuff[SysData.BattCnt++] = *Data; } Data++; } SysData.Batt = 0; for(loopi = 0; loopi < 64; loopi++) { SysData.Batt += SysData.BattBuff[loopi]; } SysData.Batt = SysData.Batt / 64; // //报警时低于3.3V不关机问题,电源检测这里添加关机 // if(SysData.Batt < BattSHUT) // { // Shut_Down(); // } //将计算的总和,存到SysData.ADC_VALUE SysData.ADC_VALUE[0] += (double)Sum[0]; SysData.ADC_VALUE[1] += (double)Sum[1]; SysData.ADC_VALUE[2] += (double)Sum[2]; SysData.ADC_CNT++; Ratio = SysData.Freq_Resp * 7 + 1; //不知道这2句是干嘛的 if(SysData.ADC_CNT >= (SMP_DMA_CNT * Ratio)) { SysData.ADC_CNT = 0; // if(SysData.Cal_Mode == 0) // { // if(SysData.OverCntt[0] < MIN_OVER_CNT) //溢出计数判断 // { // SysData.Adc_Range = RANG_70DB; // } // else if(SysData.OverCntt[1] < MIN_OVER_CNT) // { // SysData.Adc_Range = RANG_100DB; // } // else // { // SysData.Adc_Range = RANG_130DB; // } // } SysData.ADC_Sum_Value = (SysData.ADC_VALUE[SysData.Adc_Range] / (float)Ratio) + SysInfo.Cal_Adc_Squ[SysData.Adc_Range]; if(SysData.ADC_Sum_Value < 0) { ; } else { // Get_Noise_Data(); } SysData.ADC_VALUE[0] = 0; SysData.ADC_VALUE[1] = 0; SysData.ADC_VALUE[2] = 0; SysData.OverCntt[0] = 0; SysData.OverCntt[1] = 0; SysData.OverCntt[2] = 0; } } void Get_Noise_Data(void) { Phasea = SysData.ADC_Sum_Value; /* 523公式:10*log10(SysData.ADC_Sum_Value) *10 //是为了扩大10倍 用于获取小数部分,来显示 */ Phasea = log10(Phasea); Phasea = Phasea * 1000; Phaseb = (u32)Phasea; SysData.CAL_INT_Value = Phaseb + SysInfo.Cal_DB[SysData.Adc_Range]; SysData.ADC_INT_Value = SysData.CAL_INT_Value / 10; if(SysData.Cal_Mode == 0) { if(SysData.ADC_TAB_CNT == 0) { SysData.ADC_TAB_CNT = 1; SysData.ADC_INT_Value_TAB[1] = SysData.ADC_INT_Value; SysData.ADC_INT_Value_TAB[2] = SysData.ADC_INT_Value; SysData.ADC_INT_Value_TAB[3] = SysData.ADC_INT_Value; } else { SysData.ADC_INT_Value_TAB[3] = SysData.ADC_INT_Value_TAB[2]; SysData.ADC_INT_Value_TAB[2] = SysData.ADC_INT_Value_TAB[1]; SysData.ADC_INT_Value_TAB[1] = SysData.ADC_INT_Value_TAB[0]; } SysData.ADC_INT_Value_TAB[0] = SysData.ADC_INT_Value; } else { SysData.CalEn = 1; if(SysData.Adc_Range == RANG_130DB) { if(SysData.ADC_INT_Value == 1300) { SysFlag.FlickEn = 1; } else { SysFlag.FlickEn = 0; } } } } 保留温湿度和电压,去除噪音

大家在看

recommend-type

复盛压缩机选型软件.rar )

此款为官方专用,简单的压缩机可以选择。SRL型的没有,暂时不能使用请谨慎选择
recommend-type

多模态生理数据预测状态-飞行员

对应文章https://blog.csdn.net/devshilei/article/details/135049559中的图片以及logo
recommend-type

cubase 5 机架 好用方便的机架文件,内含效果器插件

cubase 5 机架 好用方便的机架文件,内含效果器插件
recommend-type

ISO 6469-3-2021 电动道路车辆 - 安全规范 - 第 3 部分:电气安全.docx

国际标准,txt格式 本文件规定了电力推进系统电压 B 级电路和电动道路车辆导电连接辅助电力系统的电气安全要求。 它规定了保护人员免受电击和热事故的电气安全要求。 它没有为制造、维护和维修人员提供全面的安全信息。 注 1: 碰撞后的电气安全要求在 ISO 6469-4 中有描述。 注 2:ISO 17409 描述了电动道路车辆与外部电源的导电连接的电气安全要求。 注 3: 外部磁场无线功率传输的特殊电气安全要求 在 ISO 19363 中描述了电力供应和电动车辆。 注 4 摩托车和轻便摩托车的电气安全要求在 ISO 13063 系列中有描述。 2 引用标准 以下文件在文中的引用方式是,其部分或全部内容构成本文件的要求。对于注明日期的参考文献,只有引用的版本适用。对于未注明日期的引用,引用文件的最新版本 (包括任何修订) 适用。 ISO 17409: 电动道路车辆。导电动力传输。安全要求 ISO 20653,道路车辆 - 保护程度 (IP 代码)- 电气设备防异物、水和接触的保护 IEC 60664 (所有部件) 低压系统内设备的绝缘配合 IEC 60990:2016,接触电流和保护导体
recommend-type

中国检查徽章背景的检察机关PPT模板

这是一套中国检查徽章背景的,检察机关PPT模板。第一PPT模板网提供精美军警类幻灯片模板免费下载; 关键词:蓝天白云、华表、彩带、中国检查徽章PPT背景图片,中国检查院工作汇报PPT模板,蓝色绿色搭配扁平化幻灯片图表,.PPTX格式;

最新推荐

recommend-type

§1.1-MATLAB操作界面.ppt

§1.1-MATLAB操作界面.ppt
recommend-type

英语-信息化教学设计.doc

英语-信息化教学设计.doc
recommend-type

数据库管理规范.doc

数据库管理规范.doc
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基础、项目设置、设计流程、高级功能应用
recommend-type

IllegalArgumentException.class

<think>首先,用户的问题是:“我想查找与Java中IllegalArgumentException类相关的信息请问Java IllegalArgumentExceptionclass usageand examples”。这翻译成英文是:“Iwant tofind informationrelated tothe IllegalArgumentExceptionclass inJava.Please provideusage andexamples ofJavaIllegalArgumentException class.” 根据系统级指令:-所有行内数学表达式必须使用$...$格式,
recommend-type

高效进程监控工具的探索与应用

根据提供的文件信息,我们可以推断出一系列与“监控进程东东”相关的知识点。这些信息暗示了该工具可能是一个用来监控操作系统中运行的进程的应用程序。以下是对这些知识点的详细说明: ### 标题知识点: 1. **监控进程的意义**:在IT行业中,监控进程是指持续跟踪系统中运行的进程状态和行为。进程监控对于系统管理员和开发人员来说至关重要,它可以帮助他们理解系统在特定时刻的行为,以及在出现问题时快速定位问题所在。 2. **“超级好用”的含义**:这通常意味着该监控工具具有用户友好的界面、高效的性能、详细的进程信息展示以及可能具备自动化问题检测与报告的功能。超级好用还可能意味着它易于安装、配置和使用,即使是对于非技术用户。 ### 描述知识点: 1. **重复强调“超级好用”**:这种表述强调该工具的易用性和高效性,暗示它可能采用了直观的用户界面设计,以及优化过的性能,能够减少系统负载,同时提供快速且精准的进程信息。 2. **监控进程工具的常见功能**:通常包括实时进程列表显示、进程资源使用情况监控(CPU、内存、磁盘I/O、网络活动等)、进程启动和结束的跟踪、进程关联性分析(例如父子关系)、以及可能的进程安全监控。 ### 标签知识点: 1. **“监控”标签**:这个标签明确指出了工具的主要用途,即监控。在IT领域,监控是指使用特定的软件或硬件工具来持续检测和记录系统、网络或应用的性能和可用性。 ### 压缩包子文件的文件名称列表知识点: 1. **procexp.chm**:这很可能是一个帮助文件(CHM是Microsoft Compiled HTML Help文件的扩展名),提供了监控进程工具的详细用户指南、使用说明、常见问题解答和功能介绍。CHM文件是将HTML页面、索引和其他资源编译成单一文件的格式,方便用户查阅。 2. **procexp.exe**:这指的是实际的监控进程应用程序的可执行文件。EXE文件是Windows操作系统下的可执行程序文件,用户通过双击它可以启动应用程序。该程序可能包含了用于监控进程的核心功能,比如列出所有运行中的进程,显示它们的详细信息,进行性能分析等。 3. **Eula.txt**:这是一个文本文件,通常包含了最终用户许可协议(End-User License Agreement,EULA)。EULA是供应商和用户之间的法律协议,规定了软件的合法使用条件,包括用户能做什么和不能做什么,以及版权和担保声明。 ### 综合知识点: - **监控进程工具选择标准**:一个优质的监控进程工具应当包括实时更新、多层次的系统信息(如进程树、模块、句柄等)、过滤和搜索功能、安全性高以及对用户行为影响小等特点。 - **监控进程工具在不同场景下的应用**:例如,在开发过程中,开发者可以使用进程监控工具来分析应用程序运行状况,进行性能调优;在安全领域,安全专家可以利用这些工具来发现可疑进程,防止恶意软件的运行。 - **监控进程工具的未来发展**:随着技术的不断进步,监控进程工具也在不断演化,可能会集成更多的智能分析技术,如机器学习算法来预测系统问题,或者提供云平台支持,使得跨区域的进程监控成为可能。 总体来说,上述文件信息所暗示的“超级好用的监控进程东东”可能是一个集多种功能于一身的进程监控工具,它能够帮助用户有效地管理和维护计算机系统,保障其稳定性和安全性。通过提供的文件列表,我们可以得知该工具附带详细的帮助文档,以及用户可能需要的许可协议,这体现了其对用户友好性和专业性的重视。