泉州市网站建设_网站建设公司_JSON_seo优化
2026/1/16 16:12:17 网站建设 项目流程

蓝桥杯单片机备赛指南第十五讲· 省赛真题01:第十二届省赛完全解析

1. 题目功能需求拆解

拿到题目(PDF),首先提取核心要素:

1.1 显示界面(3 个)

  1. 温度显示界面:标识符C,显示实时温度(保留2 位小数)。

    • 例:C 24.25
  2. 参数设置界面:标识符P,显示温度参数(整数)。

    • 例:P 25
  3. DAC 输出界面:标识符A(或U/F,依题意),显示当前DAC 输出电压(保留2 位小数)。

    • 例:A 3.50

1.2 逻辑控制

  • DAC 输出模式

    • 模式1VoutV_{out}Vout与温度相关。若T<TparamT < T_{param}T<Tparam,输出0V;若T≥TparamT \ge T_{param}TTparam,输出5V。

    • 模式2VoutV_{out}Vout固定输出(例如1V-5V 循环,或特定值,具体依代码逻辑)。

  • LED 指示

    • L1:模式1 时亮。

    • L2:温度显示界面时亮。

    • L3:参数设置界面时亮。

    • L4:DAC界面时亮。

1.3 按键定义

  • S4:界面切换(温度-> 参数-> DAC -> 温度)。

  • S5:模式切换(Mode 1 <-> Mode 2)。

  • S8:参数-1。

  • S9:参数+1。


2. 硬件与驱动层配置

本题用到两个核心外设,直接复用之前的驱动模块:

  1. DS18B20 (OneWire):复用Note 10的驱动。

    • 核心函数:Read_T()

    • 注意:读取需放在主循环,不能放在中断。

  2. PCF8591 (IIC):复用Note 11的驱动。

    • 核心函数:Da_Write(val)

    • 计算Val=Voltage×51.0Val = Voltage \times 51.0Val=Voltage×51.0


3. 软件架构实现(Grand Template 实战)

完全套用Note 12总结的“分时轮询架构”。

3.1 全局变量定义(RAM 镜像)

C

// === 核心数据 ===floatTemperature=0;// 实时温度unsignedcharT_Param=25;// 温度参数 (默认25)floatDAC_Volt=0;// DAC 输出电压// === 状态标志 ===unsignedcharSeg_Mode=0;// 0:温度, 1:参数, 2:DACunsignedcharWork_Mode=0;// 0:模式1, 1:模式2

3.2 主函数设计(Main Loop)

主函数只负责调度,不处理具体细节。

C

voidmain(){System_Init();// 关闭蜂鸣器、继电器等while(1){// 1. 数据获取 (Input)Temperature=Read_T();// 读取温度 (耗时操作放在主循环)// 2. 业务逻辑 (Logic)Key_Proc();// 按键处理Seg_Proc();// 数码管显示数据生成DAC_Proc();// DAC 输出逻辑计算LED_Proc();// LED 状态计算}}

3.3 按键处理(Key_Proc)

仅处理状态跳转和参数修改。

C

voidKey_Proc(){if(Key_Slow_Down)return;Key_Slow_Down=1;// ... (按键读取代码略) ...switch(Key_Down){case4:// S4: 切换界面if(++Seg_Mode>2)Seg_Mode=0;break;case5:// S5: 切换 DAC 模式Work_Mode^=1;break;case8:// S8: 参数 -if(Seg_Mode==1){// 仅在参数界面有效T_Param--;}break;case9:// S9: 参数 +if(Seg_Mode==1){T_Param++;}break;}}

3.4 核心业务逻辑(DAC_Proc)

将题目要求的DAC 逻辑独立封装,清晰明了。

C

voidDAC_Proc(){// 根据模式计算目标电压if(Work_Mode==0)// 模式 1: 温控输出{if(Temperature<T_Param)DAC_Volt=0.0;elseDAC_Volt=5.0;}else// 模式 2: 固定输出 (假设题意为固定 2V 或其他逻辑){DAC_Volt=2.0;}// 执行硬件输出Da_Write((unsignedchar)(DAC_Volt*51.0));}

3.5 显示处理(Seg_Proc)

只负责将数据“翻译”到Seg_Buf,不负责扫描。

C

voidSeg_Proc(){if(Seg_Slow_Down)return;Seg_Slow_Down=1;switch(Seg_Mode){case0:// 温度界面: C 24.25Seg_Buf[0]=12;// 'C'Seg_Buf[1]=10;// 熄灭// ... (中间熄灭) ...Seg_Buf[4]=(unsignedlong)(Temperature)/10;Seg_Buf[5]=(unsignedlong)(Temperature)%10;Seg_Buf[6]=(unsignedlong)(Temperature*10)%10;Seg_Buf[7]=(unsignedlong)(Temperature*100)%10;Seg_Point[5]=1;// 小数点break;case1:// 参数界面: P 25Seg_Buf[0]=13;// 'P'// ...Seg_Buf[6]=T_Param/10;Seg_Buf[7]=T_Param%10;Seg_Point[5]=0;// 清除小数点break;case2:// DAC 界面: A 3.50Seg_Buf[0]=10;// 'A' (假设字模 10)// ...Seg_Buf[5]=(unsignedchar)DAC_Volt;Seg_Buf[6]=(unsignedchar)(DAC_Volt*10)%10;Seg_Buf[7]=(unsignedchar)(DAC_Volt*100)%10;Seg_Point[5]=1;break;}}

4. 备赛心得与避坑指南

  1. DS18B20 的坑

    • 读取温度函数Read_T()内部有几十微秒甚至毫秒的延时,千万不要放在定时器中断里,否则会导致数码管闪烁、按键失灵。

    • 上电初始化时,DS18B20 默认输出85℃,建议在mainwhile(1)之前先读取一次温度丢弃,防止开机跳变。

  2. PCF8591 的坑

    • DAC 输出需要时间,虽然很快,但在高频循环中,建议加上简单的限流(例如每100ms 更新一次DAC),或者直接跟随主循环跑也没问题(因为有Read_T 的延时撑着)。
  3. 按键的坑

    • 题目中S8/S9 通常只在“参数设置界面”有效。务必在case 8case 9中加上if(Seg_Mode == 1)的判断,防止在看温度时误触修改了参数。
  4. 工程化思维

    • 看到这道题,你应该立刻反应出:这是DS18B20+ ** PCF8591**的组合。

    • 代码只需从之前的模块中复制粘贴,然后填入main.c的骨架中即可。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询