当前位置:   article > 正文

蓝桥杯第十三届单片机省赛真题(IAP15F2K61S2)_蓝桥杯单片机13届省赛原题

蓝桥杯单片机13届省赛原题

一、题目

二、题目分析

1、难点(笔者个人认为)

(1)s17按键短按和长按的设置不同,界面不同

s17短按在参数界面需要把温度参数-1;

s17长按在时间界面需要显示分,秒界面;

所以笔者这里把两个数码管显示分两个函数

  1. void Nixie_Show()//数码管显示函数
  2. {
  3. Nixie_pos_num(1,16);
  4. Nixie_pos_num(3,17);
  5. if(flag_s12 == 0)//温度显示界面
  6. {
  7. Temp = Read_DS18B20_Temp();
  8. Nixie_pos_num(2,1);
  9. Nixie_pos_num(4,17);
  10. Nixie_pos_num(5,17);
  11. Nixie_pos_num(6,Temp/1000);
  12. Nixie_Dian_pos_num(7,Temp/100%10);
  13. Nixie_pos_num(8,Temp/10%10);
  14. }
  15. if(flag_s12 == 1)//时间显示界面
  16. {
  17. Nixie_pos_num(2,2);
  18. Nixie_pos_num(4,Time[2]/16);
  19. Nixie_pos_num(5,Time[2]%16);
  20. Nixie_pos_num(6,18);
  21. Nixie_pos_num(7,Time[1]/16);
  22. Nixie_pos_num(8,Time[1]%16);
  23. }
  24. if(flag_s12 == 2)//参数显示界面
  25. {
  26. Nixie_pos_num(2,3);
  27. Nixie_pos_num(4,17);
  28. Nixie_pos_num(5,17);
  29. Nixie_pos_num(6,17);
  30. Nixie_pos_num(7,Temp_C/10);
  31. Nixie_pos_num(8,Temp_C%10);
  32. }
  33. }
  34. void Nixie_Time_S17()//在时间显示界面下,长按s17显示界面
  35. {
  36. if(flag_s12 == 1)
  37. {
  38. Read_Ds1302_Time(Time);
  39. Nixie_pos_num(1,16);
  40. Nixie_pos_num(2,2);
  41. Nixie_pos_num(3,17);
  42. Nixie_pos_num(4,Time[1]/16);
  43. Nixie_pos_num(5,Time[1]%16);
  44. Nixie_pos_num(6,18);
  45. Nixie_pos_num(7,Time[0]/16);
  46. Nixie_pos_num(8,Time[0]%16);
  47. }
  48. }

分别显示不同的界面,避免界面冲突。当然这里也可以通过switch语句进行界面选择,读者可以自己调整

(2)出现两个不同时间产生不同状态,L1点亮,5秒熄灭,L3要0.1秒交替闪烁

这里直接使用Delay是有问题的,LED灯和数码管显示会频闪。笔者这里用到是定时器

  1. void Timer0Init(void) //50毫秒@12MHz
  2. {
  3. TMOD = 0x01;
  4. TL0 = (65535 - 50000) % 256; //设置定时初值
  5. TH0 = (65535 - 50000) / 256; //设置定时初值
  6. TR0 = 1; //定时器0开始计时
  7. EA = 1;
  8. ET0 = 1;
  9. }
  10. void Timer0Init_Time() interrupt 1
  11. {
  12. TL0 = (65535 - 50000) % 256; //设置定时初值
  13. TH0 = (65535 - 50000) / 256; //设置定时初值
  14. count++;
  15. if(count % 5 == 0)//计时100ms
  16. {
  17. flag_L3 = ~flag_L3;
  18. }
  19. if(count == 100)//计时5s
  20. {
  21. flag_timer_relay = 0;
  22. flag_L1 = 0;
  23. count = 0;
  24. }
  25. }

让定时器到点发起中断,产生效果

(3)、温度浮点数处理

在上一篇笔记笔者已经提到,有兴趣的读者可以到这里的四、2、第十五届蓝桥杯单片机模拟II(IAP15F2K61S2)-CSDN博客

