当前位置:   article > 正文

蓝桥杯14届国赛试题+详细分模块代码解析+可运行代码+分析_蓝桥杯14单片机 国赛 真题

蓝桥杯14单片机 国赛 真题

一,前言

        15届省赛结束,本人也是侥幸进入国赛,在学习国赛试题的过程中总结了一些小的心得体会,给大家分享出来,希望能对大家有帮助,这次是14届的国赛试题,因为本人之前从来没有写过国赛试题,感觉难度确实增大了许多,功能,用到的模块都变多了,还有许多小细节要注意,让编写代码的时间变得很紧凑,在加入了超声波之后,原先在主进程刷新数码管的方式收到超声波的影响,让显示效果变得很差,并且超声波也占用了一个定时器,让串口和ne555模块的编写变得有困难,本人也是在网上总结了许多大家的经验,附加一些个人的理解,希望能够帮到大家。

二,试题

三,考点及代码分模块解析

1,超声波测距及校准和速度调整

        在国赛试题中,超声波一直是一个热门考点,在实际的编写后我发现常规的超声波写法(定时器0)会占用一个固定的定时器(因为要一直开关并且不可以有定时器中断程序)这可能会影响别的功能的实现,所以我们使用了STC15系列单片机中的一个外设PCA,关于这个外设的具体原理以及寄存器配置可以参考手册或者上网查找资料,这里只讲代码,我们需要知道这个外设大致和51单片机中的定时器差不多就足够了。(PCA外设的使用需要使用头文件<STC15F2K60S2.H>,reg52.h是不支持的,并且在芯片选择上也要选择STC15F2K60)。

  1. void SendWave()//超声波 产生40KHx启动信号
  2. {
  3. uchar i;
  4. EA = 0;
  5. for(i=0;i<8;i++)
  6. {
  7. Tx = 1;
  8. Delay12us();
  9. Tx = 0;
  10. Delay12us();
  11. }
  12. EA = 1;
  13. }
  14. uint csb()//获取间隔时间的函数
  15. {
  16. uint dis,time;
  17. CMOD &= 0x00;//需要配置CMOD为0x0,这里CMOD类似于定时器中的TMOD
  18. CH = 0;//初值为0
  19. CL = 0;
  20. SendWave();//发超声波
  21. CR = 1;//开外设计时
  22. while((Rx==1)&&(CF==0));//如果接收端收到了,或者定时器超时,则跳出循环
  23. CR = 0;//关外设计时
  24. if(CF==0)//if没超时,就是接收端接收到了
  25. {
  26. time = (CH<<8)|CL;//整合计时的高低八位
  27. if(fuFlag==0)//这里我们需要判断校准值是正或者是负,若是这正就加上校准值,反之减去,后面还会说
  28. dis = ((time/10)*sudu/2)/100+3+jiaozhun;//sudu是我们定义的传播速度参数,对他/2后计算距离,公式s=t*v/2
  29. else
  30. dis = ((time/10)*sudu/2)/100+3-jiaozhun1;//减去校准值
  31. }
  32. else//超时了
  33. {
  34. CF=0;//清除标志位
  35. dis = 999;//距离等于999
  36. }
  37. return dis;//返回
  38. }
  39. void Showcsb()//温度和超声波显示
  40. {
  41. seg_loop[0] = temp/100;//温度的部分
  42. seg_loop[1] = temp%100/10;
  43. seg_loop[2] = temp%10;
  44. seg_loop[3] = 18;
  45. if(distance!=999)//如果不为999(不超时情况)
  46. {
  47. if(distance/1000!=0)//判断有无过千,有就显示,反之不显示
  48. {
  49. seg_loop[4] = distance/1000;
  50. }
  51. else
  52. {
  53. seg_loop[4] = 16;
  54. }
  55. if((CountS5==1)||(distance/100!=0))//判断是否过百或者为以m为单位
  56. {
  57. seg_loop[5] = distance%1000/100;
  58. }
  59. else
  60. {
  61. seg_loop[5] = 16;
  62. }
  63. if((CountS5==1)||(distance/10!=0))//判断是否过十或者为以m为单位
  64. seg_loop[6] = distance%100/10;
  65. else
  66. seg_loop[6] = 16;
  67. if(distance>=0)判断是否大于0
  68. seg_loop[7] = distance%10;
  69. else
  70. seg_loop[7] = 16;
  71. }
  72. else seg_loop[7] = seg_loop[6] = seg_loop[5] = seg_loop[4] = 16;//超时不显示
  73. }

 2,数码管显示

        数码管显示是和省赛最大差别的地方,在省赛中我们可以在主进程中刷新片选和段选的方式来实现数码管显示,但是在加入了超声波模块之后,由于超声波代码的编写会频繁阻塞主进程,这导致数码管的显示效果不佳,所以使用定时器0显示数码管(1ms刷新一次)

  1. code unsigned char Seg_Table[] = //段码表,新增了不显示,字母p等
  2. {
  3. 0xc0, //0
  4. 0xf9, //1
  5. 0xa4, //2
  6. 0xb0, //3
  7. 0x99, //4
  8. 0x92, //5
  9. 0x82, //6
  10. 0xf8, //7
  11. 0x80, //8
  12. 0x90, //9
  13. 0x88, //A
  14. 0x83, //b
  15. 0xc6, //C
  16. 0xa1, //d
  17. 0x86, //E
  18. 0x8e,//F
  19. 0xff,
  20. 0x7f,
  21. 0xbf,
  22. 0x8c
  23. };
  24. uchar seg_loop[] = {16,16,16,16,16,16,16,16};//数码管显示的八个位,数字对应上面的断码表,如16是0xff意思是上电默认不显示
  25. void Display()//所有界面的显示
  26. {
  27. switch(CountS4)//用switch的嵌套实现各个界面的切换,不详细解释了
  28. {
  29. case 0:Showcsb();break;
  30. case 1:
  31. switch(CountS5)
  32. {
  33. case 0:ShowjuliCS();break;
  34. case 1:ShowtempCS();break;
  35. }
  36. break;
  37. case 2:
  38. switch(CountS5)
  39. {
  40. case 0:Showjiaozhun();break;
  41. case 1:Showsudu();break;
  42. case 2:ShowDA();break;
  43. }
  44. break;
  45. }
  46. }
  47. void InitTime()//只用到了一个定时器0,一毫秒刷新一次数码管
  48. {
  49. TMOD = 0x10;
  50. TH1 = (65535-1000)/256;
  51. TL1 = (65535-1000)%256;
  52. EA = 1;
  53. ET1 = 1;
  54. TR1 = 1;
  55. }
  56. void ServiceT1() interrupt 3
  57. {
  58. TH1 = (65535-1000)/256;
  59. TL1 = (65535-1000)%256;
  60. // SeleHC573(0,0xff);
  61. SeleHC573(6,0x01<<j);//片选
  62. if(CountS4==0||CountS4==2)//这里是需要显示小数点的位,需要把每个要用到小数点的地方写出来,减去0x80
  63. {
  64. if(((CountS4==0)&&(CountS5==1)&&(j==5)&&(distance != 999))||((CountS4==0)&&(j==1))||((CountS4==2)&&(CountS5==2)&&(j==6)))
  65. SeleHC573(7,Seg_Table[seg_loop[j]]-0x80);
  66. else
  67. {
  68. SeleHC573(7,Seg_Table[seg_loop[j]]);
  69. }
  70. }
  71. else
  72. {
  73. SeleHC573(7,Seg_Table[seg_loop[j]]);
  74. }
  75. // SeleHC573(0,0xff);
  76. CtrlJDQ();//下面与数码管无关
  77. j++;if(j>7)j=0;
  78. counttemp++;
  79. countcsb++;
  80. countkey++;
  81. countled++;
  82. countchangan++;
  83. if(countjilu<=6000) countjilu++;
  84. CtrlLED();
  85. }

