#ifndef macro_h #define macro_h #define uint8 unsigned char #define uint16 unsigned int #define uint32 unsigned long #define BIT0 0x01//??µÍËÄλ #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10//??¸ßËÄλ #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 #define BIT8 0x0100 #define BIT9 0x0200 #define BIT10 0x0400 #define BIT11 0x0800 #define BIT12 0x1000 #define BIT13 0x2000 #define BIT14 0x4000 #define BIT15 0x8000 #define BIT16 0x010000 #define BIT17 0x020000 #define BIT18 0x040000 #define BIT19 0x080000 #define BIT20 0x100000 #define BIT21 0x200000 #define BIT22 0x400000 #define BIT23 0x800000 #define BIT24 0x01000000 #define BIT25 0x02000000 #define BIT26 0x04000000 #define BIT27 0x08000000 #define BIT28 0x10000000 #define BIT29 0x20000000 #define BIT30 0x40000000 #define BIT31 0x80000000这一堆是在干什么

时间: 2025-07-05 15:12:12 浏览: 7
这段代码定义了一系列宏(`BIT0`到`BIT31`),用于**位操作**,目的是通过预定义的十六进制常量快速访问或操作整数的特定位。以下是详细解析: --- ### **作用** 1. **位掩码(Bitmask)** 每个宏对应一个二进制位(从最低位`BIT0`到最高位`BIT31`),值为`1`左移对应位数的结果(如`BIT3=0x08`即二进制的`00001000`)。 - 用途:通过按位与(`&`)、或(`|`)、异或(`^`)等操作,快速检查、设置或清除特定位。 2. **简化硬件寄存器操作** 在嵌入式开发中,常需直接操作硬件寄存器的特定位(如控制GPIO、中断使能等)。这些宏可以避免手动计算位掩码,提高代码可读性。 --- ### **示例场景** 假设有一个32位寄存器`REG`,需要操作其第5位(`BIT5`): ```c REG |= BIT5; // 将第5位置1(设置位) REG &= ~BIT5; // 将第5位清0(清除位) if (REG & BIT5) { ... } // 检查第5位是否为1 ``` --- ### **代码结构分析** 1. **分组注释** - `//??µÍËÄλ`(可能是乱码,应为“低四位”)和`//??¸ßËÄλ`(“高四位”)是注释,但实际定义的宏覆盖了全部32位(可能是代码片段不完整)。 - 正确的分组应为: - `BIT0`-`BIT3`:最低4位(但代码中`BIT4`开始被标记为“高四位”,可能是注释错误)。 - `BIT4`-`BIT7`:次低4位。 - 以此类推,每4位一组。 2. **宏定义规律** 每个宏的值是前一个的2倍(即左移1位): ```c #define BIT0 0x01 // 1 << 0 #define BIT1 0x02 // 1 << 1 #define BIT2 0x04 // 1 << 2 ... #define BIT31 0x80000000 // 1 << 31 ``` --- ### **为什么需要这么多位?** 1. **支持32位系统** 现代MCU常用32位寄存器,需要完整的32位掩码。 2. **统一风格** 即使某些位在当前项目中未使用,预定义所有位可以方便后续扩展或兼容其他硬件。 --- ### **潜在问题** 1. **注释错误** `//??µÍËÄλ`和`//??¸ßËÄλ`可能是编码问题,正确注释应明确位范围(如“Bits 0-3”)。 2. **冗余定义** 如果项目仅用部分位(如仅`BIT0`-`BIT7`),定义全部32位会占用更多预处理内存,但通常影响可忽略。 --- ### **总结** 这些宏是**位操作的工具集**,用于: - 快速生成位掩码。 - 简化硬件寄存器操作。 - 提高代码可读性和可维护性。 在嵌入式开发中,这种写法非常常见,尤其是需要直接操作寄存器或状态标志时。 ---
阅读全文

相关推荐