这里就不过多阐述

三、代码(仅供参考)

1、头文件

  1. #include <STC15F2K60S2.H>
  2. #include <ds1302.H>
  3. #include <onewire.H>

2、变量声明

  1. sbit K1 = P3^5;
  2. sbit K2 = P3^4;
  3. sbit K3 = P3^3;
  4. sbit K4 = P3^2;
  5. sbit L1 = P0^0;
  6. sbit L2 = P0^1;
  7. sbit L3 = P0^2;
  8. //==================数组定义===================
  9. code unsigned char Seg_Table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xc1,0xff,0xbf};//数码管不带小数点 16:0xc1:U 18:0xbf:-
  10. code unsigned char Seg_Dian_Table[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};//数码管带小数点
  11. unsigned char Time[3]={0x55,0x59,0x07};//秒,分,时
  12. //==================变量定义===================
  13. unsigned char flag_s12;//按键s12按下三种状态
  14. unsigned char flag_s13;//按键s13按下两种状态
  15. unsigned char flag_relay = 0;//继电器两种状态
  16. unsigned char Temp_C = 23;//温度参数
  17. unsigned char count;//定时器计时参数
  18. unsigned char flag_L3;//L3灯状态
  19. unsigned char flag_L1;//L1灯状态
  20. unsigned char flag_timer_relay;//时间控制模式下继电器状态
  21. unsigned int Temp;//温度变量

3、函数声明

  1. //==================函数声明===================
  2. void Nixie_Show();//数码管显示函数
  3. void Scan_Key();//按键控制函数
  4. void Nixie_Time_S17();//在时间显示界面下,长按s17显示
  5. void Relay();//继电器控制函数
  6. void LED();//LED灯控制函数
  7. //=============================================

四、函数模块

1、其他函数

  1. void delay(unsigned char i)
  2. {
  3. while(i--);
  4. }
  5. void hc(unsigned char n)//通道选择
  6. {
  7. switch(n)
  8. {
  9. case 0:
  10. P2 = P2 & 0x1f;
  11. break;
  12. case 4:
  13. P2 = (P2 & 0x1f) | 0x80;//LED
  14. break;
  15. case 5:
  16. P2 = (P2 & 0x1f) | 0xa0;//蜂鸣器,继电器
  17. break;
  18. case 6:
  19. P2 = (P2 & 0x1f) | 0xc0;//数码管位选
  20. break;
  21. case 7:
  22. P2 = (P2 & 0x1f) | 0xe0;//数码管段选
  23. break;
  24. }
  25. }
  26. void System_Init()//系统初始化
  27. {
  28. hc(4);
  29. P0 = 0xFF;
  30. hc(5);
  31. P0 = 0x00;
  32. hc(0);
  33. }

