当前位置:   article > 正文

蓝桥杯单片机第十四届省赛题目和程序答案_蓝桥杯单片机历届试题

蓝桥杯单片机历届试题

目录

 1、前言

 2、题目

3、程序架构 

   3.1 display.c

   3.2 ds1302.c

   3.3 iic.c

   3.4 onewire.c

   3.5 main.c 主函数文件

   3.6 环境配置

4. 历年蓝桥杯单片机试题和答案


 1、前言

       抽空复习了一下,拿下单片机省赛一等奖,在此分享一下最新的14届省赛程序设计答案

 2、题目

 

 

 

3、程序架构 

 

 模块化编程,每个模块的程序单独写在一个文中,下面分别给出图中文件的详细代码

   3.1 display.c

          主要包含数码管、led显示。

  1. #include "display.h"
  2. code unsigned char Seg_Table[] =
  3. {
  4. 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, //9
  5. 0x88, //A
  6. 0x83, //b
  7. 0xc6, //C 12
  8. 0xa1, //d
  9. 0x86, //E
  10. 0x8e, //F 15
  11. 0xbf, // - 16
  12. 0x89, // H 17
  13. 0x8C, // P 18
  14. 0x88 // R 19
  15. };
  16. //0-9带小数点
  17. code unsigned char Seg_Table_f[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};
  18. void Delayms(int ms) //@12.000MHz
  19. {
  20. unsigned char i, j;
  21. int k =0;
  22. for(k=0;k<ms;k++){
  23. i = 12;
  24. j = 169;
  25. do
  26. {
  27. while (--j);
  28. } while (--i);
  29. }
  30. }
  31. //选择开启哪一个锁存器
  32. void SelectHc573(char wei)
  33. {
  34. switch(wei){
  35. case 4: P2 = (P2 & 0x1f) | 0x80; break; //LED驱动
  36. case 5: P2 = (P2 & 0x1f) | 0xa0; break; //蜂鸣器,继电器
  37. case 6: P2 = (P2 & 0x1f) | 0xc0; break; //数码管位选
  38. case 7: P2 = (P2 & 0x1f) | 0xe0; break; //数码管段选
  39. }
  40. P2 = (P2 & 0x1f) | 0x00;
  41. }
  42. //系统初始化,关蜂鸣器继电器、数码管
  43. void SysInit()
  44. {
  45. P0 = 0x00;
  46. SelectHc573(5);
  47. SelectHc573(6);
  48. P0 = 0xff;
  49. SelectHc573(4);
  50. }
  51. //数码管无小数点显示,参数wei:打开哪一个数码管,参数duan:显示什么内容
  52. void DisplaySeg(char wei, char duan)
  53. {
  54. P0 = 0x01 << wei - 1;
  55. SelectHc573(6);
  56. P0 = Seg_Table[duan];
  57. SelectHc573(7);
  58. Delayms(1);
  59. P0 = 0x01 << wei - 1;
  60. SelectHc573(6);
  61. P0 = 0xff;
  62. SelectHc573(7);
  63. }
  64. //数码管带小数点显示
  65. void DisplaySeg_f(char wei, char duan)
  66. {
  67. P0 = 0x01 << wei - 1;
  68. SelectHc573(6);
  69. P0 = Seg_Table_f[duan];
  70. SelectHc573(7);
  71. Delayms(1);
  72. P0 = 0x01 << wei - 1;
  73. SelectHc573(6);
  74. P0 = 0xff;
  75. SelectHc573(7);
  76. }//LED显示,参数wei:控制哪一个LED,参数on_off1-点亮,0-关闭
  77. void DisplayLed(char wei,char on_off)
  78. {
  79. static unsigned char temp = 0xff;
  80. if(on_off){
  81. switch(wei){
  82. case 1: temp = temp & 0xfe; break;
  83. case 2: temp = temp & 0xfd; break;
  84. case 3: temp = temp & 0xfb; break;
  85. case 4: temp = temp & 0xf7; break;
  86. case 5: temp = temp & 0xef; break;
  87. case 6: temp = temp & 0xdf; break;
  88. }
  89. }else{
  90. switch(wei){
  91. case 1: temp = temp | 0x01; break;
  92. case 2: temp = temp | 0x02; break;
  93. case 3: temp = temp | 0x04; break;
  94. case 4: temp = temp | 0x08; break;
  95. case 5: temp = temp | 0x10; break;
  96. case 6: temp = temp | 0x20; break;
  97. }
  98. }
  99. P0 = temp;
  100. SelectHc573(4);
  101. }

 上面代码中头文件display.h

  1. #ifndef __DISPLAY_H__
  2. #define __DISPLAY_H__
  3. #include <stc15.h>
  4. void Delayms(int ms) ; //@12.000MHz
  5. void SelectHc573(char wei);
  6. void SysInit();
  7. void DisplayLed(char wei,char on_off);
  8. void DisplaySeg(char wei, char duan);
  9. void DisplaySeg_f(char wei, char duan);
  10. #endif

   3.2 ds1302.c

          主要是ds1302写时间函数,和读时间函数

  1. /* # DS1302代码片段说明
  2. 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
  3. 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
  4. 中对单片机时钟频率的要求,进行代码调试和修改。
  5. */
  6. #include "ds1302.h"
  7. //
  8. void Write_Ds1302(unsigned char temp)
  9. {
  10. unsigned char i;
  11. for (i=0;i<8;i++)
  12. {
  13. SCK = 0;
  14. SDA = temp&0x01;
  15. temp>>=1;
  16. SCK=1;
  17. }
  18. }
  19. //
  20. void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
  21. {
  22. RST=0; _nop_();
  23. SCK=0; _nop_();
  24. RST=1; _nop_();
  25. Write_Ds1302(address);
  26. Write_Ds1302(dat);
  27. RST=0;
  28. }
  29. //
  30. unsigned char Read_Ds1302_Byte ( unsigned char address )
  31. {
  32. unsigned char i,temp=0x00;
  33. RST=0; _nop_();
  34. SCK=0; _nop_();
  35. RST=1; _nop_();
  36. Write_Ds1302(address);
  37. for (i=0;i<8;i++)
  38. {
  39. SCK=0;
  40. temp>>=1;
  41. if(SDA)
  42. temp|=0x80;
  43. SCK=1;
  44. }
  45. RST=0; _nop_();
  46. SCK=0; _nop_();
  47. SCK=1; _nop_();
  48. SDA=0; _nop_();
  49. SDA=1; _nop_();
  50. return (temp);
  51. }
  52. //本行之前的代码是官方给出的,本行下面的代码是自己写的
  53. #define WP 0x8e
  54. #define W_HOUR 0x84
  55. #define W_MIN 0x82
  56. #define W_SEC 0x80
  57. #define R_HOUR 0x85
  58. #define R_MIN 0x83
  59. #define R_SEC 0x81
  60. //写入一个初始时间到ds1302
  61. void WriteDateTo1302(ds1302 *date)
  62. {
  63. unsigned char hour,min,sec;
  64. hour = date->hour/10*16 + date->hour%10; //十进制转16进制
  65. min = date->min/10*16 + date->min%10;
  66. sec = date->sec/10*16 + date->sec%10;
  67. Write_Ds1302_Byte(WP,0x00);
  68. Write_Ds1302_Byte(W_HOUR,hour);
  69. Write_Ds1302_Byte(W_MIN,min);
  70. Write_Ds1302_Byte(W_SEC,sec);
  71. Write_Ds1302_Byte(WP,0x80);
  72. }
  73. //读取当前时间
  74. ds1302 ReadTimeFrom1302()
  75. {
  76. unsigned char hour,min,sec;
  77. ds1302 date;
  78. hour = Read_Ds1302_Byte(R_HOUR);
  79. min = Read_Ds1302_Byte(R_MIN);
  80. sec = Read_Ds1302_Byte(R_SEC);
  81. date.hour = hour/16*10 + hour%16; //十六进制转十进制
  82. date.min = min/16*10 + min%16;
  83. date.sec = sec/16*10 + sec%16;
  84. return date;
  85. }

 头文件ds1302.h,该文件从今年开始官方不提供,都是自己写

  1. #ifndef __DS1302_H__
  2. #define __DS1302_H__
  3. #include "intrins.h"
  4. #include <stc15.h>
  5. #define SCK P17
  6. #define SDA P23
  7. #define RST P13
  8. //定义ds1302数据类型
  9. typedef struct{
  10. unsigned char hour;
  11. unsigned char min;
  12. unsigned char sec;
  13. }ds1302;
  14. ds1302 ReadTimeFrom1302();
  15. void WriteDateTo1302(ds1302 *date);
  16. #endif

   3.3 iic.c

           用于读取pcf8591通道1的电压

  1. /* # I2C代码片段说明
  2. 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
  3. 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
  4. 中对单片机时钟频率的要求,进行代码调试和修改。
  5. */
  6. #include "iic.h"
  7. #include "intrins.h"
  8. #define DELAY_TIME 5
  9. //
  10. static void I2C_Delay(unsigned char n)
  11. {
  12. do
  13. {
  14. _nop_();_nop_();_nop_();_nop_();_nop_();
  15. _nop_();_nop_();_nop_();_nop_();_nop_();
  16. _nop_();_nop_();_nop_();_nop_();_nop_();
  17. }
  18. while(n--);
  19. }
  20. //
  21. void I2CStart(void)
  22. {
  23. sda = 1;
  24. scl = 1;
  25. I2C_Delay(DELAY_TIME);
  26. sda = 0;
  27. I2C_Delay(DELAY_TIME);
  28. scl = 0;
  29. }
  30. //
  31. void I2CStop(void)
  32. {
  33. sda = 0;
  34. scl = 1;
  35. I2C_Delay(DELAY_TIME);
  36. sda = 1;
  37. I2C_Delay(DELAY_TIME);
  38. }
  39. //
  40. void I2CSendByte(unsigned char byt)
  41. {
  42. unsigned char i;
  43. for(i=0; i<8; i++){
  44. scl = 0;
  45. I2C_Delay(DELAY_TIME);
  46. if(byt & 0x80){
  47. sda = 1;
  48. }
  49. else{
  50. sda = 0;
  51. }
  52. I2C_Delay(DELAY_TIME);
  53. scl = 1;
  54. byt <<= 1;
  55. I2C_Delay(DELAY_TIME);
  56. }
  57. scl = 0;
  58. }
  59. //
  60. unsigned char I2CReceiveByte(void)
  61. {
  62. unsigned char da;
  63. unsigned char i;
  64. for(i=0;i<8;i++){
  65. scl = 1;
  66. I2C_Delay(DELAY_TIME);
  67. da <<= 1;
  68. if(sda)
  69. da |= 0x01;
  70. scl = 0;
  71. I2C_Delay(DELAY_TIME);
  72. }
  73. return da;
  74. }
  75. //
  76. unsigned char I2CWaitAck(void)
  77. {
  78. unsigned char ackbit;
  79. scl = 1;
  80. I2C_Delay(DELAY_TIME);
  81. ackbit = sda;
  82. scl = 0;
  83. I2C_Delay(DELAY_TIME);
  84. return ackbit;
  85. }
  86. //
  87. void I2CSendAck(unsigned char ackbit)
  88. {
  89. scl = 0;
  90. sda = ackbit;
  91. I2C_Delay(DELAY_TIME);
  92. scl = 1;
  93. I2C_Delay(DELAY_TIME);
  94. scl = 0;
  95. sda = 1;
  96. I2C_Delay(DELAY_TIME);
  97. }
  98. 本行之前的代码是官方给出的,本行下面的代码是自己写的
  99. unsigned char ADC_Output(char channel)
  100. {
  101. unsigned char adc_val;
  102. I2CStart();
  103. I2CSendByte(0x90);
  104. I2CWaitAck();
  105. I2CSendByte(channel);
  106. I2CWaitAck();
  107. I2CStart();
  108. I2CSendByte(0x91);
  109. I2CWaitAck();
  110. adc_val = I2CReceiveByte();
  111. I2CSendAck(1);
  112. I2CStop();
  113. return adc_val;
  114. }

 对应的头文件iic.h

  1. #ifndef __IIC_H__
  2. #define __IIC_H__
  3. #include <stc15.h>
  4. #define sda P21
  5. #define scl P20
  6. unsigned char ADC_Output(char channel);
  7. #endif

   3.4 onewire.c

  1. /* # 单总线代码片段说明
  2. 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
  3. 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
  4. 中对单片机时钟频率的要求,进行代码调试和修改。
  5. */
  6. #include "onewire.h"
  7. //
  8. void Delay_OneWire(unsigned int t)
  9. {
  10. unsigned char i;
  11. while(t--){
  12. for(i=0;i<12;i++);
  13. }
  14. }
  15. //
  16. void Write_DS18B20(unsigned char dat)
  17. {
  18. unsigned char i;
  19. for(i=0;i<8;i++)
  20. {
  21. DQ = 0;
  22. DQ = dat&0x01;
  23. Delay_OneWire(5);
  24. DQ = 1;
  25. dat >>= 1;
  26. }
  27. Delay_OneWire(5);
  28. }
  29. //
  30. unsigned char Read_DS18B20(void)
  31. {
  32. unsigned char i;
  33. unsigned char dat;
  34. for(i=0;i<8;i++)
  35. {
  36. DQ = 0;
  37. dat >>= 1;
  38. DQ = 1;
  39. Delay_OneWire(1);//本行代码可删去,原来没有的,只是为了适应本人的板子添加
  40. if(DQ)
  41. {
  42. dat |= 0x80;
  43. }
  44. Delay_OneWire(5);
  45. }
  46. return dat;
  47. }
  48. //
  49. bit init_ds18b20(void)
  50. {
  51. bit initflag = 0;
  52. DQ = 1;
  53. Delay_OneWire(12);
  54. DQ = 0;
  55. Delay_OneWire(80);
  56. DQ = 1;
  57. Delay_OneWire(10);
  58. initflag = DQ;
  59. Delay_OneWire(5);
  60. return initflag;
  61. }
  62. //本行之前的代码是官方给出的,本行下面的代码是自己写的
  63. unsigned char rd_temperature()
  64. {
  65. unsigned char temp,th,tl;
  66. init_ds18b20();
  67. Write_DS18B20(0xcc);
  68. Write_DS18B20(0x44);
  69. init_ds18b20();
  70. //本函数上面部分是启动温度转化,下面部分是温度读取
  71. // 为防止开机上电读取出现85,可在上电先启动温度转换,延时750模式,再进入循环。
  72. Write_DS18B20(0xcc);
  73. Write_DS18B20(0xbe);
  74. tl = Read_DS18B20(); //先读低8位,再读高8
  75. th = Read_DS18B20();
  76. temp = (th*256 + tl)*0.0625;
  77. return temp;
  78. }

 对应的onewire.h

  1. #ifndef __ONEWIRE_H__
  2. #define __ONEWIRE_H__
  3. #include <stc15.h>
  4. #define DQ P14
  5. unsigned char rd_temperature();
  6. #endif

   3.5 main.c 主函数文件

  1. #include "display.h"
  2. #include "onewire.h"
  3. #include "ds1302.h"
  4. #include "iic.h"
  5. #include "string.h"
  6. ds1302 date = {23,59,55}; //初始化时间为23-59-55
  7. unsigned int FREQUENTCY; //NE5555频率
  8. unsigned char count,count2,flag_1s,sec,key_val,flag_100ms;
  9. unsigned char show_switching = 1,collect_flag=1,show,S5_flag=1,L4_flag,L5_flag,L6_flag;
  10. unsigned char adc_val,t_para=30,count_triggle,count3,count_sec;
  11. unsigned char temp=0,humidity,i,last_hour,last_min;
  12. unsigned char t[3],h[3]; //用于保存采集的温度、湿度,只保存3
  13. /* 参数说明:count,count2用于定时器中断计时,flag_1s 用来表示1S时间到,统计NE555的频率
  14. sec: 在定时器2中,用来3S计时,sec=3后,自动退出温湿度显示界面
  15. key_val: 只是用来记录按键,S4按下key_val=4,S5按下key_val=5
  16. flag_100ms:0.1S标志位,指示灯 L40.1 秒为间隔切换亮、灭状态。
  17. show_switching:界面切换,1:时间显示界面,2:回显界面,3:参数显示
  18. collect_flag = 1:处于亮环境标志
  19. show : 0: 温湿度显示界面,1:显示show_switching对应的界面
  20. S5_flag: 回显界面下,切换温度、湿度、时间回显
  21. L4_flag,L5_flag,L6_flag:分别表示LED456的点亮标志位
  22. adc_val:ADC转化后输出值, t_para 温度参数,count_triggle:记录触发数据采集次数
  23. count3,count_sec :用于S9长按2S的计时
  24. temp,humidity : 温度、湿度。 i:范围0-1-2,用于作为t[3],h[3]数组的索引
  25. last_hour,last_min :最近一次采集触发的时间
  26. */
  27. void Timer0Init(void); //@12.000MHz;
  28. void Timer1Init(void); //10毫秒@12.000MHz
  29. void Timer2Init(void); //20毫秒@12.000MHz
  30. void show_switch();
  31. void key_board();
  32. unsigned char max(unsigned char str[]);
  33. void main()
  34. {
  35. SysInit();
  36. WriteDateTo1302(&date);
  37. Timer0Init();
  38. Timer1Init();
  39. Timer2Init();
  40. while(1){ //频率和湿度的转换关系
  41. if(FREQUENTCY<2000 && FREQUENTCY > 200)
  42. humidity = 2/45.0*FREQUENTCY + 1.11;
  43. else if(FREQUENTCY == 2000)
  44. humidity = 90;
  45. else if(FREQUENTCY == 200)
  46. humidity = 10;
  47. else
  48. humidity = 0; //无效数据
  49. adc_val = ADC_Output(0x01);
  50. if( adc_val> 100) collect_flag = 1; //亮,adc_val<100代表暗
  51. if(collect_flag == 1 && adc_val<=100){ //满足条件触发数据测量
  52. collect_flag=0; AUXR |= 0x10; //启动定时器2
  53. show = 1, t[i] = temp;
  54. if(humidity != 0) { h[i] = humidity; L5_flag = 0;}
  55. else{ L5_flag = 1; //采集到无效数据,无效数据不保存,触发LED5
  56. }
  57. count_triggle++;
  58. if( i == 0 && count_triggle>=2){ //本次采集大小与上次对比
  59. if(temp > t[2] && humidity > h[2]) L6_flag = 1;
  60. else L6_flag = 0;
  61. }else L6_flag = 0;
  62. if(i!= 0 && count_triggle>=2) {//本次采集大小与上次对比
  63. if(temp > t[i-1] && humidity > h[i-1]) L6_flag = 1; //温湿度都大于上次,触发LED6
  64. else L6_flag = 0;
  65. }else L6_flag = 0;
  66. i++;
  67. if(i>3) i = 0;
  68. last_hour = date.hour, last_min = date.min;
  69. if(temp > t_para) L4_flag = 1; //采集温度大于温度参数,触发LED4
  70. else L4_flag = 0;
  71. }
  72. key_board(); //按键检测函数
  73. show_switch(); //所有显示放在此函数内,为了使按键按下,不影响显示内容
  74. }
  75. }
  76. void show_switch()
  77. {
  78. unsigned char t_max,h_max;
  79. int t_avr,h_avr;
  80. date = ReadTimeFrom1302();
  81. temp = rd_temperature();
  82. t_max = max(t), h_max = max(h);
  83. t_avr = (t[0]+t[1]+t[2])/3.0 * 10; h_avr = (h[0]+h[1]+h[2])/3.0 * 10;
  84. if(show != 1){
  85. if(show_switching == 1){ //时间显示界面
  86. DisplaySeg(1,date.hour/10); DisplaySeg(2,date.hour%10); DisplaySeg(3,16);
  87. DisplaySeg(4,date.min/10); DisplaySeg(5,date.min%10); DisplaySeg(6,16);
  88. DisplaySeg(7,date.sec/10); DisplaySeg(8,date.sec%10);
  89. }
  90. if(show_switching == 2){ //回显界面,默认温度回显C
  91. switch(S5_flag){ // 温度回显C, 湿度回显H,时间回显F
  92. case 1: DisplaySeg(1,12);
  93. if(count_triggle != 0){
  94. DisplaySeg(3,t_max/10); DisplaySeg(4,t_max%10); //最大温度
  95. DisplaySeg(5,16); DisplaySeg(6,t_avr/100); DisplaySeg_f(7,t_avr%100/10); DisplaySeg(8,t_avr%10);
  96. }
  97. break;
  98. case 2: DisplaySeg(1,17);
  99. if(count_triggle != 0){
  100. DisplaySeg(3,h_max/10); DisplaySeg(4,h_max%10); //最大湿度
  101. DisplaySeg(5,16); DisplaySeg(6,h_avr/100); DisplaySeg_f(7,h_avr%100/10); DisplaySeg(8,h_avr%10);
  102. }
  103. break;
  104. case 3: DisplaySeg(1,15); DisplaySeg(2,count_triggle/10); DisplaySeg(3,count_triggle%10);//触发次数
  105. if(count_triggle != 0){
  106. DisplaySeg(4,last_hour/10); DisplaySeg(5,last_hour%10); //上一次触发的时间
  107. DisplaySeg(6,16); DisplaySeg(7,last_min/10); DisplaySeg(8,last_min%10);
  108. }
  109. break;
  110. }
  111. }
  112. if(show_switching == 3){ //参数设置界面
  113. DisplaySeg(1,18);
  114. DisplaySeg(7,t_para/10); DisplaySeg(8,t_para%10);
  115. }
  116. }else{ //温湿度显示界面,每次显示3S后自动推出
  117. DisplaySeg(1,14); // E
  118. DisplaySeg(4,temp/10); DisplaySeg(5,temp%10); DisplaySeg(6,16); //温度
  119. if(humidity != 0) {
  120. DisplaySeg(7,humidity/10); DisplaySeg(8,humidity%10); //湿度
  121. }else{
  122. DisplaySeg(7,19); DisplaySeg(8,19);
  123. }
  124. }
  125. // LED 显示
  126. switch(show_switching){
  127. case 1: DisplayLed(1,1);DisplayLed(2,0);DisplayLed(3,0); break;
  128. case 2: DisplayLed(2,1);DisplayLed(1,0);DisplayLed(3,0); break;
  129. case 3: DisplayLed(3,1);DisplayLed(1,0);DisplayLed(2,0); break;
  130. }
  131. if(L4_flag == 1){
  132. if(flag_100ms) DisplayLed(4,1); //L4
  133. else DisplayLed(4,0); //L4
  134. }else{
  135. DisplayLed(4,0);
  136. }
  137. if(L5_flag == 1){
  138. DisplayLed(5,1); //L5
  139. }else{
  140. DisplayLed(5,0);//L5
  141. }
  142. if(L6_flag == 1){
  143. DisplayLed(6,1); //L6
  144. }else{
  145. DisplayLed(6,0); //L6
  146. }
  147. }
  148. void key_board()
  149. {
  150. unsigned char key;
  151. P44 = 0, P42 = 1; P3 |= 0x0f;
  152. key = P3; key = key & 0x0c;
  153. if(key != 0x0c){
  154. Delayms(5);
  155. if(key != 0x0c){
  156. switch(key){
  157. case 0x04: key_val = 4; show_switching++; //每次进入回显界面默认是温度回显
  158. if(show_switching > 3) { show_switching = 1 ; S5_flag = 1; }
  159. break;
  160. case 0x08: key_val = 5; if(show_switching == 2) S5_flag++;
  161. if(S5_flag > 3) S5_flag = 1;
  162. break;
  163. }
  164. }
  165. while(key != 0x0c){
  166. key = P3; key = key & 0x0c;
  167. show_switch();
  168. }
  169. }
  170. //第二列按键
  171. P44 = 1, P42 = 0; P3 |= 0x0f;
  172. key = P3; key = key & 0x0c;
  173. if(key != 0x0c){
  174. Delayms(5);
  175. if(key != 0x0c){ // S8++, S9--
  176. switch(key){
  177. case 0x04: key_val = 8; if(show_switching == 3) t_para++;
  178. if(t_para > 99) t_para = 0;
  179. break;
  180. case 0x08: key_val = 9; if(show_switching == 3) t_para--;
  181. if(t_para == 255) t_para = 99;
  182. break;
  183. }
  184. if(S5_flag == 3) { count3 = 0, count_sec = 0;} //时间回显下,S9按下2秒计时开始
  185. }
  186. while(key != 0x0c){
  187. key = P3; key = key & 0x0c;
  188. show_switch();
  189. if(count_sec >= 2 && S5_flag == 3) { //时间回显界面,长按S9两秒,数据清零
  190. memset(t,0,sizeof(t)), memset(h,0,sizeof(h));
  191. count_triggle = 0;
  192. }
  193. }
  194. }
  195. }
  196. void Timer0Init(void) //@12.000MHz
  197. {
  198. AUXR &= 0x7F; //定时器时钟12T模式
  199. TMOD &= 0xF0; //设置定时器模式
  200. TMOD |= 0x04;
  201. TL0 = 0; //设置定时初值
  202. TH0 = 0; //设置定时初值
  203. TF0 = 0; //清除TF0标志
  204. ET0 = 1;
  205. TR0 = 1; //定时器0开始计时
  206. }
  207. void Timer1Init(void) //10毫秒@12.000MHz
  208. {
  209. AUXR &= 0xBF; //定时器时钟12T模式
  210. TMOD &= 0x0F; //设置定时器模式
  211. TL1 = 0xF0; //设置定时初值
  212. TH1 = 0xD8; //设置定时初值
  213. TF1 = 0; //清除TF1标志
  214. TR1 = 1; //定时器1开始计时
  215. ET1 = 1;
  216. EA = 1;
  217. }
  218. void Timer1() interrupt 3
  219. {
  220. count++; count3++;
  221. if(count == 100){
  222. count = 0;
  223. flag_1s = 1;
  224. }
  225. if(count %10 == 0){
  226. flag_100ms = ~flag_100ms;
  227. }
  228. if(flag_1s == 1){
  229. flag_1s = 0; TR0 = 0;
  230. FREQUENTCY = TH0*256 + TL0 ;
  231. TH0 = 0, TL0 = 0;
  232. TR0 = 1;
  233. }
  234. if(count3 == 100) {
  235. count3 = 0;
  236. count_sec++;
  237. }
  238. }
  239. void Timer2Init(void) //20毫秒@12.000MHz
  240. {
  241. AUXR &= 0xFB; //定时器时钟12T模式
  242. T2L = 0xE0; //设置定时初值
  243. T2H = 0xB1; //设置定时初值
  244. // AUXR |= 0x10; //定时器2开始计时
  245. AUXR &= 0xef;
  246. IE2 |= 0x04;
  247. }
  248. void Timer2() interrupt 12
  249. {
  250. count2++;
  251. if(count2 == 50){
  252. count2 = 0;
  253. sec++;
  254. if(sec == 3){
  255. sec = 0;
  256. show = 0;
  257. AUXR &= 0xef; //停止定时器2
  258. }
  259. }
  260. }
  261. //求数组的最大值,这里数组大小固定为3
  262. unsigned char max(unsigned char str[])
  263. {
  264. unsigned char Max = str[0] , i;
  265. for(i=1;i<3;i++){
  266. if( str[i] > Max)
  267. Max = str[i] ;
  268. }
  269. return Max;
  270. }

    3.6 环境配置

           keil5 创建工程,选择芯片型号STC15F2K60S2,将上述.c文件都添加在Source Group 1下进行编译

 编译成功后,0错误,0警告

第14届完整工程代码: 

第14届蓝桥杯省赛程序设计题源码,第14届驱动代码和以往相比发生了一些改变,需要注意,只给除了c文件,头文件需要自己手写资源-CSDN文库

4. 历年蓝桥杯单片机试题和答案

       需要历年程序题客观题试题和答案,可在咸鱼购买,另外需要程序指导也可私信

 闲鱼】https://m.tb.cn/h.UFji1l1?tk=hM4BdnfMkVP CZ0001 「我在闲鱼发布了【蓝桥杯各模块程序驱动代码,历年试题答案,程序无bug。如需程】」
点击链接直接打开

https://m.tb.cn/h.UFji1l1?tk=hM4BdnfMkVP CZ0001

     

 

 

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

闽ICP备14008679号