/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __OBJ_CAN1_H #define __OBJ_CAN1_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "Public.h" //***********data type definiton*********************// typedef struct _CAN_COMM_MSG_ { unsigned short u16CanStatus; unsigned short u16LinkStep; unsigned short u16StepTimer; unsigned short u16LinkingTimer; unsigned short u16LinkFlag; unsigned short u16Rxflag; CAN_RX_FRAME *xRxFrame; CAN_TX_FRAME xTxFrame; }CAN_COMM_MSG; //触发发送条件内部定时器和标志位的定义 typedef struct _CAN_INTIM_ { unsigned short u16Time; //发送等待计时 unsigned long u32CanID; //ID值和发送的标记 unsigned char u8Ident; // unsigned short u16CycTxTime; }CAN_INTIM; //*******************接收*************************// typedef struct _MSG_SYS_LK_ { unsigned char u8LiftMsg; unsigned char u8rsvd; unsigned char u8Ident; unsigned char u8SWVer; unsigned char u8Mod; unsigned char u8HWVer; }MSG_SYS_LK; typedef struct _MSG_FROM_MC2_IDM_ { unsigned char u8Mask; unsigned char u8Data; unsigned char u8MsgCnt; }MSG_FROM_MC2_IDM; typedef struct _MSG_FROM_MC2_ { MSG_SYS_LK xMsgLk; MSG_FROM_MC2_IDM xMsgId70; MSG_FROM_MC2_IDM xMsgId71; MSG_FROM_MC2_IDM xMsgId72; MSG_FROM_MC2_IDM xMsgId73; MSG_FROM_MC2_IDM xMsgId80; MSG_FROM_MC2_IDM xMsgId81; }MSG_FROM_MC2; //*******************发送*************************// typedef struct _MSG_FROM_MF3_DI_ { unsigned char u8MaskId30; unsigned char u8MsgId30; unsigned char u8MaskId32; unsigned char u8MsgId32; unsigned char u8MaskId34; unsigned char u8MsgId34; unsigned char u8MaskIdA0; unsigned char u8MsgIdA0; unsigned char u8MaskIdA1; unsigned char u8MsgIdA1; }MSG_FROM_MF3_DI; //total typedef struct _MSG_FROM_MF3_ { MSG_SYS_LK xMsgLk; MSG_FROM_MF3_DI xMsgDi; }MSG_FROM_MF3; //****************EID*********** typedef struct _CAN_EID_PROCESS__ { unsigned char u8ReqFlag; unsigned char u8TxFlag; unsigned char u8Step; unsigned char u8TxNum; unsigned char u8TxTimer; }CAN_EID_PROCESS; //***********macro definiton************************// #define CAN_COMM_INIT 0 //通讯握手 #define CAN_COMM_OK 1 //握手成功正常传输 #define CAN_ID_NULL 0xFFFFFFFF #define UP_LIMIT_IN_TIM 0xFFFF //发送计数上限制 #define CAN_POS_NULL 0xFFFF #define CAN_IDENT_NULL 0xFF //****************************CAN_ID************************************// #define CAN_ID_MF3_TO_MC2 0x191 #define CAN_ID_MF3_TO_MC2_EXT 0x02000000 #define CAN_ID_MF3_TO_MC2_EID 0x112 #define CAN_MC2_TO_MF3_ID100 0x100 #define CAN_MC2_TO_MF3_ID740 0x740 #define CAN_MC2_TO_MF3_ID500 0x500 //****************************Identification*****************************// #define IDENT_MF3_F8 0xF8 #define IDENT_MF3_F9 0xF9 #define IDENT_MF3_30 0x30 #define IDENT_MF3_32 0x32 #define IDENT_MF3_34 0x34 #define IDENT_MF3_FA 0xFA #define IDENT_MF3_A0 0xA0 #define IDENT_MF3_A1 0xA1 #define IDENT_MF3_EID 0XE5 #define IDENT_MF3_EXT 0XFE #define IDENT_MC2_F8 0xF8 #define IDENT_MC2_E8 0xE8 #define IDENT_MC2_40 0x40 #define IDENT_MC2_47 0x47 #define IDENT_MC2_48 0x48 #define IDENT_MC2_49 0x49 #define IDENT_MC2_50 0x50 #define IDENT_MC2_51 0x51 #define IDENT_MC2_52 0x52 #define IDENT_MC2_60 0x60 #define IDENT_MC2_61 0x61 #define IDENT_MC2_62 0x62 #define IDENT_MC2_63 0x63 #define IDENT_MC2_64 0x64 #define IDENT_MC2_65 0x65 #define IDENT_MC2_66 0x66 #define IDENT_MC2_67 0x67 #define IDENT_MC2_68 0x68 #define IDENT_MC2_69 0x69 #define IDENT_MC2_6A 0x6A #define IDENT_MC2_6B 0x6B #define IDENT_MC2_6C 0x6C #define IDENT_MC2_6D 0x6D #define IDENT_MC2_6E 0x6E #define IDENT_MC2_6F 0x6F #define IDENT_MC2_70 0x70 #define IDENT_MC2_71 0x71 #define IDENT_MC2_72 0x72 #define IDENT_MC2_73 0x73 #define IDENT_MC2_80 0x80 #define IDENT_MC2_81 0x81 #define IDENT_MC2_EID 0XE4 #define CAN_LINK_STEP0 0 #define CAN_LINK_STEP1 1 #define CAN_LINK_STEP2 2 #define CAN_LINK_STEP3 3 #define CAN_LINK_STEP4 4 #define CAN_LINK_STEP5 5 #define MF3_D2_DEVICE_NO 0 //******************************************** #define CAN_EID_STEP0 0 #define CAN_EID_STEP1 1 #define CAN_EID_STEP2 2 #define CAN_EID_STEP3 3 #define CAN_EID_STEP4 4 #define CAN_EID_STEP5 5 #define CAN_EID_STEP6 6 #define CAN_EID_STEP7 7 #define CAN_EID_STEP8 8 #define CAN_EID_STEP9 9 #define CAN_EID_STEP_END 20 //每个ID的周期定时的位置宏 #define ID_TIM_POS_IDFA 0 #define ID_TIM_POS_ID30 1 #define ID_TIM_POS_ID32 2 #define ID_TIM_POS_ID34 3 #define ID_TIM_POS_IDA0 4 #define ID_TIM_POS_IDA1 5 #define ID_TIM_POS_EID 6 #define ID_TIM_POS_EXT 7 #define ID_TIM_POS8 8 #define ID_TIM_POS9 9 #define ID_TIM_POS10 10 #define ID_TIM_POS11 11 #define ID_TIM_POS12 12 #define ID_TIM_POS13 13 #define ID_TIM_POS14 14 #define ID_TIM_POS15 15 #define ID_TIM_POS16 16 #define ID_TIM_POS17 17 #define ID_TIM_POS18 18 #define ID_TIM_POS19 19 #define CAN1_COMM_IS_OK() (gObjCan1_xMsg.u16CanStatus==CAN_COMM_OK) //***********prototype function definiton*************// void ObjCan1_Init(void); void ObjCan1_Main(void); void ObjCan1_RxDeal(void); //***********prototype variable definiton*************// extern CAN_COMM_MSG gObjCan1_xMsg; extern MSG_FROM_MC2 gObjCan1_xMsgFromMc2; extern MSG_FROM_MF3 gObjCan1_xMsgFromMf3; extern CAN_RX_FIFO gObjCan1_xRxFifo; extern CAN_EID_PROCESS gObjCan1_xEid; #ifdef __cplusplus } #endif #endif /*__ pinoutConfig_H */

/* FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. All rights reserved VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. This file is part of the FreeRTOS distribution. FreeRTOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2) as published by the Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *************************************************************************** >>! NOTE: The modification to the GPL is included to allow you to !<< >>! distribute a combined work that includes FreeRTOS without being !<< >>! obliged to provide the source code for proprietary components !<< >>! outside of the FreeRTOS kernel. !<< *************************************************************************** FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Full license text is available on the following link: http://www.freertos.org/a00114.html *************************************************************************** * * * FreeRTOS provides completely free yet professionally developed, * * robust, strictly quality controlled, supported, and cross * * platform software that is more than just the market leader, it * * is the industry's de facto standard. * * * * Help yourself get started quickly while simultaneously helping * * to support the FreeRTOS project by purchasing a FreeRTOS * * tutorial book, reference manual, or both: * * http://www.FreeRTOS.org/Documentation * * * *************************************************************************** http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading the FAQ page "My application does not run, what could be wrong?". Have you defined configASSERT()? http://www.FreeRTOS.org/support - In return for receiving this top quality embedded software for free we request you assist our global community by participating in the support forum. http://www.FreeRTOS.org/training - Investing in training allows your team to be as productive as possible as early as possible. Now you can receive FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers Ltd, and the world's leading authority on the world's leading RTOS. http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, including FreeRTOS+Trace - an indispensable productivity tool, a DOS compatible FAT file system, and our tiny thread aware UDP/IP stack. http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS licenses offer ticketed support, indemnification and commercial middleware. http://www.SafeRTOS.com - High Integrity Systems also provide a safety engineered and independently SIL3 certified version for use in safety and mission critical applications that require provable dependability. 1 tab == 4 spaces! */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H #include "stm32f10x.h" // Device header //* 1:RTOS使用抢占式调度器;0:RTOS使用协作式调度器(时间片) #define configUSE_PREEMPTION 1 /*一些 FreeRTOS 移植有两种选择下一个执行任务的方法, *0:一种是通用方法, *1:另一种是移植特定的方法(依赖于一种或多种架构特定的汇编指令 (通常是前导零计数 [CLZ] 指令或同等指令) , *因此 仅适用于专为其编写该指令的架构。)。 */ //#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 //设置为 1,使用 低功耗无 滴答 模式, 或设置为 0,保持 滴答 中断始终运行。 #define configUSE_TICKLESS_IDLE 1 //内核时钟 #define configCPU_CLOCK_HZ (SystemCoreClock) //SysTick 时钟频率 系统已定义,此处不用定义 //#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ //RTOS系统节拍中断的频率 1ms #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) //可使用的最大优先级 #define configMAX_PRIORITIES (32) //空闲任务使用的堆栈大小 #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) //任务名字字符串长度 #define configMAX_TASK_NAME_LEN 16 //系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形 #define configUSE_16_BIT_TICKS 0 // RTOS 内核启动后,滴答中断已经执行的次数。滴答数存放在 滴答Type_t 类型的变量中 //#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS //空闲任务放弃CPU使用权给其他同优先级的用户任务 #define configIDLE_SHOULD_YIELD 1 //开启任务通知功能,1开启 //#define configUSE_TASK_NOTIFICATIONS 1 //每个 RTOS 任务都有一个任务通知数组。 configTASK_NOTIFICATION_ARRAY_ENTRIES 设置数组的索引数。 //#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 //1 使用互斥信号量 #define configUSE_MUTEXES 1 //1 使用递归互斥信号量 //#define configUSE_RECURSIVE_MUTEXES 0 //1 使用计数信号量 //#define configUSE_COUNTING_SEMAPHORES 0 //#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ //设置可以注册的信号量和消息队列个数 //#define configQUEUE_REGISTRY_SIZE 10 //启用队列 //#define configUSE_QUEUE_SETS 0 //1使能时间片调度 //#define configUSE_TIME_SLICING 1 //如果 configUSE_NEWLIB_REENTRANT 设置为 1,那么将为每个创建的任务分配一个newlib 重入结构体 。 //#define configUSE_NEWLIB_REENTRANT 0 //1 兼容8.0以前的版本 //#define configENABLE_BACKWARD_COMPATIBILITY 0 //设置每个任务的 线程本地存储数组 //#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 //设置为 0 时, MiniListItem_t 和 ListItem_t 保持一致。设置为 1 时,MiniListItem_t 包含的字段比 ListItem_t 少 3 个 //#define configUSE_MINI_LIST_ITEM 1 //设置调用 xTaskCreate() 时用于指定堆栈深度的类型 //#define configSTACK_DEPTH_TYPE uint16_t //消息缓冲区使用 configMESSAGE_BUFFER_LENGTH_TYPE 类型的变量存储 每个消息的长度 //#define configMESSAGE_BUFFER_LENGTH_TYPE size_t // //#define configHEAP_CLEAR_MEMORY_ON_FREE 1 /***************************************************************** FreeRTOS与内存申请有关配置选项 *****************************************************************/ //支持静态内存 #define configSUPPORT_STATIC_ALLOCATION 0 //支持动态内存申请 #define configSUPPORT_DYNAMIC_ALLOCATION 1 //系统所有总的堆大小 #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) /*默认情况下,FreeRTOS 堆由 FreeRTOS 声明 并由链接器放置在存储器中。 *将 configAPPLICATION_ALLOCATED_HEAP 设置为 1, *允许应用程序编写者声明堆,这使得 应用程序编写者可以将堆放置在内存的任意位置。 *如果使用 heap_1.c、heap_2.c 或 heap_4.c,并且将 configAPPLICATION_ALLOCATED_HEAP 设置为 1, *那么应用程序编写者必须提供一个 uint8_t 数组, 其确切的名称和大小如下所示。 *该数组将用作 FreeRTOS 堆。 数组如何放置在内存的特定位置取决于使用的编译器, 请参阅编译器的文档。 */ //#define configAPPLICATION_ALLOCATED_HEAP 1 /*设置为 1,那么对于任何 使用 xTaskCreate 或 xTaskCreateRestricted API 创建的任务, *其堆栈 使用 pvPortMallocStack 函数分配并使用 vPortFreeStack 函数释放。 *用户需要 实现线程安全的 pvPortMallocStack 和 vPortFreeStack 函数。 */ //#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 1 /*************************************************************** FreeRTOS与钩子函数有关的配置选项 **************************************************************/ /* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子 * * 空闲任务钩子是一个函数,这个函数由用户来实现, * FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ), * 这个函数在每个空闲任务周期都会被调用 * 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。 * 因此必须保证空闲任务可以被CPU执行 * 使用空闲钩子函数设置CPU进入省电模式是很常见的 * 不可以调用会引起空闲任务阻塞的API函数 */ #define configUSE_IDLE_HOOK 0 /* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子 * * * 时间片钩子是一个函数,这个函数由用户来实现, * FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void ) * 时间片中断可以周期性的调用 * 函数必须非常短小,不能大量使用堆栈, * 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数 */ /*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/ #define configUSE_TICK_HOOK 0 /* * 大于0时启用堆栈溢出检测功能,如果使用此功能 * 用户必须提供一个栈溢出钩子函数,如果使用的话 * 此值可以为1或者2,因为有两种栈溢出检测方法 */ //#define configCHECK_FOR_STACK_OVERFLOW 0 //使用内存申请失败钩子函数 #define configUSE_MALLOC_FAILED_HOOK 0 //#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 //#define configUSE_SB_COMPLETED_CALLBACK 0 /******************************************************************** FreeRTOS与运行时间和任务状态收集有关的配置选项 **********************************************************************/ //启用运行时间统计功能 //#define configGENERATE_RUN_TIME_STATS 0 //启用可视化跟踪调试 //#define configUSE_TRACE_FACILITY 1 /* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数 * prvWriteNameToBuffer() * vTaskList(), * vTaskGetRunTimeStats() */ //#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /******************************************************************** FreeRTOS与协程有关的配置选项 *********************************************************************/ //启用协程,启用协程以后必须添加文件croutine.c #define configUSE_CO_ROUTINES 0 ////协程的有效优先级数目 #define configMAX_CO_ROUTINE_PRIORITIES 2 /*********************************************************************** FreeRTOS与软件定时器有关的配置选项 **********************************************************************/ //启用软件定时器 #define configUSE_TIMERS 0 //软件定时器优先级 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) //软件定时器队列长度 #define configTIMER_QUEUE_LENGTH 10 //软件定时器任务堆栈大小 #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) /************************************************************ 中断嵌套行为配置 ************************************************************/ #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 #endif //中断最低优先级 #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //系统可管理的最高中断优先级 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) //#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] /************************************************************ 断言配置 ************************************************************/ //#define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) /************************************************************ FreeRTOS MPU的具体定义 ************************************************************/ //#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 //#define configTOTAL_MPU_REGIONS 8 /* Default value. */ //#define configTEX_S_C_B_FLASH 0x07UL /* Default value. */ //#define configTEX_S_C_B_SRAM 0x07UL /* Default value. */ //#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 //#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 //#define configENABLE_ERRATA_837070_WORKAROUND 1 //#define configUSE_MPU_WRAPPERS_V1 0 //#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 10 //#define configSYSTEM_CALL_STACK_SIZE 128 ///* ARMv8-M secure side port related definitions. */ //#define secureconfigMAX_SECURE_CONTEXTS 5 /************************************************************ FreeRTOS可选函数配置选项 ************************************************************/ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_xResumeFromISR 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark2 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_eTaskGetState 1 #define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 0 #define INCLUDE_xTaskAbortDelay 0 #define INCLUDE_xTaskGetHandle 0 #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_vTaskCleanUpResources 0 /* A header file that defines trace macro can be included here. */ #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler //#define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */ freertos用的是什么时钟?