2、数码管

  1. void Nixie_pos_num(unsigned char pos,num)//数码管(不带小数点)位置,显示数字
  2. {
  3. hc(6);
  4. P0 = 0x01 << (pos-1);
  5. hc(7);
  6. P0 = Seg_Table[num];
  7. delay(500);
  8. P0 = 0xFF;
  9. hc(0);
  10. }
  11. void Nixie_Dian_pos_num(unsigned char pos,num)//数码管(带小数点)位置,显示数字
  12. {
  13. hc(6);
  14. P0 = 0x01 << (pos-1);
  15. hc(7);
  16. P0 = Seg_Dian_Table[num];
  17. delay(500);
  18. P0 = 0xFF;
  19. hc(0);
  20. }
  21. void Nixie_Show()//数码管显示函数
  22. {
  23. Nixie_pos_num(1,16);
  24. Nixie_pos_num(3,17);
  25. if(flag_s12 == 0)//温度显示界面
  26. {
  27. Temp = Read_DS18B20_Temp();
  28. Nixie_pos_num(2,1);
  29. Nixie_pos_num(4,17);
  30. Nixie_pos_num(5,17);
  31. Nixie_pos_num(6,Temp/1000);
  32. Nixie_Dian_pos_num(7,Temp/100%10);
  33. Nixie_pos_num(8,Temp/10%10);
  34. }
  35. if(flag_s12 == 1)//时间显示界面
  36. {
  37. Nixie_pos_num(2,2);
  38. Nixie_pos_num(4,Time[2]/16);
  39. Nixie_pos_num(5,Time[2]%16);
  40. Nixie_pos_num(6,18);
  41. Nixie_pos_num(7,Time[1]/16);
  42. Nixie_pos_num(8,Time[1]%16);
  43. }
  44. if(flag_s12 == 2)//参数显示界面
  45. {
  46. Nixie_pos_num(2,3);
  47. Nixie_pos_num(4,17);
  48. Nixie_pos_num(5,17);
  49. Nixie_pos_num(6,17);
  50. Nixie_pos_num(7,Temp_C/10);
  51. Nixie_pos_num(8,Temp_C%10);
  52. }
  53. }
  54. void Nixie_Time_S17()//在时间显示界面下,长按s17显示界面
  55. {
  56. if(flag_s12 == 1)
  57. {
  58. Read_Ds1302_Time(Time);
  59. Nixie_pos_num(1,16);
  60. Nixie_pos_num(2,2);
  61. Nixie_pos_num(3,17);
  62. Nixie_pos_num(4,Time[1]/16);
  63. Nixie_pos_num(5,Time[1]%16);
  64. Nixie_pos_num(6,18);
  65. Nixie_pos_num(7,Time[0]/16);
  66. Nixie_pos_num(8,Time[0]%16);
  67. }
  68. }

3、按键

  1. void Scan_Key()//按键控制函数
  2. {
  3. K2 = K3 = K4 = 1;K1 = 0;
  4. if(K3 == 0 || K4 == 0)
  5. {
  6. delay(100);
  7. if(K3 == 0)//s12按键按下
  8. {
  9. flag_s12 = (flag_s12 + 1) % 3;
  10. while(K3 == 0)
  11. {
  12. Nixie_Show();
  13. }
  14. }
  15. if(K4 == 0)//s13按键按下
  16. {
  17. flag_s13 = (flag_s13 + 1) % 2;
  18. while(K4 == 0)
  19. {
  20. Nixie_Show();
  21. LED();
  22. }
  23. }
  24. }
  25. if(flag_s12 == 2)//在参数设置界面关于s16,s17控制
  26. {
  27. K1 = K3 = K4 = 1;K2 = 0;
  28. if(K3 == 0 || K4 == 0)
  29. {
  30. delay(100);
  31. if(K3 == 0)//s16按键按下
  32. {
  33. Temp_C++;
  34. if(Temp_C >= 90)
  35. {
  36. Temp_C = 90;
  37. }
  38. while(K3 == 0)
  39. {
  40. Nixie_Show();
  41. }
  42. }
  43. if(K4 == 0)//s17按键按下
  44. {
  45. Temp_C--;
  46. if(Temp_C <= 10)
  47. {
  48. Temp_C = 10;
  49. }
  50. while(K4 == 0)
  51. {
  52. Nixie_Show();
  53. }
  54. }
  55. }
  56. }
  57. if(flag_s12 == 1)//在时间显示界面关于s17控制
  58. {
  59. K1 = K3 = K4 = 1;K2 = 0;
  60. if(K4 == 0)
  61. {
  62. delay(100);
  63. if(K4 == 0)
  64. {
  65. while(K4 == 0)
  66. {
  67. Nixie_Time_S17();
  68. }
  69. }
  70. }
  71. }
  72. }