3,按键正负数判断和检测两个键同时按下 

         按键中只有两个难点,一个是正负数,还有一个是检测到S8和S9同时按下时程序复位,正负数是通过一个标志位实现的,当正变量减到0,标志位置一,然后负变量继续加,负数加到0也是同理,标志位置零,正变量置零,检测两个键是否同时按下就在每个按键的while循环内加一个判断另一个键是否按下,按下就计时,到两秒就复位,复位使用的是手册中的方法,想了解原理的可以查询手册,直接搜索软件复位就可以了,有例程参考,在这里不多赘述。

 

  1. sfr ISP_CONTR = 0xc7;
  2. sbit R1 = P3^0;
  3. sbit R2 = P3^1;
  4. sbit R3 = P3^2;
  5. sbit R4 = P3^3;
  6. sbit C1 = P3^4;
  7. sbit C2 = P3^5;
  8. sbit C3 = P4^2;
  9. sbit C4 = P4^4;
  10. void KeyScanf()
  11. {
  12. R3=0;
  13. R1 = R2 = R4 = 1;
  14. C1 = C2 = C3 =C4= 1;
  15. if(C4==0)//S5
  16. {
  17. countkey=0;while(countkey<=10);//延时
  18. if(C4==0)
  19. {
  20. while(C4==0);
  21. CountS5++;
  22. if(CountS4!=2)//界面2有三个子界面
  23. {
  24. if(CountS5==2)CountS5=0;//切子页面
  25. }
  26. else
  27. {
  28. if(CountS5==3)CountS5=0;
  29. }
  30. }
  31. }
  32. if(C3==0)//S9
  33. {
  34. countkey=0;while(countkey<=10);
  35. if(C3==0)
  36. {
  37. while(C3==0)//while中判断S8是否按下
  38. {
  39. R4=0;
  40. R1 = R2 = R3 = 1;
  41. C1 = C2 = C3 =C4= 1;
  42. // countkey=0;while(countkey<=50);
  43. if(C3==0)
  44. {
  45. countchangan=0;//计时变量
  46. while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;//复位命令
  47. }
  48. R3=0;
  49. R1 = R2 = R4 = 1;
  50. C1 = C2 = C3 =C4= 1;//记得切回来S9这一行,不然就不满足while中的C3==0了
  51. }
  52. if(CountS5==0&&CountS4==2)//下面就是界面中的一些数值的加减,不多赘述
  53. {
  54. if(jiaozhun==0)
  55. {
  56. if(jiaozhun1!=90)
  57. jiaozhun1+=5;
  58. fuFlag=1;
  59. }
  60. else
  61. {
  62. fuFlag=0;
  63. jiaozhun-=5;
  64. }
  65. }
  66. if(CountS5==1&&CountS4==2)
  67. {
  68. if(sudu!=1)sudu--;
  69. }
  70. if(CountS5==2&&CountS4==2)
  71. {
  72. if(DA!=1)DA--;
  73. }
  74. if(CountS4==0&&JLflag==1)
  75. {
  76. DAdistance=distance;
  77. DAflag=1;
  78. }
  79. if(CountS5==1&&CountS4==1)if(tempCS!=0)tempCS-=10;
  80. if(CountS5==0&&CountS4==1)if(juliCS!=10)juliCS-=10;
  81. }
  82. }
  83. R4=0;
  84. R1 = R2 = R3 = 1;
  85. C1 = C2 = C3 =C4= 1;
  86. if(C4==0)//S4
  87. {
  88. countkey=0;while(countkey<=10);
  89. if(C4==0)
  90. {
  91. while(C4==0);
  92. CountS4++;//主界面切换
  93. CountS5=0;
  94. if(CountS4==3)CountS4=0;
  95. }
  96. }
  97. if(C3==0)//S8
  98. {
  99. countkey=0;while(countkey<=10);
  100. if(C3==0)//S8同理S9
  101. {
  102. while(C3==0)
  103. {
  104. R3=0;
  105. R1 = R2 = R4 = 1;
  106. C1 = C2 = C3 =C4= 1;
  107. countkey=0;while(countkey<=50);
  108. if(C3==0)
  109. {
  110. countchangan=0;
  111. while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;
  112. }
  113. R4=0;
  114. R1 = R2 = R3 = 1;
  115. C1 = C2 = C3 =C4= 1;
  116. }
  117. if(CountS5==0&&CountS4==2)
  118. {
  119. if(fuFlag==1)
  120. {
  121. if(jiaozhun1==0)
  122. {
  123. fuFlag==0;
  124. jiaozhun+=5;
  125. }
  126. else
  127. {
  128. jiaozhun1-=5;
  129. if(jiaozhun1==0)fuFlag=0;
  130. }
  131. }
  132. else
  133. {
  134. if(jiaozhun!=90)
  135. jiaozhun+=5;
  136. }
  137. }
  138. if(CountS5==1&&CountS4==2)
  139. {
  140. if(sudu!=999)sudu++;
  141. }
  142. if(CountS5==2&&CountS4==2)
  143. {
  144. if(DA!=20)DA++;
  145. }
  146. if(CountS4==0)countjilu=0;
  147. if(CountS5==1&&CountS4==1)if(tempCS!=800)tempCS+=10;
  148. if(CountS5==0&&CountS4==1)if(juliCS!=90)juliCS+=10;
  149. }
  150. }
  151. }