基于stm32cubemx,stm32f103c8t6,kile5mdk,和oled.c,oled.h文件帮我写雨滴传感器的驱动文件rain.c和rain.h,并在main.c中写出显示语句在显示屏上显示,雨量大小,雨滴传感器的AO接PA6,用到的电位器是3362#ifndef __OLED_H_ #define __OLED_H_ #include "stdint.h" #include "i2c.h" void WriteCmd(void); //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd); //向设备写数据 void OLED_WR_DATA(uint8_t data); //初始化oled屏幕 void OLED_Init(void); //清屏 void OLED_Clear(void); //开启OLED显示 void OLED_Display_On(void); //关闭OLED显示 void OLED_Display_Off(void); //设置光标 void OLED_Set_Pos(uint8_t x, uint8_t y); void OLED_On(void); //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size); //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2); //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); #endif #include "oled.h" #include "oledfont.h" //几个变量声明 uint8_t **Hzk; //初始化命令 uint8_t CMD_Data[]={ 0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12, 0xD8, 0x30, 0x8D, 0x14, 0xAF}; void WriteCmd() { uint8_t i = 0; for(i=0; i<27; i++){ HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,CMD_Data+i,1,0x100); } } //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100); } //向设备写数据 void OLED_WR_DATA(uint8_t data) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100); } //初始化oled屏幕 void OLED_Init(void) { HAL_Delay(200); WriteCmd(); } //清屏 void OLED_Clear() { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } } //开启OLED显示 void OLED_Display_On(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X14); //DCDC ON OLED_WR_CMD(0XAF); //DISPLAY ON } //关闭OLED显示 void OLED_Display_Off(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X10); //DCDC OFF OLED_WR_CMD(0XAE); //DISPLAY OFF } void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_WR_CMD(0xb0+y); OLED_WR_CMD(((x&0xf0)>>4)|0x10); OLED_WR_CMD(x&0x0f); } void OLED_On(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(1); } //更新显示 } unsigned int oled_pow(uint8_t m,uint8_t n) { unsigned int result=1; while(n--)result*=m; return result; } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>128-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i]); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i+8]); } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_WR_DATA(F6x8[c][i]); } } //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2) { uint8_t t,temp; uint8_t enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } } //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size) { unsigned char j=0; while (chr[j]!='\0') { OLED_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>120){x=0;y+=2;} j++; } } //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no) { uint8_t t,adder=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no][t]); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no+1][t]); adder+=1; } } /* 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 "i2c.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "OLED.h" #include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ double yudi=0; int data=0; //sprintf((char *)LCD_r37_adc," R37:%.2fV ",r37); /* 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_ADC1_Init(); MX_USART1_UART_Init(); MX_I2C1_Init(); MX_ADC2_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); OLED_Display_On();//����OLED��ʾ //���� OLED_Clear(); // OLED_ShowNum(10,10,10,8,8); // OLED_ShowChar(0, 0,'C',16); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_ADC_Start(&hadc2); HAL_ADC_PollForConversion(&hadc2,HAL_MAX_DELAY); yudi= 4095-HAL_ADC_GetValue(&hadc2) * 1000/4095.0; uint8_t A[]="hdilisa !!"; OLED_ShowString(0,0,A,sizeof(A)); //OLED_ShowString(0,2,YUDI,sizeof(YUDI)); char display_str[16]; sprintf(display_str, "data:%.2fL/m2", yudi); // 在OLED指定位置显示(x=0,y=0,10) OLED_ShowString(0, 2, (uint8_t*)display_str,10); } /* 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 */ /* 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 */