4、LED

  1. void LED()//LED灯控制函数
  2. {
  3. //L1灯控制
  4. if(Time[0]==0x00&&Time[1]==0x00)
  5. {
  6. if(flag_L1 == 0)
  7. {
  8. hc(4);
  9. L1 = 0;
  10. hc(0);
  11. }
  12. else
  13. {
  14. hc(4);
  15. L1 = 1;
  16. hc(0);
  17. }
  18. }
  19. else
  20. {
  21. hc(4);
  22. L1 = 1;
  23. hc(0);
  24. }
  25. //L2灯控制
  26. if(flag_s13 == 0)
  27. {
  28. hc(4);
  29. L2 = 0;
  30. hc(0);
  31. }
  32. else
  33. {
  34. hc(4);
  35. L2 = 1;
  36. hc(0);
  37. }
  38. //L3灯控制
  39. if(flag_relay == 1)//在继电器吸合状态
  40. {
  41. if(flag_L3 == 0)
  42. {
  43. hc(4);
  44. L3 = 0;
  45. hc(0);
  46. }
  47. else
  48. {
  49. hc(4);
  50. L3 = 1;
  51. hc(0);
  52. }
  53. }
  54. else
  55. {
  56. hc(4);
  57. L3 = 1;
  58. hc(0);
  59. }
  60. }

5、继电器

  1. void Relay()//继电器控制函数
  2. {
  3. if(flag_s13 == 0)//温度控制模式
  4. {
  5. if(Temp>Temp_C*100)
  6. {
  7. hc(5);
  8. P0 = 0x10;
  9. hc(0);
  10. flag_relay = 1;
  11. }
  12. else
  13. {
  14. hc(5);
  15. P0 = 0x00;
  16. hc(0);
  17. flag_relay = 0;
  18. }
  19. }
  20. if(flag_s13 == 1)//时间控制模式
  21. {
  22. if(Time[0]==0x00&&Time[1]==0x00)
  23. {
  24. hc(5);
  25. P0 = 0x10;
  26. hc(0);
  27. flag_relay = 1;
  28. flag_timer_relay = 1;
  29. }
  30. else
  31. {
  32. hc(5);
  33. P0 = 0x00;
  34. hc(0);
  35. flag_relay = 0;
  36. }
  37. }
  38. }

6、main

  1. void main()
  2. {
  3. System_Init();
  4. Timer0Init();
  5. Temp = Read_DS18B20_Temp();
  6. Write_Ds1302_Time(Time);
  7. while(1)
  8. {
  9. Read_Ds1302_Time(Time);
  10. Temp = Read_DS18B20_Temp();
  11. Nixie_Show();
  12. Scan_Key();
  13. LED();
  14. Relay();
  15. }
  16. }

7、onewrie

  1. unsigned int Read_DS18B20_Temp()
  2. {
  3. unsigned char LSB,MSB;
  4. unsigned int Temp;
  5. init_ds18b20();
  6. Write_DS18B20(0xcc);
  7. Write_DS18B20(0x44);
  8. init_ds18b20();
  9. Write_DS18B20(0xcc);
  10. Write_DS18B20(0xbe);
  11. LSB = Read_DS18B20();
  12. MSB = Read_DS18B20();
  13. Temp = (MSB << 8) | LSB;
  14. Temp = Temp >> 4;
  15. Temp = Temp * 100;
  16. Temp = Temp + (LSB & 0x0f) * 0.0625 * 100;
  17. return Temp;
  18. }

8、ds1302

  1. code unsigned char Write_Time[3]={0x80,0x82,0x84};
  2. code unsigned char Read_Time[3]={0x81,0x83,0x85};
  3. void Write_Ds1302_Time(unsigned char *time)
  4. {
  5. unsigned char i;
  6. Write_Ds1302_Byte(0x8e,0x00);
  7. for(i = 0;i < 3;i++)
  8. {
  9. Write_Ds1302_Byte(Write_Time[i],time[i]);
  10. }
  11. Write_Ds1302_Byte(0x8e,0x00);
  12. }
  13. void Read_Ds1302_Time(unsigned char *time)
  14. {
  15. unsigned char i;
  16. for(i = 0;i < 3;i++)
  17. time[i]=Read_Ds1302_Byte(Read_Time[i]);
  18. }

五、演示

六、总结

注意:本代码只是提供读者参考,给读者提供一个方法。

蓝桥杯第十三届单片机省赛的题难度不大,但是要处理的细节比较多,需要细心看题,认真思考。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/419792
推荐阅读
相关标签
  

闽ICP备14008679号