一、项目概述1.1 项目功能基于 STM32 标准库F10372MHz 系统时钟设计分段温控 PWM 调速风扇系统搭载 DS18B20 采集环境温度通过温度阈值自动切换风扇停机 / 低速 / 中速 / 全速四档位附带以下配套功能5 阶滑动均值滤波消除温度采集抖动2℃温度回差防止风扇频繁启停跳档超高温区间间歇蜂鸣报警LCD1602 实时显示当前温度、风扇运行档位USART1 串口 9600bps 打印温度与 PWM 占空比LED 周期心跳指示系统正常运行DS18B20 传感器断线 / 未接入检测LCD 报错提示TIM3_CH1 输出 10kHz PWM 波形驱动风扇调速PA6 复用输出。1.2 硬件资源分配STM32F103表格外设模块占用 IO功能说明LED 指示灯PB1200ms 翻转心跳灯蜂鸣器 BEEPPB5超温间歇报警DS18B20 单总线自定义引脚头文件宏定义温度采集USART1 串口PA9(TX)、PA10(RX)打印调试信息回显接收数据TIM3_CH1 PWMPA6风扇调速 10kHz PWM 输出LCD1602 控制脚PB0(RS)、PB1(RW)、PB2(E)屏幕控制LCD1602 数据脚PB8~PB158 位并行数据口系统时钟APB272MHz定时器、GPIO、串口时钟源1.3 核心温控参数表格参数宏数值含义TEMP_STOP27.0℃低于该温度风扇停机TEMP_LOW31.0℃低速档分界温度TEMP_MID40.0℃中速 / 全速分界温度TEMP_HYSTER2.0℃温度回差防频繁跳档PWM_PSC71TIM3 预分频72M/(711)1MHzPWM_ARR999自动重装载值PWM 频率 1M/(9991)10kHzDUTY_STOP00% 占空比风扇停止DUTY_SLOW30030% 占空比低速DUTY_MID60060% 占空比中速DUTY_FULL999100% 占空比全速1.4 温控档位逻辑带回差防抖停机档滤波温度 27℃ → PWM0风扇停转低速档 (30%)27℃ ≤ 温度 31℃中速档 (60%)31℃ ≤ 温度 40℃全速档 (100%)温度 ≥40℃蜂鸣器间歇报警回差机制降温时必须低于档位阈值 - 2℃才降档避免温度在临界点小幅波动导致风扇反复切换。二、文件分层架构说明项目共 9 个代码文件分为主逻辑文件外设驱动头源文件分层解耦便于单独移植外设驱动。plaintext├── main.c // 主程序、温控逻辑、系统总调度 ├── pwm.c // TIM3_CH1 PWM初始化、占空比设置驱动 ├── ds18b20.c // DS18B20单总线温度传感器完整驱动 ├── led.c // LED指示灯底层初始化 ├── beep.c // 有源蜂鸣器开关驱动 ├── usart.c // USART1串口驱动支持printf重定向 ├── SysTick.c // 系统滴答定时器us/ms延时函数 ├── lcd1602.c // LCD1602 8位并行驱动清屏/字符串显示 ├── system.h // 系统基础宏、类型定义u8/u16等三、各文件逐模块详细说明3.1 main.c 主程序核心文件3.1.1 全局变量说明float temp_buf[5]5 点滑动滤波缓存存储连续 5 次温度采样u8 buf_idx滤波数组循环下标float temp_filter滤波后平滑温度系统温控使用该值原始采样值不参与控制float last_temp上一次滤波温度用于回差跳档判断static u8 fan_state风扇档位状态机0 停机 / 1 低速 / 2 中速 / 3 全速static u8 beep_cnt蜂鸣计数控制超温间歇鸣叫u16 tick_cnt系统 10ms 时基计数器用于定时任务调度。3.1.2 核心函数 1Get_Filter_Temp 滑动均值滤波c运行float Get_Filter_Temp(float new_temp)功能消除 DS18B20 单次采样噪声输出平滑温度。 执行逻辑将最新温度存入循环数组temp_buf数组下标循环溢出归零累加数组全部 5 个采样值取算术平均值返回 优势低通滤波温度小幅抖动不会触发风扇频繁换挡。3.1.3 核心函数 2Fan_PWM_Ctrl 温控 PWM 与报警逻辑c运行void Fan_PWM_Ctrl(float temp)项目核心控制函数输入滤波平滑温度自动设置 PWM 占空比 控制蜂鸣器。 逻辑拆解每次进入先关闭蜂鸣器仅超高温时触发鸣叫四段温度区间分层判断结合last_temp实现 2℃回差温度≥40℃全速模式每 20 次采样触发一次蜂鸣间歇报警更新last_temp保存当前温度用于下一次回差判断。3.1.4 main () 主函数执行流程第一步系统与外设初始化SysTick 滴答定时器初始化72MHz 系统时钟适配延时中断优先级分组 2 配置LED、蜂鸣、串口、LCD1602、TIM3 PWM 全部初始化PWM 初始占空比置 0风扇上电默认停止。第二步DS18B20 传感器硬件检测循环调用DS18B20_Init()返回 1 代表传感器未接入 / 损坏异常时 LCD 显示报错字符串、串口打印故障信息、风扇保持停机传感器正常跳出循环清屏并打印正常提示。第三步主循环 while (1) 分时调度10ms 基础节拍节拍计数tick_cnt自增基础延时 10ms200ms 任务tick_cnt%20LED 电平翻转心跳指示灯500ms 定时任务tick_cnt%50温度采集周期读取原始 DS18B20 温度滑动滤波计算平滑温度调用温控函数自动调节 PWM 风扇档位sprintf 格式化字符串串口打印温度 PWM 百分比LCD1602 刷新两行显示第一行当前温度第二行风扇档位与占空比。3.2 pwm.c TIM3_CH1 PWM 驱动文件3.2.1 TIM3_CH1_PWM_Init PWM 初始化函数c运行void TIM3_CH1_PWM_Init(u16 per,u16 psc)输入参数per自动重装载值 ARR本项目固定 999psc预分频系数 PSC本项目固定 71。 初始化步骤开启 GPIOA、TIM3、复用功能 AFIO 时钟PA6 配置为复用推挽输出TIM3_CH1 硬件通道定时器时基单元配置向上计数模式通道 1 配置为 PWM1 模式计数值小于 CCR 时输出高电平占空比 CCR/ARR开启 CCR 预装载、ARR 自动重装载使能 TIM3 定时器。3.2.2 SetPWM_Duty 设置占空比接口c运行void SetPWM_Duty(u16 duty)调用标准库TIM_SetCompare1(TIM3, duty)修改通道 1 比较值实时调整风扇转速上层主程序无需操作寄存器接口简洁。3.3 ds18b20.c DS18B20 单总线驱动文件完整 DS18B20 标准单总线时序驱动支持复位、存在检测、读写位 / 字节、温度转换、温度读取。IO 模式切换函数DS18B20_IO_IN上拉输入、DS18B20_IO_OUT推挽输出单总线分时切换输入输出底层时序函数复位脉冲 750us、存在脉冲检测、读位时序、写 0 / 写 1 时序严格匹配 DS18B20 手册命令封装跳过 ROM 指令 0xCC、温度转换 0x44、读取寄存器 0xBEDS18B20_Init传感器初始化 硬件存在检测返回 1 故障0 正常DS18B20_GetTemperture读取原始 16 位温度寄存器正负温度换算返回浮点摄氏温度精度 0.0625℃。3.4 lcd1602.c LCD1602 并行屏驱动支持 8 位并行接口可通过宏切换 4 位模式提供基础屏幕操作接口lcd1602_gpio_init初始化 PB0~PB2 控制脚、PB8~PB15 数据脚lcd1602_write_cmd发送 LCD 指令清屏、显示模式、地址设置lcd1602_write_data发送字符数据到屏幕lcd1602_init上电初始化 LCD1602设置 2 行 16 列、显示开无光标lcd1602_clear发送 0x01 指令清屏lcd1602_show_string(x,y,str)指定坐标 x (0~15)、y (0/1) 显示字符串自动换行处理。3.5 usart.c 串口驱动USART1 9600 波特率初始化PA9 发送、PA10 浮空接收开启串口接收中断收到数据自动回显fputc函数重定向支持标准库printf()打印调试信息中断服务函数USART1_IRQHandler接收中断读取字节并回发。3.6 SysTick.c 系统滴答延时驱动基于内核 SysTick 定时器实现微秒、毫秒阻塞延时适配 72MHz 系统时钟SysTick_Init(u8 SYSCLK)配置 SysTick 时钟为 AHB/8计算 us/ms 延时倍乘数delay_us(u32 nus)微秒级精准延时delay_ms(u16 nms)毫秒延时24 位计数器限制最大延时 1864ms72M。3.7 led.c/beep.c 简单 IO 驱动LED_InitPB1 推挽输出初始化上电默认熄灭主程序直接操作PBout(1)翻转BEEP_InitPB5 推挽输出BEEP_ON/BEEP_OFF 宏函数控制蜂鸣器高低电平。四、关键技术设计点详解4.1 PWM 调速原理APB1 定时器时钟 72MHzPSC71 分频后时钟 1MHzARR999计数周期 1000 个时钟输出 10kHz PWM 占空比 CCR 值 / 1000CCR0 → 0% 停机CCR300→30% 低速CCR600→60% 中速CCR999→100% 全速。4.2 滑动均值滤波抗干扰DS18B20 单总线易受电源干扰单次温度采样波动 ±0.5℃采用 5 次采样取平均平滑曲线避免温度小幅跳动触发风扇频繁换挡。4.3 温度回差防抖设计无回差缺陷温度在 31℃上下小幅波动时风扇会低速 / 中速反复切换 解决逻辑降温时必须低于档位阈值 - 2℃才降档。 例温度升到 31℃切中速只有降温到 29℃才切回低速消除震荡。4.4 分时多任务调度全程无操作系统基于 10ms 基础节拍使用软件定时器分时执行任务200msLED 心跳低优先级指示500ms温度采集、滤波、温控调节、屏幕刷新、串口打印 优势代码简洁、资源占用极低适合单片机裸机项目。4.5 DS18B20 故障保护上电循环检测传感器断线时强制风扇停机LCD 与串口双重告警防止无测温下风扇持续全速运行。五、调试与使用说明5.1 硬件接线要求DS18B20DQ 引脚接上拉 4.7K 电阻后接入定义 IO风扇驱动PA6 PWM 输出接三极管 / MOS 管驱动直流风扇LCD1602VSS 接地、VDD5V、VO 对比度电位器RS/RW/E/D0~D7 对应 PB 口蜂鸣器PB5 串联三极管驱动有源蜂鸣器。5.2 串口调试信息格式正常采样输出示例plaintextTemp:29.63C PWM:30%Temp滤波后平滑温度PWM当前占空比百分比。5.3 LCD1602 显示格式第一行T:XX.XX C实时平滑温度 第二行Fan:Stop / Slow 30% / Mid 60% / Full 100%当前风扇档位。5.4 故障现象说明LCD 持续显示DS18B20 ERROR传感器接线断开、DQ 无上拉电阻、传感器损坏风扇无转速PWM 占空比 0或 PA6 接线、驱动三极管损坏风扇持续全速温度高于 40℃正常报警状态LED 不闪烁SysTick 延时异常、主循环卡死。六、代码优缺点与拓展方案6.1 优点模块化分层驱动所有外设可单独移植到其他项目温控逻辑带滤波 回差稳定性高无频繁跳档裸机分时调度无 RTOSFlash/RAM 占用小多重状态提示LED、LCD、串口三重可视化调试硬件故障自动检测保护鲁棒性强。6.2 可优化拓展方向增加按键修改温度阈值实现参数可调存储阈值到 EEPROM掉电保存设置加入 OLED 屏替代 LCD1602增加曲线显示移植中断非阻塞温度采集消除 500ms 延时阻塞增加多档 PWM 线性调速替换固定四档位增加过热停机保护超过 50℃切断风扇电源。七、开发环境说明主控芯片STM32F103C8T672MHz标准库版本STM32F10x_StdPeriph_Lib V3.5编译软件Keil MDK5编程语言标准 C89依赖外设DS18B20、LCD1602、直流 PWM 风扇、有源蜂鸣器、串口模块。七、核心代码//main.c #include system.h #include SysTick.h #include led.h #include beep.h #include usart.h #include ds18b20.h #include lcd1602.h #include pwm.h #include stdio.h #include string.h #include math.h // 温度分段阈值 #define TEMP_STOP 27.0f #define TEMP_LOW 31.0f #define TEMP_MID 40.0f // PWM配置10KHz 72M APB272M, PSC71 ARR999 → 72M/(72*1000)10KHz #define PWM_PSC 71 #define PWM_ARR 999 // 各档位占空比 #define DUTY_STOP 0 #define DUTY_SLOW 300 //30% #define DUTY_MID 600 //60% #define DUTY_FULL 999 //100% // 回差2℃防抖动 #define TEMP_HYSTER 2.0f // 滑动滤波缓存 float temp_buf[5]; u8 buf_idx 0; float temp_filter 0.0f; float last_temp 0.0f; // 计算滤波平均温度 float Get_Filter_Temp(float new_temp) { u8 i0; float sum 0; temp_buf[buf_idx] new_temp; if(buf_idx 5) buf_idx 0; for(i0;i5;i) sum temp_buf[i]; return sum / 5.0f; } // 根据温度设置PWM与蜂鸣 void Fan_PWM_Ctrl(float temp) { static u8 fan_state 0; //0停 1低速 2中速 3全速 static u8 beep_cnt 0; BEEP_OFF(); // 回差判断逻辑 if(temp TEMP_STOP) { SetPWM_Duty(DUTY_STOP); fan_state 0; } else if(temp TEMP_MID) { SetPWM_Duty(DUTY_FULL); fan_state 3; //超高温间歇蜂鸣 beep_cnt; if(beep_cnt % 20 0) BEEP_ON(); } else if(temp TEMP_LOW) { if(last_temp TEMP_MID temp TEMP_MID - TEMP_HYSTER) { SetPWM_Duty(DUTY_MID); fan_state 2; } else if(last_temp TEMP_LOW) { SetPWM_Duty(DUTY_MID); fan_state 2; } } else //22 ~ 27℃ 低速区间 { if(last_temp TEMP_LOW temp TEMP_LOW - TEMP_HYSTER) { SetPWM_Duty(DUTY_SLOW); fan_state 1; } else if(last_temp TEMP_STOP) { SetPWM_Duty(DUTY_SLOW); fan_state 1; } } last_temp temp; } int main(void) { u16 tick_cnt 0; float temp_val 0.0f; char lcd_buf[16] {0}; u8 ds_err 0; u16 duty 0; //外设初始化 SysTick_Init(72); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_Init(); BEEP_Init(); USART1_Init(9600); lcd1602_init(); TIM3_CH1_PWM_Init(PWM_ARR, PWM_PSC); SetPWM_Duty(0); //DS18B20上电检测 while(DS18B20_Init() ! 0) { ds_err 1; lcd1602_clear(); lcd1602_show_string(0,0,(u8*)DS18B20 ERROR); lcd1602_show_string(0,1,(u8*)Check Sensor!); printf(DS18B20未检测到风扇关闭!\r\n); SetPWM_Duty(0); delay_ms(500); } ds_err 0; printf(DS18B20检测正常温控启动\r\n); lcd1602_clear(); while(1) { tick_cnt; delay_ms(10); //LED心跳 200ms翻转 if(tick_cnt % 20 0) { led1 !led1; PBout(1) led1; } //500ms采集一次温度 if(tick_cnt % 50 0) { temp_val DS18B20_GetTemperture(); //修复函数拼写错误 temp_filter Get_Filter_Temp(temp_val); Fan_PWM_Ctrl(temp_filter); //串口打印读取TIM3通道1占空比 memset(lcd_buf,0,sizeof(lcd_buf)); sprintf(lcd_buf,Temp:%.2fC PWM:%d%%,temp_filter,TIM_GetCapture1(TIM3)/10); printf(%s\r\n,lcd_buf); //LCD刷新 lcd1602_clear(); sprintf(lcd_buf,T:%.2f C,temp_filter); lcd1602_show_string(0,0,(u8*)lcd_buf); duty TIM_GetCapture1(TIM3); //统一读取TIM3 if(duty DUTY_STOP) strcpy(lcd_buf,Fan:Stop); else if(duty DUTY_SLOW) strcpy(lcd_buf,Fan:Slow 30%); else if(duty DUTY_MID) strcpy(lcd_buf,Fan:Mid 60%); else strcpy(lcd_buf,Fan:Full 100%); lcd1602_show_string(0,1,(u8*)lcd_buf); } } }#include pwm.h /******************************************************************************* * 函 数 名 : TIM3_CH1_PWM_Init * 函数功能 : TIM3通道1 PWM初始化函数 PA6输出 * 输 入 : per:重装载值 psc:分频系数 * 输 出 : 无 *******************************************************************************/ void TIM3_CH1_PWM_Init(u16 per,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* 开启时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); /* 配置GPIO的模式和IO口 PA6 TIM3_CH1*/ GPIO_InitStructure.GPIO_PinGPIO_Pin_6; GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz; GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF_PP;//复用推挽输出 GPIO_Init(GPIOA,GPIO_InitStructure); TIM_TimeBaseInitStructure.TIM_Periodper; //自动装载值 TIM_TimeBaseInitStructure.TIM_Prescalerpsc; //分频系数 TIM_TimeBaseInitStructure.TIM_ClockDivisionTIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterModeTIM_CounterMode_Up; //设置向上计数模式 TIM_TimeBaseInit(TIM3,TIM_TimeBaseInitStructure); TIM_OCInitStructure.TIM_OCModeTIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarityTIM_OCPolarity_High; //修复极性CCR越大高电平越长风扇越快 TIM_OCInitStructure.TIM_OutputStateTIM_OutputState_Enable; TIM_OC1Init(TIM3,TIM_OCInitStructure); //输出比较通道1初始化 TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器 TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器 TIM_Cmd(TIM3,ENABLE); //使能定时器 } // 设置TIM3_CH1占空比 void SetPWM_Duty(u16 duty) { TIM_SetCompare1(TIM3, duty); }//ds18b20.c #include ds18b20.h #include SysTick.h /******************************************************************************* * 函 数 名 : DS18B20_IO_IN * 函数功能 : DS18B20_IO输入配置 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void DS18B20_IO_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_PinDS18B20_PIN; GPIO_InitStructure.GPIO_ModeGPIO_Mode_IPU; GPIO_Init(DS18B20_PORT,GPIO_InitStructure); } /******************************************************************************* * 函 数 名 : DS18B20_IO_OUT * 函数功能 : DS18B20_IO输出配置 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void DS18B20_IO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_PinDS18B20_PIN; GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz; GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_PP; GPIO_Init(DS18B20_PORT,GPIO_InitStructure); } /******************************************************************************* * 函 数 名 : DS18B20_Reset * 函数功能 : 复位DS18B20 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void DS18B20_Reset(void) { DS18B20_IO_OUT(); //SET PG11 OUTPUT DS18B20_DQ_OUT0; //拉低DQ delay_us(750); //拉低750us DS18B20_DQ_OUT1; //DQ1 delay_us(15); //15US } /******************************************************************************* * 函 数 名 : DS18B20_Check * 函数功能 : 检测DS18B20是否存在 * 输 入 : 无 * 输 出 : 1:未检测到DS18B20的存在0:存在 *******************************************************************************/ u8 DS18B20_Check(void) { u8 retry0; DS18B20_IO_IN();//SET PG11 INPUT while (DS18B20_DQ_INretry200) { retry; delay_us(1); }; if(retry200)return 1; else retry0; while (!DS18B20_DQ_INretry240) { retry; delay_us(1); }; if(retry240)return 1; return 0; } /******************************************************************************* * 函 数 名 : DS18B20_Read_Bit * 函数功能 : 从DS18B20读取一个位 * 输 入 : 无 * 输 出 : 1/0 *******************************************************************************/ u8 DS18B20_Read_Bit(void) // read one bit { u8 data; DS18B20_IO_OUT();//SET PG11 OUTPUT DS18B20_DQ_OUT0; delay_us(2); DS18B20_DQ_OUT1; DS18B20_IO_IN();//SET PG11 INPUT delay_us(12); if(DS18B20_DQ_IN)data1; else data0; delay_us(50); return data; } /******************************************************************************* * 函 数 名 : DS18B20_Read_Byte * 函数功能 : 从DS18B20读取一个字节 * 输 入 : 无 * 输 出 : 一个字节数据 *******************************************************************************/ u8 DS18B20_Read_Byte(void) // read one byte { u8 i,j,dat; dat0; for (i1;i8;i) { jDS18B20_Read_Bit(); dat(j7)|(dat1); } return dat; } /******************************************************************************* * 函 数 名 : DS18B20_Write_Byte * 函数功能 : 写一个字节到DS18B20 * 输 入 : dat要写入的字节 * 输 出 : 无 *******************************************************************************/ void DS18B20_Write_Byte(u8 dat) { u8 j; u8 testb; DS18B20_IO_OUT();//SET PG11 OUTPUT; for (j1;j8;j) { testbdat0x01; datdat1; if (testb) { DS18B20_DQ_OUT0;// Write 1 delay_us(2); DS18B20_DQ_OUT1; delay_us(60); } else { DS18B20_DQ_OUT0;// Write 0 delay_us(60); DS18B20_DQ_OUT1; delay_us(2); } } } /******************************************************************************* * 函 数 名 : DS18B20_Start * 函数功能 : 开始温度转换 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void DS18B20_Start(void)// ds1820 start convert { DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// convert } /******************************************************************************* * 函 数 名 : DS18B20_Init * 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在 * 输 入 : 无 * 输 出 : 1:不存在0:存在 *******************************************************************************/ u8 DS18B20_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(DS18B20_PORT_RCC,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); GPIO_InitStructure.GPIO_PinDS18B20_PIN; GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz; GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_PP; GPIO_Init(DS18B20_PORT,GPIO_InitStructure); DS18B20_Reset(); return DS18B20_Check(); } /******************************************************************************* * 函 数 名 : DS18B20_GetTemperture * 函数功能 : 从ds18b20得到温度值 * 输 入 : 无 * 输 出 : 温度数据 *******************************************************************************/ float DS18B20_GetTemperture(void) { u16 temp; u8 a,b; float value; DS18B20_Start(); // ds1820 start convert DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0xbe);// convert aDS18B20_Read_Byte(); // LSB bDS18B20_Read_Byte(); // MSB tempb; temp(temp8)a; if((temp0xf800)0xf800) { temp(~temp)1; valuetemp*(-0.0625); } else { valuetemp*0.0625; } return value; }