基于stm32cubemx,stm32f103c8t6,四针脚的oled,帮我写雨滴传感器的驱动文件,实现测量雨量大小并在屏幕上,雨量处理数据和显示数据在main.c中写,其中oled.c:#include "oled.h" #include "oledfont.h" //几个变量声明 uint8_t **Hzk; //初始化命令 uint8_t CMD_Data[]={ 0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12, 0xD8, 0x30, 0x8D, 0x14, 0xAF}; void WriteCmd() { uint8_t i = 0; for(i=0; i<27; i++){ HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,CMD_Data+i,1,0x100); } } //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100); } //向设备写数据 void OLED_WR_DATA(uint8_t data) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100); } //初始化oled屏幕 void OLED_Init(void) { HAL_Delay(200); WriteCmd(); } //清屏size12 size16要清两行,其他函数有类似情况 void OLED_Clear() { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } } //清行 void OLED_Clearrow(uint8_t i) { uint8_t n; OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } //开启OLED显示 void OLED_Display_On(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X14); //DCDC ON OLED_WR_CMD(0XAF); //DISPLAY ON } //关闭OLED显示 void OLED_Display_Off(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X10); //DCDC OFF OLED_WR_CMD(0XAE); //DISPLAY OFF } void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_WR_CMD(0xb0+y); OLED_WR_CMD(((x&0xf0)>>4)|0x10); OLED_WR_CMD(x&0x0f); } void OLED_On(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(1); } //更新显示 } unsigned int oled_pow(uint8_t m,uint8_t n) { unsigned int result=1; while(n--)result*=m; return result; } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>128-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i]); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i+8]); } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_WR_DATA(F6x8[c][i]); } } //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2) { uint8_t t,temp; uint8_t enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } } //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size) { unsigned char j=0; while (chr[j]!='\0') { OLED_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>120){x=0;y+=2;} j++; } } //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no) { uint8_t t,adder=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no][t]); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no+1][t]); adder+=1; } } oled.h:#ifndef __OLED_H_ #define __OLED_H_ #include "stdint.h" #include "i2c.h" void WriteCmd(void); //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd); //向设备写数据 void OLED_WR_DATA(uint8_t data); //初始化oled屏幕 void OLED_Init(void); //清屏 void OLED_Clear(void); //清行 void OLED_Clearrow(uint8_t i); //开启OLED显示 void OLED_Display_On(void); //关闭OLED显示 void OLED_Display_Off(void); //设置光标 void OLED_Set_Pos(uint8_t x, uint8_t y); void OLED_On(void); //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size); //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2); //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); #endif main.c:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2019 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "i2c.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #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 */ 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_I2C1_Init(); /* USER CODE BEGIN 2 */ uint8_t A[]="hdilisa !!"; //初始化oled屏幕 OLED_Init(); //开启OLED显示 OLED_Display_On(); //清屏 OLED_Clear(); // OLED_ShowNum(10,10,10,8,8); // OLED_ShowChar(0, 0,'C',16); OLED_ShowString(0,0,A,sizeof(A)); // //清行 // OLED_Clearrow(2); // OLED_Clearrow(3); /* 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 CPU, AHB and APB busses clocks */ 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 busses 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 */ /* 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, tex: 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****/