4,DA输出和记录超声波数据

        DA输出的计算和省赛区别不大,记录过程中要屏蔽按键,只需要设置一个标志位就可以做到,在设置一个计时变量,等待时间到了,赋值输出变量即可。

  1. void CtrlDA()
  2. {
  3. if(DAdistance<=10)DAshuchu=DA;
  4. if(DAdistance>=90)DAshuchu=50;
  5. if(DAdistance<90&&distance>10)
  6. {
  7. DAshuchu=((50-DA)/80.00)*(DAdistance-10)+DA;
  8. }
  9. DAtransport(DAshuchu*5.1);
  10. }
  11. //下面的代码在main中
  12. if(countjilu>6000)//如果计时变量大于6秒才可以使用按键
  13. KeyScanf();
  14. if(countjilu==6001)//到了六秒,记录标志位置一,计时变量置9999(不再自增)
  15. {
  16. JLflag=1;
  17. countjilu=9999;
  18. }
  19. if(DAflag==1)CtrlDA();
  20. //下面代码在按键中
  21. //S8
  22. if(CountS4==0)countjilu=0;//S8记录开启
  23. //S9
  24. if(CountS4==0&&JLflag==1)//如果在界面一且记录完成
  25. {
  26. DAdistance=distance;//赋值
  27. DAflag=1;//输出变量
  28. }