大家在看

recommend-type

C语言流程图生成工具

AutoFlowChart 自动生成流程图 AutoFlowchart 是一个极佳的根据源码生成流程图的工具 它生成的流程图支持展开 合拢 并且可以预定义流程图块的大小和间隔 移动和缩放流程图也很方便 你还可以把它导出到WORD文档或BMP文件 它可以帮助程序员更好地理解程序 制作文档和可视化代码 支持C C++ VC++ Visual C++ NET Delphi Object Pascal 主要功能 根据源程序生成流程图 导出流程图到WORD文档中 展开 合拢流程图 自动生成一个 TreeView显示所有函数 过程 同步显示对应块的源程序和流程图 自定义流程图的配色方案 自定义流程图的大小和间距 根据格式自动排列程序 自由缩小 放大 移动流程图 显示程序行号 支持清除当前流程图 导出流程图到 bmp文件 发展前瞻 ① 支持各种语言 已经完成Pascal C 待完成:Java FoxPro Basic Fortan等; ② 支持反向操作 可以动态修改流程图 并可根据流程图生成相应的语言代码; ③ 结合Delphi专家 嵌入IDE直接运行 已经完成详见主页 操作说明 ① 打开一个或多个文件; ② 双击一个If For While Case Repeat Try begin的起始行 你就可以看到流程图; ③ 双击流程图中相应的框 可以同步显示程序块位置;">AutoFlowChart 自动生成流程图 AutoFlowchart 是一个极佳的根据源码生成流程图的工具 它生成的流程图支持展开 合拢 并且可以预定义流程图块的大小和间隔 移动和缩放流程图也很方便 你还可以把它导出到WORD文档或BMP文件 [更多]
recommend-type

GPRS网络信令实例详解

抓取了GPRS各个接口信令,很详细的各类问题抓包,值得喜欢分析的人下载做为原材料
recommend-type

The GNU Toolchain for ARM targets HOWTO.pdf

英文原版的介绍怎样制作交叉编译工具的资料
recommend-type

高频双调谐谐振放大电路设计3MHz+电压200倍放大.zip

高频双调谐谐振放大电路设计3MHz+电压200倍放大.zip
recommend-type

中国地级市地图shp

中国地级市地图shp文件,希望对大家科研有帮助。

最新推荐

recommend-type

Google C++ Style Guide(Google C++编程规范)高清PDF

Header Files The #define Guard Header File Dependencies Inline Functions The -inl.h Files Function Parameter Ordering Names and Order of Includes Scoping Namespaces Nested Classes Nonmember, Static ...
recommend-type

netty-all-4.1.23.Final.jar中文文档.zip

1、压缩文件中包含: 中文文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
recommend-type

OKT507_修改默认界面显示_Linux_应用笔记_V1.0_20220627.pdf

OKT507_修改默认界面显示_Linux_应用笔记_V1.0_20220627
recommend-type

Linux_G2D_开发指南.pdf

Linux_G2D_开发指南
recommend-type

天气系统插件,所见即所得

天气系统插件,所见即所得
recommend-type

实现Struts2+IBatis+Spring集成的快速教程

### 知识点概览 #### 标题解析 - **Struts2**: Apache Struts2 是一个用于创建企业级Java Web应用的开源框架。它基于MVC(Model-View-Controller)设计模式,允许开发者将应用的业务逻辑、数据模型和用户界面视图进行分离。 - **iBatis**: iBatis 是一个基于 Java 的持久层框架,它提供了对象关系映射(ORM)的功能,简化了 Java 应用程序与数据库之间的交互。 - **Spring**: Spring 是一个开源的轻量级Java应用框架,提供了全面的编程和配置模型,用于现代基于Java的企业的开发。它提供了控制反转(IoC)和面向切面编程(AOP)的特性,用于简化企业应用开发。 #### 描述解析 描述中提到的“struts2+ibatis+spring集成的简单例子”,指的是将这三个流行的Java框架整合起来,形成一个统一的开发环境。开发者可以利用Struts2处理Web层的MVC设计模式,使用iBatis来简化数据库的CRUD(创建、读取、更新、删除)操作,同时通过Spring框架提供的依赖注入和事务管理等功能,将整个系统整合在一起。 #### 标签解析 - **Struts2**: 作为标签,意味着文档中会重点讲解关于Struts2框架的内容。 - **iBatis**: 作为标签,说明文档同样会包含关于iBatis框架的内容。 #### 文件名称列表解析 - **SSI**: 这个缩写可能代表“Server Side Include”,一种在Web服务器上运行的服务器端脚本语言。但鉴于描述中提到导入包太大,且没有具体文件列表,无法确切地解析SSI在此的具体含义。如果此处SSI代表实际的文件或者压缩包名称,则可能是一个缩写或别名,需要具体的上下文来确定。 ### 知识点详细说明 #### Struts2框架 Struts2的核心是一个Filter过滤器,称为`StrutsPrepareAndExecuteFilter`,它负责拦截用户请求并根据配置将请求分发到相应的Action类。Struts2框架的主要组件有: - **Action**: 在Struts2中,Action类是MVC模式中的C(控制器),负责接收用户的输入,执行业务逻辑,并将结果返回给用户界面。 - **Interceptor(拦截器)**: Struts2中的拦截器可以在Action执行前后添加额外的功能,比如表单验证、日志记录等。 - **ValueStack(值栈)**: Struts2使用值栈来存储Action和页面间传递的数据。 - **Result**: 结果是Action执行完成后返回的响应,可以是JSP页面、HTML片段、JSON数据等。 #### iBatis框架 iBatis允许开发者将SQL语句和Java类的映射关系存储在XML配置文件中,从而避免了复杂的SQL代码直接嵌入到Java代码中,使得代码的可读性和可维护性提高。iBatis的主要组件有: - **SQLMap配置文件**: 定义了数据库表与Java类之间的映射关系,以及具体的SQL语句。 - **SqlSessionFactory**: 负责创建和管理SqlSession对象。 - **SqlSession**: 在执行数据库操作时,SqlSession是一个与数据库交互的会话。它提供了操作数据库的方法,例如执行SQL语句、处理事务等。 #### Spring框架 Spring的核心理念是IoC(控制反转)和AOP(面向切面编程),它通过依赖注入(DI)来管理对象的生命周期和对象间的依赖关系。Spring框架的主要组件有: - **IoC容器**: 也称为依赖注入(DI),管理对象的创建和它们之间的依赖关系。 - **AOP**: 允许将横切关注点(如日志、安全等)与业务逻辑分离。 - **事务管理**: 提供了一致的事务管理接口,可以在多个事务管理器之间切换,支持声明式事务和编程式事务。 - **Spring MVC**: 是Spring提供的基于MVC设计模式的Web框架,与Struts2类似,但更灵活,且与Spring的其他组件集成得更紧密。 #### 集成Struts2, iBatis和Spring 集成这三种框架的目的是利用它们各自的优势,在同一个项目中形成互补,提高开发效率和系统的可维护性。这种集成通常涉及以下步骤: 1. **配置整合**:在`web.xml`中配置Struts2的`StrutsPrepareAndExecuteFilter`,以及Spring的`DispatcherServlet`。 2. **依赖注入配置**:在Spring的配置文件中声明Struts2和iBatis的组件,以及需要的其他bean,并通过依赖注入将它们整合。 3. **Action和SQL映射**:在Struts2中创建Action类,并在iBatis的SQLMap配置文件中定义对应的SQL语句,将Struts2的Action与iBatis的映射关联起来。 4. **事务管理**:利用Spring的事务管理功能来管理数据库操作的事务。 5. **安全和服务层**:通过Spring的AOP和IoC功能来实现业务逻辑的解耦合和事务的管理。 ### 结语 通过上述的整合,开发者可以有效地利用Struts2处理Web层的展示和用户交互,使用iBatis简化数据库操作,同时借助Spring强大的依赖注入和事务管理功能,创建一个结构良好、可维护性强的应用。这种集成方式在许多企业级Java Web应用中非常常见,是Java开发人员必须掌握的知识点。
recommend-type

【数据融合技术】:甘肃土壤类型空间分析中的专业性应用

# 摘要 数据融合技术作为一种集成多源数据信息的方法,在土壤类型空间分析中发挥着关键作用。本文介绍了数据融合技术的基本概念及其理论基础,阐述了数据预处理、同步整合及冲突解决等关键技术,并详细描述了甘肃土壤类型数据准备的流程,包括数据采集、质量评估、空间化处理及融合实践准备。通过具体案例分析,展示了数据融合在土壤类型空间分布分析、土壤质量评估及土壤保护规划中的应用。同时,文
recommend-type