5,LED显示二进制和继电器

        这是本代码中最容易的考点,只需要判断距离的值,在0到256中直接将P0 等于距离值取反就行了,继电器就更简单了,判断在区间内,执行就行了,比较简单就不写注释了(累了)

  1. void CtrlJDQ()
  2. {
  3. if((distance>=juliCS-5)&&(distance<=juliCS+5)&&temp>=tempCS)
  4. {
  5. SeleHC573(0,0x00);
  6. SeleHC573(5,0x10);
  7. SeleHC573(0,0x00);
  8. }
  9. else
  10. {
  11. SeleHC573(0,0x00);
  12. SeleHC573(5,0x00);
  13. SeleHC573(0,0x00);
  14. }
  15. }
  16. void CtrlLED()
  17. {
  18. uchar LED=0xff;
  19. switch(CountS4)
  20. {
  21. case 0:
  22. if(distance>=255)LED=0x00;
  23. if(distance<255&&distance>=0)LED=~distance;
  24. if(distance<0)LED=0xff;
  25. break;
  26. case 1:
  27. LED = 0x7f;
  28. break;
  29. case 2:
  30. if(countled<=100)LED=0xfe;
  31. else
  32. {
  33. if(countled>=200)countled=0;
  34. LED=0xff;
  35. }
  36. }
  37. SeleHC573(4,LED);
  38. }

 四,可运行代码

  1. #include <STC15F2K60S2.H>
  2. #include "intrins.h"
  3. #include "onewire.h"
  4. #include "iic.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. sbit Tx = P1^0;
  8. sbit Rx = P1^1;
  9. sfr ISP_CONTR = 0xc7;
  10. sbit R1 = P3^0;
  11. sbit R2 = P3^1;
  12. sbit R3 = P3^2;
  13. sbit R4 = P3^3;
  14. sbit C1 = P3^4;
  15. sbit C2 = P3^5;
  16. sbit C3 = P4^2;
  17. sbit C4 = P4^4;
  18. code unsigned char Seg_Table[] =
  19. {
  20. 0xc0, //0
  21. 0xf9, //1
  22. 0xa4, //2
  23. 0xb0, //3
  24. 0x99, //4
  25. 0x92, //5
  26. 0x82, //6
  27. 0xf8, //7
  28. 0x80, //8
  29. 0x90, //9
  30. 0x88, //A
  31. 0x83, //b
  32. 0xc6, //C
  33. 0xa1, //d
  34. 0x86, //E
  35. 0x8e,//F
  36. 0xff,
  37. 0x7f,
  38. 0xbf,
  39. 0x8c
  40. };
  41. uchar seg_loop[] = {16,16,16,16,16,16,16,16};
  42. uchar j;
  43. uchar DAflag,JLflag;
  44. uint countcsb,countkey,counttemp,countjilu=9999 ,countled;
  45. uint countchangan;
  46. uint distance,DAdistance;
  47. uint temp;
  48. uchar CountS5,CountS4;
  49. uchar juliCS=40;
  50. uint tempCS=300;
  51. uchar jiaozhun,jiaozhun1;
  52. uint sudu=34;
  53. uchar fuFlag;
  54. uchar DA=10,DAshuchu;
  55. void CtrlJDQ();void CtrlLED();
  56. void Delay12us(void) //@12.000MHz
  57. {
  58. unsigned char data i;
  59. _nop_();
  60. _nop_();
  61. i = 33;
  62. while (--i);
  63. }
  64. void SeleHC573(uchar n,dat)
  65. {
  66. P0 = dat;
  67. switch(n)
  68. {
  69. case 0:P2 = (P2&0x1f)|0x00;break;
  70. case 4:P2 = (P2&0x1f)|0x80;break;
  71. case 5:P2 = (P2&0x1f)|0xa0;break;
  72. case 6:P2 = (P2&0x1f)|0xc0;break;
  73. case 7:P2 = (P2&0x1f)|0xe0;break;
  74. }
  75. P2 = (P2&0x1f)|0x00;
  76. }
  77. void InitTime()
  78. {
  79. TMOD = 0x10;
  80. TH1 = (65535-1000)/256;
  81. TL1 = (65535-1000)%256;
  82. EA = 1;
  83. ET1 = 1;
  84. TR1 = 1;
  85. }
  86. void ServiceT1() interrupt 3
  87. {
  88. TH1 = (65535-1000)/256;
  89. TL1 = (65535-1000)%256;
  90. // SeleHC573(0,0xff);
  91. SeleHC573(6,0x01<<j);
  92. if(CountS4==0||CountS4==2)
  93. {
  94. if(((CountS4==0)&&(CountS5==1)&&(j==5)&&(distance != 999))||((CountS4==0)&&(j==1))||((CountS4==2)&&(CountS5==2)&&(j==6)))
  95. SeleHC573(7,Seg_Table[seg_loop[j]]-0x80);
  96. else
  97. {
  98. SeleHC573(7,Seg_Table[seg_loop[j]]);
  99. }
  100. }
  101. else
  102. {
  103. SeleHC573(7,Seg_Table[seg_loop[j]]);
  104. }
  105. // SeleHC573(0,0xff);
  106. CtrlJDQ();
  107. j++;if(j>7)j=0;
  108. counttemp++;
  109. countcsb++;
  110. countkey++;
  111. countled++;
  112. countchangan++;
  113. if(countjilu<=6000) countjilu++;
  114. CtrlLED();
  115. }
  116. void SendWave()
  117. {
  118. uchar i;
  119. EA = 0;
  120. for(i=0;i<8;i++)
  121. {
  122. Tx = 1;
  123. Delay12us();
  124. Tx = 0;
  125. Delay12us();
  126. }
  127. EA = 1;
  128. }
  129. uint csb()
  130. {
  131. uint dis,time;
  132. CMOD &= 0x00;
  133. CH = 0;
  134. CL = 0;
  135. SendWave();
  136. CR = 1;
  137. while((Rx==1)&&(CF==0));
  138. CR = 0;
  139. if(CF==0)
  140. {
  141. time = (CH<<8)|CL;
  142. if(fuFlag==0)
  143. dis = ((time/10)*sudu/2)/100+3+jiaozhun;
  144. else
  145. dis = ((time/10)*sudu/2)/100+3-jiaozhun1;
  146. }
  147. else
  148. {
  149. CF=0;
  150. dis = 999;
  151. }
  152. return dis;
  153. }
  154. void Init_sys()
  155. {
  156. SeleHC573(4,0xff);
  157. SeleHC573(5,0x00);
  158. }
  159. void ReadTemp()
  160. {
  161. uchar MSB,LSB;
  162. init_ds18b20();
  163. Write_DS18B20(0xcc);
  164. Write_DS18B20(0x44);
  165. init_ds18b20();
  166. Write_DS18B20(0xcc);
  167. Write_DS18B20(0xbe);
  168. LSB = Read_DS18B20();
  169. MSB = Read_DS18B20();
  170. // temp = MSB;
  171. temp = ((MSB<<8)|LSB)*0.625;
  172. // temp = temp*0.625;
  173. }
  174. void DAtransport(uchar x)
  175. {
  176. I2CStart();
  177. I2CSendByte(0x90);
  178. I2CWaitAck();
  179. I2CSendByte(0x40);
  180. I2CWaitAck();
  181. I2CSendByte(x);
  182. I2CWaitAck();
  183. I2CStop();
  184. }
  185. void Showcsb()
  186. {
  187. seg_loop[0] = temp/100;
  188. seg_loop[1] = temp%100/10;
  189. seg_loop[2] = temp%10;
  190. seg_loop[3] = 18;
  191. if(distance!=999)
  192. {
  193. if(distance/1000!=0)
  194. {
  195. seg_loop[4] = distance/1000;
  196. }
  197. else
  198. {
  199. seg_loop[4] = 16;
  200. }
  201. if((CountS5==1)||(distance/100!=0))
  202. {
  203. seg_loop[5] = distance%1000/100;
  204. }
  205. else
  206. {
  207. seg_loop[5] = 16;
  208. }
  209. if((CountS5==1)||(distance/10!=0))
  210. seg_loop[6] = distance%100/10;
  211. else
  212. seg_loop[6] = 16;
  213. if(distance>=0)
  214. seg_loop[7] = distance%10;
  215. else
  216. seg_loop[7] = 16;
  217. }
  218. else seg_loop[7] = seg_loop[6] = seg_loop[5] = seg_loop[4] = 16;
  219. }
  220. void ShowtempCS()
  221. {
  222. seg_loop[0] = 19;
  223. seg_loop[1] = 2;
  224. seg_loop[2] = seg_loop[3] = seg_loop[4] = seg_loop[5] = 16;
  225. seg_loop[6] = tempCS/100;
  226. seg_loop[7] = tempCS%100/10;
  227. }
  228. void ShowjuliCS()
  229. {
  230. seg_loop[0] = 19;
  231. seg_loop[1] = 1;
  232. seg_loop[2] = seg_loop[3] = seg_loop[4] = seg_loop[5] = 16;
  233. seg_loop[6] = juliCS/10;
  234. seg_loop[7] = juliCS%10;
  235. }
  236. void Showjiaozhun()
  237. {
  238. seg_loop[0] = 15;
  239. seg_loop[1] = 1;
  240. seg_loop[2] = seg_loop[3] = seg_loop[4] =16;
  241. if(fuFlag==0)
  242. {
  243. seg_loop[5] = 16;
  244. if(jiaozhun>=10)seg_loop[6] = jiaozhun/10;
  245. else seg_loop[6] = 16;
  246. seg_loop[7] = jiaozhun%10;
  247. }
  248. else
  249. {
  250. if(jiaozhun1>=10)
  251. {
  252. seg_loop[6] = jiaozhun1/10;
  253. seg_loop[5] = 18;
  254. }
  255. else
  256. {
  257. seg_loop[6] = 18;
  258. seg_loop[5] = 16;
  259. }
  260. seg_loop[7] = jiaozhun1%10;
  261. }
  262. }
  263. void Showsudu()
  264. {
  265. seg_loop[0] = 15;
  266. seg_loop[1] = 2;
  267. seg_loop[2] = seg_loop[3] = 16;
  268. if(sudu/100!=0)
  269. seg_loop[4] = sudu/100;
  270. else
  271. seg_loop[4] = 16;
  272. if(sudu/10!=0)
  273. seg_loop[5] = sudu%100/10;
  274. else
  275. seg_loop[5] = 16;
  276. seg_loop[6] = sudu%10;
  277. seg_loop[7] = 0;
  278. }
  279. void ShowDA()
  280. {
  281. seg_loop[0] = 15;
  282. seg_loop[1] = 3;
  283. seg_loop[2] = seg_loop[3] = seg_loop[4] = seg_loop[5] = 16;
  284. seg_loop[6] = DA/10;
  285. seg_loop[7] = DA%10;
  286. }
  287. void Display()
  288. {
  289. switch(CountS4)
  290. {
  291. case 0:Showcsb();break;
  292. case 1:
  293. switch(CountS5)
  294. {
  295. case 0:ShowjuliCS();break;
  296. case 1:ShowtempCS();break;
  297. }
  298. break;
  299. case 2:
  300. switch(CountS5)
  301. {
  302. case 0:Showjiaozhun();break;
  303. case 1:Showsudu();break;
  304. case 2:ShowDA();break;
  305. }
  306. break;
  307. }
  308. }
  309. void CtrlDA()
  310. {
  311. if(DAdistance<=10)DAshuchu=DA;
  312. if(DAdistance>=90)DAshuchu=50;
  313. if(DAdistance<90&&distance>10)
  314. {
  315. DAshuchu=((50-DA)/80.00)*(DAdistance-10)+DA;
  316. }
  317. DAtransport(DAshuchu*5.1);
  318. }
  319. void CtrlJDQ()
  320. {
  321. if((distance>=juliCS-5)&&(distance<=juliCS+5)&&temp>=tempCS)
  322. {
  323. SeleHC573(0,0x00);
  324. SeleHC573(5,0x10);
  325. SeleHC573(0,0x00);
  326. }
  327. else
  328. {
  329. SeleHC573(0,0x00);
  330. SeleHC573(5,0x00);
  331. SeleHC573(0,0x00);
  332. }
  333. }
  334. void CtrlLED()
  335. {
  336. uchar LED=0xff;
  337. switch(CountS4)
  338. {
  339. case 0:
  340. if(distance>=255)LED=0x00;
  341. if(distance<255&&distance>=0)LED=~distance;
  342. if(distance<0)LED=0xff;
  343. break;
  344. case 1:
  345. LED = 0x7f;
  346. break;
  347. case 2:
  348. if(countled<=100)LED=0xfe;
  349. else
  350. {
  351. if(countled>=200)countled=0;
  352. LED=0xff;
  353. }
  354. }
  355. SeleHC573(4,LED);
  356. }
  357. void KeyScanf()
  358. {
  359. R3=0;
  360. R1 = R2 = R4 = 1;
  361. C1 = C2 = C3 =C4= 1;
  362. if(C4==0)//S5
  363. {
  364. countkey=0;while(countkey<=10);
  365. if(C4==0)
  366. {
  367. while(C4==0);
  368. CountS5++;
  369. if(CountS4!=2)
  370. {
  371. if(CountS5==2)CountS5=0;
  372. }
  373. else
  374. {
  375. if(CountS5==3)CountS5=0;
  376. }
  377. }
  378. }
  379. if(C3==0)//S9
  380. {
  381. countkey=0;while(countkey<=10);
  382. //
  383. // R4=0;
  384. // R1 = R2 = R3 = 1;
  385. // C1 = C2 = C3 =C4= 1;
  386. // countkey=0;while(countkey<=50);
  387. // if(C3==0)
  388. // {
  389. // countchangan=0;
  390. // while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;
  391. // }
  392. // else
  393. // {
  394. // R3=0;
  395. // R1 = R2 = R4 = 1;
  396. // C1 = C2 = C3 =C4= 1;
  397. if(C3==0)
  398. {
  399. while(C3==0)
  400. {
  401. R4=0;
  402. R1 = R2 = R3 = 1;
  403. C1 = C2 = C3 =C4= 1;
  404. // countkey=0;while(countkey<=50);
  405. if(C3==0)
  406. {
  407. countchangan=0;
  408. while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;
  409. }
  410. R3=0;
  411. R1 = R2 = R4 = 1;
  412. C1 = C2 = C3 =C4= 1;
  413. }
  414. if(CountS5==0&&CountS4==2)
  415. {
  416. if(jiaozhun==0)
  417. {
  418. if(jiaozhun1!=90)
  419. jiaozhun1+=5;
  420. fuFlag=1;
  421. }
  422. else
  423. {
  424. fuFlag=0;
  425. jiaozhun-=5;
  426. }
  427. }
  428. if(CountS5==1&&CountS4==2)
  429. {
  430. if(sudu!=1)sudu--;
  431. }
  432. if(CountS5==2&&CountS4==2)
  433. {
  434. if(DA!=1)DA--;
  435. }
  436. if(CountS4==0&&JLflag==1)
  437. {
  438. DAdistance=distance;
  439. DAflag=1;
  440. }
  441. if(CountS5==1&&CountS4==1)if(tempCS!=0)tempCS-=10;
  442. if(CountS5==0&&CountS4==1)if(juliCS!=10)juliCS-=10;
  443. }
  444. }
  445. R4=0;
  446. R1 = R2 = R3 = 1;
  447. C1 = C2 = C3 =C4= 1;
  448. if(C4==0)//S4
  449. {
  450. countkey=0;while(countkey<=10);
  451. if(C4==0)
  452. {
  453. while(C4==0);
  454. CountS4++;
  455. CountS5=0;
  456. if(CountS4==3)CountS4=0;
  457. }
  458. }
  459. if(C3==0)//S8
  460. {
  461. countkey=0;while(countkey<=10);
  462. // R3=0;
  463. // R1 = R2 = R4 = 1;
  464. // C1 = C2 = C3 =C4= 1;
  465. // countkey=0;while(countkey<=50);
  466. // if(C3==0)
  467. // {
  468. // countchangan=0;
  469. // while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;
  470. // }
  471. // else
  472. // {
  473. // R4=0;
  474. // R1 = R2 = R3 = 1;
  475. // C1 = C2 = C3 =C4= 1;
  476. if(C3==0)
  477. {
  478. while(C3==0)
  479. {
  480. R3=0;
  481. R1 = R2 = R4 = 1;
  482. C1 = C2 = C3 =C4= 1;
  483. countkey=0;while(countkey<=50);
  484. if(C3==0)
  485. {
  486. countchangan=0;
  487. while(C3==0)if(countchangan>=2000)ISP_CONTR = 0x20;
  488. }
  489. R4=0;
  490. R1 = R2 = R3 = 1;
  491. C1 = C2 = C3 =C4= 1;
  492. }
  493. if(CountS5==0&&CountS4==2)
  494. {
  495. if(fuFlag==1)
  496. {
  497. if(jiaozhun1==0)
  498. {
  499. fuFlag==0;
  500. jiaozhun+=5;
  501. }
  502. else
  503. {
  504. jiaozhun1-=5;
  505. if(jiaozhun1==0)fuFlag=0;
  506. }
  507. }
  508. else
  509. {
  510. if(jiaozhun!=90)
  511. jiaozhun+=5;
  512. }
  513. }
  514. if(CountS5==1&&CountS4==2)
  515. {
  516. if(sudu!=999)sudu++;
  517. }
  518. if(CountS5==2&&CountS4==2)
  519. {
  520. if(DA!=20)DA++;
  521. }
  522. if(CountS4==0)countjilu=0;
  523. if(CountS5==1&&CountS4==1)if(tempCS!=800)tempCS+=10;
  524. if(CountS5==0&&CountS4==1)if(juliCS!=90)juliCS+=10;
  525. }
  526. }
  527. }
  528. void main()
  529. {
  530. Init_sys();
  531. InitTime();
  532. while(1)
  533. {
  534. if(countjilu>6000)
  535. KeyScanf();
  536. if(countjilu==6001)
  537. {
  538. JLflag=1;
  539. countjilu=9999;
  540. }
  541. if(counttemp>=150)
  542. {
  543. counttemp=0;
  544. ReadTemp();
  545. }
  546. if(countcsb>=500)
  547. {
  548. countcsb=0;
  549. distance = csb();
  550. }
  551. if(DAflag==1)CtrlDA();
  552. // CtrlLED();
  553. // CtrlJDQ();
  554. Display();
  555. }
  556. }

五,心得 

        写完国赛题之后,个人认为好的代码不是越短或者是使用的语法越高级越好,在看了许多例程和高手的代码后,才知道好的代码需要有很高的可读性。希望在国赛可以取得好成绩。

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

闽ICP备14008679号