Waymo使用稀疏图卷积处理LiDAR点云,目标检测精度提升15%

<think>好的,用户让我介绍一下Waymo使用稀疏图卷积处理LiDAR点云,目标检测精度提升15%的具体情况。我需要先回忆之前提供的回答中提到的相关案例,然后深入展开。 首先,用户可能已经知道稀疏图卷积的基本概念,但需要更详细的应用案例。他们可能对Waymo如何具体应用该技术感兴趣,比如技术细节、实现方式、提升的具体指标等。需要确保回答结构清晰,分点说明,同时保持技术准确性。 要考虑到用户可能的背景,可能是研究或工程领域的,需要技术细节,但避免过于复杂的数学公式,除非必要。之前回答中提到了应用案例,现在需要扩展这个部分。需要解释为什么稀疏图卷积在这里有效,比如处理LiDAR点云的稀疏性
recommend-type

Dwr实现无刷新分页功能的代码与数据库实例

### DWR简介 DWR(Direct Web Remoting)是一个用于允许Web页面中的JavaScript直接调用服务器端Java方法的开源库。它简化了Ajax应用的开发,并使得异步通信成为可能。DWR在幕后处理了所有的细节,包括将JavaScript函数调用转换为HTTP请求,以及将HTTP响应转换回JavaScript函数调用的参数。 ### 无刷新分页 无刷新分页是网页设计中的一种技术,它允许用户在不重新加载整个页面的情况下,通过Ajax与服务器进行交互,从而获取新的数据并显示。这通常用来优化用户体验,因为它加快了响应时间并减少了服务器负载。 ### 使用DWR实现无刷新分页的关键知识点 1. **Ajax通信机制:**Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过XMLHttpRequest对象,可以与服务器交换数据,并使用JavaScript来更新页面的局部内容。DWR利用Ajax技术来实现页面的无刷新分页。 2. **JSON数据格式:**DWR在进行Ajax调用时,通常会使用JSON(JavaScript Object Notation)作为数据交换格式。JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 3. **Java后端实现:**Java代码需要编写相应的后端逻辑来处理分页请求。这通常包括查询数据库、计算分页结果以及返回分页数据。DWR允许Java方法被暴露给前端JavaScript,从而实现前后端的交互。 4. **数据库操作:**在Java后端逻辑中,处理分页的关键之一是数据库查询。这通常涉及到编写SQL查询语句,并利用数据库管理系统(如MySQL、Oracle等)提供的分页功能。例如,使用LIMIT和OFFSET语句可以实现数据库查询的分页。 5. **前端页面设计:**前端页面需要设计成能够响应用户分页操作的界面。例如,提供“下一页”、“上一页”按钮,或是分页条。这些元素在用户点击时会触发JavaScript函数,从而通过DWR调用Java后端方法,获取新的分页数据,并动态更新页面内容。 ### 数据库操作的关键知识点 1. **SQL查询语句:**在数据库操作中,需要编写能够支持分页的SQL查询语句。这通常涉及到对特定字段进行排序,并通过LIMIT和OFFSET来控制返回数据的范围。 2. **分页算法:**分页算法需要考虑当前页码、每页显示的记录数以及数据库中记录的总数。SQL语句中的OFFSET计算方式通常为(当前页码 - 1)* 每页记录数。 3. **数据库优化:**在分页查询时,尤其是当数据量较大时,需要考虑到查询效率问题。可以通过建立索引、优化SQL语句或使用存储过程等方式来提高数据库操作的性能。 ### DWR无刷新分页实现的代码要点 1. **DWR配置:**在实现DWR无刷新分页时,首先需要配置DWR,以暴露Java方法给前端JavaScript调用。 2. **JavaScript调用:**编写JavaScript代码,使用DWR提供的API发起Ajax调用。这些调用将触发后端Java方法,并接收返回的分页数据。 3. **数据展示:**在获取到新的分页数据后,需要将这些数据显示在前端页面的相应位置。这通常需要操作DOM元素,将新数据插入到页面中。 ### 结论 通过结合上述知识点,可以使用DWR技术实现一个无刷新分页的动态Web应用。DWR简化了Ajax通信过程,让开发者可以专注于业务逻辑的实现。通过熟练掌握Java后端处理、数据库查询和前端页面设计的相关技术,便能高效地完成无刷新分页的开发任务。
recommend-type

【空间分布规律】:甘肃土壤类型与农业生产的关联性研究

# 摘要 本文对甘肃土壤类型及其在农业生产中的作用进行了系统性研究。首先概述了甘肃土壤类型的基础理论,并探讨了土壤类型与农业生产的理论联系。通过GIS技术分析,本文详细阐述了甘肃土壤的空间分布规律,并对其特征和影响因素进行了深入分析。此外,本文还研究了甘肃土壤类型对农业生产实际影响,包括不同区域土壤改良和作物种植案例,以及土壤养分、水分管理对作物生长周期和产量的具体影响。最后,提出了促进甘肃土壤与农业可持续发展的策略,包括土壤保护、退化防治对策以及土壤类型优化与农业创新的结合。本文旨在为