当前位置:   article > 正文

蓝桥杯单片机组第十四届省赛_csdn蓝桥杯14届省赛单片机

csdn蓝桥杯14届省赛单片机

 1.题目

 本次题目模块较多,难度较大

 

 


2.底层代码

2.1三个常用模块

2.1.1 按键

本次省赛采用了NE555模块,要用P34引脚,在按键底层中,要把P34相关的代码注释掉,并且要将P34引脚用跳线帽(可以用超声波模块的跳线帽)与SIGNAL相连

  1. Key.c
  2. #include <Key.h>
  3. unsigned char Key_Read()
  4. {
  5. unsigned char temp=0;
  6. ET0 = 0;//用于串口优化
  7. P44=0;
  8. P42=1;
  9. P35=1;
  10. //P34=1;
  11. if(P33==0) temp=4;
  12. if(P32==0) temp=5;
  13. if(P31==0) temp=6;
  14. if(P30==0) temp=7;
  15. P44=1;
  16. P42=0;
  17. P35=1;
  18. //P34=1;
  19. if(P33==0) temp=8;
  20. if(P32==0) temp=9;
  21. if(P31==0) temp=10;
  22. if(P30==0) temp=11;
  23. P44=1;
  24. P42=1;
  25. P35=0;
  26. //P34=1;
  27. if(P33==0) temp=12;
  28. if(P32==0) temp=13;
  29. if(P31==0) temp=14;
  30. if(P30==0) temp=15;
  31. //P44=1;
  32. //P42=1;
  33. //P35=1;
  34. //P34=0;
  35. //if(P33==0) temp=12;
  36. //if(P32==0) temp=13;
  37. //if(P31==0) temp=14;
  38. //if(P30==0) temp=15;
  39. ET0 = 1;
  40. P3=0xff;
  41. return temp;
  42. }

2.1.2 数码管 

  1. Seg.c
  2. #include <Seg.h>
  3. code unsigned char Dulu[18]={
  4. 0xc0, //0
  5. 0xf9, //1
  6. 0xa4, //2
  7. 0xb0, //3
  8. 0x99, //4
  9. 0x92, //5
  10. 0x82, //6
  11. 0xf8, //7
  12. 0x80, //8
  13. 0x90, //9
  14. 0xff, //熄灭
  15. 0xbf, //-
  16. 0xc6, //C
  17. 0x89, //H
  18. 0x8e, //F
  19. 0x8c, //P
  20. 0x86, //E
  21. 0x88 //A
  22. };
  23. code unsigned char Wulu[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  24. void Seg_Disp(unsigned char addr,dat,point)
  25. {
  26. //用段选消隐
  27. P0=0xff;
  28. P2=P2&0x1f|0xe0;
  29. P2&=0x1f;
  30. //位选
  31. P0=Wulu[addr];
  32. P2=P2&0x1f|0xc0;
  33. P2&=0x1f;
  34. //段选
  35. P0=Dulu[dat];
  36. if(point)
  37. P0&=0x7f;
  38. P2=P2&0x1f|0xe0;
  39. P2&=0x1f;
  40. }

2.1.3 Led

我使用的是Led灯1亮,0灭的逻辑,所有P0取了一下反

  1. Led.c
  2. #include <Led.h>
  3. void Led_Disp(unsigned char addr,unsigned char flag)
  4. {
  5. static unsigned char temp=0x00;
  6. static unsigned char temp_old=0xff;
  7. if(flag)
  8. temp|=0x01<<addr;
  9. else
  10. temp&=~(0x01<<addr);
  11. if(temp!=temp_old)
  12. {
  13. P0=~temp;
  14. P2=P2&0x1f|0x80;
  15. P2&=0x1f;
  16. temp_old=temp;
  17. }
  18. }

2.1.4 初始化 

关闭了Led和数码管,防止在烧录过程在乱叫

  1. Init.c
  2. #include <Init.h>
  3. void System_Init(void)
  4. {
  5. P0=0xff;
  6. P2=P2&0x1f|0x80;
  7. P2&=0x1f;
  8. P0=0x00;
  9. P2=P2&0x1f|0xa0;
  10. P2&=0x1f;
  11. }

准备工作做好了,接下来我们开始写题目要求的底层代码


2.2 题目要求底层

由于第十四届只提供了.c文件,所有我们需要自己写.h文件

2.2.1 PCF88591

题目中只要求ADC转换,所以我只写了这个部分。

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

2.2.2 DS18B20 

该模块一次只能读取8位,所以要读两次,采用float型数据

  1. onewire.c
  2. /* # 单总线代码片段说明
  3. 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
  4. 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
  5. 中对单片机时钟频率的要求,进行代码调试和修改。
  6. */
  7. #include <onewire.h>
  8. sbit DQ=P1^4;
  9. //
  10. void Delay_OneWire(unsigned int t)
  11. {
  12. unsigned char i;
  13. while(t--){
  14. for(i=0;i<12;i++);
  15. }
  16. }
  17. //
  18. void Write_DS18B20(unsigned char dat)
  19. {
  20. unsigned char i;
  21. for(i=0;i<8;i++)
  22. {
  23. DQ = 0;
  24. DQ = dat&0x01;
  25. Delay_OneWire(5);
  26. DQ = 1;
  27. dat >>= 1;
  28. }
  29. Delay_OneWire(5);
  30. }
  31. //
  32. unsigned char Read_DS18B20(void)
  33. {
  34. unsigned char i;
  35. unsigned char dat;
  36. for(i=0;i<8;i++)
  37. {
  38. DQ = 0;
  39. dat >>= 1;
  40. DQ = 1;
  41. if(DQ)
  42. {
  43. dat |= 0x80;
  44. }
  45. Delay_OneWire(5);
  46. }
  47. return dat;
  48. }
  49. //
  50. bit init_ds18b20(void)
  51. {
  52. bit initflag = 0;
  53. DQ = 1;
  54. Delay_OneWire(12);
  55. DQ = 0;
  56. Delay_OneWire(80);
  57. DQ = 1;
  58. Delay_OneWire(10);
  59. initflag = DQ;
  60. Delay_OneWire(5);
  61. return initflag;
  62. }
  63. //读取温度
  64. float Read_Temperature(void)
  65. {
  66. unsigned char high,low;
  67. init_ds18b20();
  68. Write_DS18B20(0xcc);
  69. Write_DS18B20(0x44);
  70. init_ds18b20();
  71. Write_DS18B20(0xcc);
  72. Write_DS18B20(0xbe);
  73. low=Read_DS18B20();
  74. high=Read_DS18B20();
  75. return ((high<<8)|low)/16.0;
  76. }
  1. onewire.h
  2. #include <STC15F2K60S2.H>
  3. void Delay_OneWire(unsigned int t) ;
  4. void Write_DS18B20(unsigned char dat);
  5. unsigned char Read_DS18B20(void);
  6. bit init_ds18b20(void);
  7. float Read_Temperature(void);

 2.2.3 DS1302

该模块读取数据是16进制,不要忘记数码管表示时除或者取余16

  1. ds1302.c
  2. /* # DS1302代码片段说明
  3. 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
  4. 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
  5. 中对单片机时钟频率的要求,进行代码调试和修改。
  6. */
  7. #include <ds1302.h>
  8. #include <intrins.h>
  9. sbit SCK=P1^7;
  10. sbit SDA=P2^3;
  11. sbit RST=P1^3;
  12. //
  13. void Write_Ds1302(unsigned char temp)
  14. {
  15. unsigned char i;
  16. for (i=0;i<8;i++)
  17. {
  18. SCK = 0;
  19. SDA = temp&0x01;
  20. temp>>=1;
  21. SCK=1;
  22. }
  23. }
  24. //
  25. void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
  26. {
  27. RST=0; _nop_();
  28. SCK=0; _nop_();
  29. RST=1; _nop_();
  30. Write_Ds1302(address);
  31. Write_Ds1302(dat);
  32. RST=0;
  33. }
  34. //
  35. unsigned char Read_Ds1302_Byte ( unsigned char address )
  36. {
  37. unsigned char i,temp=0x00;
  38. RST=0; _nop_();
  39. SCK=0; _nop_();
  40. RST=1; _nop_();
  41. Write_Ds1302(address);
  42. for (i=0;i<8;i++)
  43. {
  44. SCK=0;
  45. temp>>=1;
  46. if(SDA)
  47. temp|=0x80;
  48. SCK=1;
  49. }
  50. RST=0; _nop_();
  51. SCK=0; _nop_();
  52. SCK=1; _nop_();
  53. SDA=0; _nop_();
  54. SDA=1; _nop_();
  55. return (temp);
  56. }
  57. void Set_Rtc(unsigned char *ucRtc)
  58. {
  59. unsigned char i;
  60. Write_Ds1302_Byte(0x8e,0);//关闭写保护
  61. for(i=0;i<3;i++)
  62. Write_Ds1302_Byte(0x84-i*2,ucRtc[i]);
  63. Write_Ds1302_Byte(0x8e,1);//打开写保护
  64. }
  65. void Read_Rtc(unsigned char *ucRtc)
  66. {
  67. unsigned char i;
  68. for(i=0;i<3;i++)
  69. ucRtc[i]=Read_Ds1302_Byte(0x85-i*2);
  70. }
  1. ds1302.h
  2. #include <STC15F2K60S2.H>
  3. void Write_Ds1302(unsigned char temp);
  4. void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
  5. unsigned char Read_Ds1302_Byte ( unsigned char address );
  6. void Set_Rtc(unsigned char *ucRtc);
  7. void Read_Rtc(unsigned char *ucRtc);

2.2.4 NE555 

NE555模块我放在main.c里面写的,采用定时器0,可以用STC烧录工具生成代码

加上一句TMOD|=0x05;就ok了 

  1. //NE555必须使用定时器0 且要加入(TMOD|=0x05;)这段代码
  2. //定时器0初始化
  3. void Timer0Init(void) //0毫秒@12.000MHz
  4. {
  5. AUXR &= 0x7F; //定时器时钟12T模式
  6. TMOD &= 0xF0; //设置定时器模式
  7. TMOD |= 0x05; //设置计时方式
  8. TL0 = 0x00; //设置定时初始值
  9. TH0 = 0x00; //设置定时初始值
  10. TF0 = 0; //清除TF0标志
  11. TR0 = 1; //定时器0开始计时
  12. }

3.main.c文件

3.1 定时器

因为NE555采用定时器0,所以我采用定时器1来计时

  1. /利用STC工具生成后要加入(ET1=1,EA=1)两段代码
  2. //定时器1初始化
  3. void Timer1Init(void) //1毫秒@12.000MHz
  4. {
  5. AUXR &= 0xBF; //定时器时钟12T模式
  6. TMOD &= 0x0F; //设置定时器模式
  7. TL1 = 0x18; //设置定时初始值
  8. TH1 = 0xFC; //设置定时初始值
  9. TF1 = 0; //清除TF1标志
  10. TR1 = 1; //定时器1开始计时
  11. ET1=1;
  12. EA=1;
  13. }
  14. //定时器1
  15. void Timer1Sever(void) interrupt 3
  16. {
  17. if(++Key_Slow==10) Key_Slow=0;
  18. if(++Seg_Slow==500) Seg_Slow=0;
  19. if(++Seg_Pos==8) Seg_Pos=0;
  20. if(++Timer_1000ms==1000)
  21. {
  22. TR0=0;//停止计时
  23. Timer_1000ms=0;
  24. Freq=(TH0<<8)|TL0;
  25. TH0=TL0=0;
  26. TR0=1;//开始计时
  27. }
  28. if(Find_Flag==1)
  29. {
  30. if(++Timer_3000ms==3000)
  31. {
  32. Timer_3000ms=3001;
  33. }
  34. }
  35. if(S9_Flag==1)
  36. {
  37. if(++Timer_2000ms==2000)
  38. Timer_2000ms=2001;
  39. }
  40. else
  41. Timer_2000ms=0;
  42. if(++Timer_1000ms==1000)
  43. {
  44. Timer_1000ms=0;
  45. Led_Star_Flag=!Led_Star_Flag;
  46. }
  47. Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
  48. Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
  49. }

3.2 void main() 

 DS18B20上电后会先显示85,所以要延时750ms,STC生成

对应DS1302模块,要先设置时间

  1. //main()函数
  2. void main()
  3. {
  4. //读取DS18B20要在main()函数里面先读取延时750ms。
  5. Read_Temperature();
  6. Delay750ms();
  7. //读书DS1302的时间要先在main()函数里面先设置。
  8. Set_Rtc(ucRtc);
  9. //用定时器要先初始化
  10. Timer0Init();
  11. Timer1Init();
  12. //板子要先初始化
  13. System_Init();
  14. while(1)
  15. {
  16. Key_Proc();
  17. Seg_Proc();
  18. Led_Proc();
  19. }
  20. }

 3.3 完整代码

  1. main.c
  2. #include <STC15F2K60S2.H>
  3. #include <intrins.h>
  4. #include <iic.h>
  5. #include <onewire.h>
  6. #include <ds1302.h>
  7. #include <Seg.h>
  8. #include <Key.h>
  9. #include <Led.h>
  10. #include <Init.h>
  11. //变量定义区
  12. /*按键*/
  13. unsigned char Key_Slow;//10
  14. unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
  15. /*数码管*/
  16. unsigned int Seg_Slow;//500
  17. unsigned Seg_Pos;
  18. unsigned Seg_Buf[8]={10,10,10,10,10,10,10,10};
  19. unsigned Seg_Point[8]={0,0,0,0,0,0,0,0};
  20. /*Led*/
  21. unsigned ucLed[8]={0,0,0,0,0,0,0,0};
  22. /*自定义变量*/
  23. unsigned char Seg_Disp_Mode;//界面:0-时间,1-回显,2-参数
  24. /*时间界面*/
  25. unsigned char ucRtc[3]={0x13,0x03,0x05};//时-分-秒,写出0x的形式
  26. /*回显界面*/
  27. unsigned char Re_Disp_Mode;//回显:0-温度,1-湿度,2-时间
  28. //温度回显·
  29. unsigned char Max_Temperature;//最大温度
  30. float Aver_Temperature;//平均温度
  31. //湿度回显
  32. unsigned char Max_Humidity;//最大湿度
  33. float Aver_Humidity;//平均湿度
  34. //时间回显
  35. unsigned char trigger_Inedx;//触发次数
  36. unsigned char trigger_Time[3];//触发时间
  37. /*参数界面*/
  38. unsigned char Temperature_Set=30;
  39. /*温湿度界面*/
  40. unsigned int Freq;//实时频率
  41. unsigned int Timer_1000ms;
  42. /*S9长短按*/
  43. unsigned int Timer_2000ms;//用于S9长按
  44. bit S9_Flag;//记录是否按下S9;
  45. /*温湿度界面*/
  46. bit Tem_And_Hum_Flag;//温湿度界面和其他界面的区分标志
  47. unsigned char Temperature_Disp;//温湿度界面的温度
  48. unsigned char Humidity_Disp;//温湿度界面的湿度
  49. unsigned char Temperature_Disp_Old;//上一次温湿度界面的温度
  50. unsigned char Humidity_Disp_Old;//上一次温湿度界面的湿度
  51. bit Error_Humidity;//湿度是否有效
  52. bit Led6_Flag;//判断本次采集的温湿度是否均升高
  53. /*判断是否进入采集*/
  54. bit flag;//判断湿度数据是否有效,有效为0,无效为1;
  55. unsigned char Voltage;
  56. unsigned char Voltage_Old;
  57. unsigned int Timer_3000ms;//3s
  58. bit Find_Flag;
  59. /*报警指示灯*/
  60. bit Led_Star_Flag;//控制亮灭
  61. bit Led_Flag;//表明采集温度大于温度参数的状态
  62. unsigned int Timer_1000ms;//1000ms
  63. //清空数据函数
  64. void Clear_Data(void)
  65. {
  66. unsigned char i=0;
  67. Max_Temperature=0;
  68. Aver_Temperature=0;
  69. Max_Humidity=0;
  70. Aver_Humidity=0;
  71. trigger_Inedx=0;
  72. for(i=0;i<3;i++)
  73. trigger_Time[i]=0;
  74. }
  75. //按键处理函数
  76. void Key_Proc()
  77. {
  78. if(Key_Slow) return;
  79. Key_Slow=1;
  80. Key_Val = Key_Read();
  81. Key_Down = Key_Val & (Key_Old ^ Key_Val);
  82. Key_Up = ~ Key_Val & (Key_Old ^ Key_Val);
  83. Key_Old = Key_Val;
  84. //时间回显界面
  85. if(Re_Disp_Mode==2&&Seg_Disp_Mode==1)
  86. {
  87. if(Key_Down==9)
  88. S9_Flag=1;//开始计时
  89. if(Key_Up==9)//S9抬起
  90. {
  91. if(Timer_2000ms>=2000&&S9_Flag==1)
  92. {
  93. Clear_Data();
  94. S9_Flag=0;//停止计时
  95. }
  96. else
  97. S9_Flag=0;//停止计时
  98. }
  99. }
  100. switch(Key_Down)
  101. {
  102. case 4:
  103. if(++Seg_Disp_Mode==3)
  104. Seg_Disp_Mode=0;
  105. Re_Disp_Mode=0;
  106. break;
  107. case 5:
  108. if(Seg_Disp_Mode==1)
  109. {
  110. if(++Re_Disp_Mode==3)
  111. Re_Disp_Mode=0;
  112. }
  113. break;
  114. case 8:
  115. if(Seg_Disp_Mode==2)
  116. {
  117. if(++Temperature_Set==100)
  118. Temperature_Set=99;
  119. }
  120. break;
  121. case 9:
  122. //参数界面
  123. if(Seg_Disp_Mode==2)
  124. {
  125. if(--Temperature_Set==255)
  126. Temperature_Set=0;
  127. }
  128. break;
  129. }
  130. }
  131. //湿度处理函数
  132. bit Read_Humidity(void)
  133. {
  134. if(Freq<200||Freq>2000)
  135. Error_Humidity=0;//无效数据
  136. else
  137. {
  138. Error_Humidity=1;
  139. Humidity_Disp=(unsigned char)(2/45*(Freq-200)+10);
  140. }
  141. return Error_Humidity;
  142. }
  143. //清除数码管
  144. void Clear_Seg(void)
  145. {
  146. unsigned char i;
  147. for(i=0;i<8;i++)
  148. {
  149. Seg_Buf[i]=10;
  150. Seg_Point[i]=0;
  151. }
  152. }
  153. //信息处理函数
  154. void Seg_Proc()
  155. {
  156. unsigned char i;
  157. if(Seg_Slow) return;
  158. Seg_Slow=1;
  159. Read_Rtc(ucRtc);
  160. Temperature_Disp=(unsigned char)Read_Temperature();
  161. //判断是否进入温湿度界面
  162. Voltage=AD_Read(0x41);
  163. //由亮到暗,避免重复进入
  164. if((Voltage_Old>50&&Voltage<50)&&Tem_And_Hum_Flag==0)
  165. {
  166. Find_Flag=1;//开始计时
  167. Tem_And_Hum_Flag=1;
  168. if(Read_Humidity()==1)
  169. {
  170. if(++trigger_Inedx==100) trigger_Inedx=99;
  171. for(i=0;i<3;i++)
  172. trigger_Time[i]=ucRtc[i];
  173. }
  174. }
  175. //是否间隔3s
  176. else if(Tem_And_Hum_Flag==1&&Timer_3000ms>=3000)
  177. {
  178. Find_Flag=0;//停止计时·
  179. Timer_3000ms=0;
  180. Tem_And_Hum_Flag=0;
  181. }
  182. Voltage_Old=Voltage;
  183. //处于温湿度界面
  184. if(Tem_And_Hum_Flag==1)
  185. {
  186. Seg_Buf[0]=16;//E
  187. Seg_Buf[1]=Seg_Buf[2]=10;//熄灭
  188. Seg_Buf[3]=Temperature_Disp/10;
  189. Seg_Buf[4]=Temperature_Disp%10;
  190. Seg_Point[6]=0;
  191. if(Temperature_Disp>Temperature_Set)
  192. Led_Flag=1;
  193. else
  194. Led_Flag=0;
  195. /*用于读取最大温度,平均温度*/
  196. Max_Temperature=(Max_Temperature>Temperature_Disp)?Max_Temperature:Temperature_Disp;
  197. //平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
  198. Aver_Temperature=((trigger_Inedx-1)*Aver_Temperature+Temperature_Disp)/trigger_Inedx;
  199. Seg_Buf[5]=11;//-
  200. //采集有效
  201. if(Error_Humidity==1)
  202. {
  203. flag=0;//进行了温湿度采集,且采集有效
  204. Seg_Buf[6]=Humidity_Disp/10;
  205. Seg_Buf[7]=Humidity_Disp%10;
  206. /*用于读取最大温度,平均温度*/
  207. Max_Humidity=(Max_Humidity>Humidity_Disp)?Max_Humidity:Humidity_Disp;
  208. //平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
  209. Aver_Humidity=((trigger_Inedx-1)*Aver_Humidity+Humidity_Disp)/trigger_Inedx;
  210. if(trigger_Inedx>=2)
  211. {
  212. Led6_Flag=(Temperature_Disp>Temperature_Disp_Old)&(Humidity_Disp>Humidity_Disp_Old);
  213. Temperature_Disp_Old=Temperature_Disp;
  214. Humidity_Disp_Old=Humidity_Disp;
  215. }
  216. }
  217. else
  218. {
  219. flag=1;//进行了温湿度采集,且采集有效
  220. Seg_Buf[6]=Seg_Buf[7]=17;//A
  221. }
  222. }
  223. else
  224. {
  225. switch(Seg_Disp_Mode)
  226. {
  227. //时间
  228. case 0:
  229. Seg_Buf[0]=ucRtc[0]/16;
  230. Seg_Buf[1]=ucRtc[0]%16;
  231. Seg_Buf[2]=11;//-
  232. Seg_Buf[3]=ucRtc[1]/16;
  233. Seg_Buf[4]=ucRtc[1]%16;
  234. Seg_Buf[5]=11;//-
  235. Seg_Buf[6]=ucRtc[2]/16;
  236. Seg_Buf[7]=ucRtc[2]%16;
  237. Seg_Point[6]=0;
  238. break;
  239. //回显
  240. case 1:
  241. switch(Re_Disp_Mode)
  242. {
  243. //温度
  244. case 0:
  245. if(trigger_Inedx==0)
  246. Clear_Seg();
  247. Seg_Buf[0]=12;//C
  248. Seg_Buf[1]=10;//熄灭
  249. if(trigger_Inedx>0)
  250. {
  251. Seg_Buf[2]=Max_Temperature/10;
  252. Seg_Buf[3]=Max_Temperature%10;
  253. Seg_Buf[4]=11;//-
  254. Seg_Buf[5]=(unsigned char)Aver_Temperature/10;
  255. Seg_Buf[6]=(unsigned char)Aver_Temperature%10;
  256. Seg_Buf[7]=(unsigned int)(Aver_Temperature*100)%10;
  257. Seg_Point[6]=1;
  258. }
  259. break;
  260. //湿度
  261. case 1:
  262. if(trigger_Inedx==0)
  263. Clear_Seg();
  264. Seg_Buf[0]=13;//H
  265. Seg_Buf[1]=10;//熄灭
  266. if(trigger_Inedx>0)
  267. {
  268. Seg_Buf[2]=Max_Humidity/10;
  269. Seg_Buf[3]=Max_Humidity%10;
  270. Seg_Buf[4]=11;//-
  271. Seg_Buf[5]=(unsigned char)Aver_Humidity/10;
  272. Seg_Buf[6]=(unsigned char)Aver_Humidity%10;
  273. Seg_Buf[7]=(unsigned int)(Aver_Humidity*100)%10;
  274. Seg_Point[6]=1;
  275. }
  276. break;
  277. //时间
  278. case 2:
  279. if(trigger_Inedx==0)
  280. Clear_Seg();
  281. Seg_Buf[0]=14;//F
  282. Seg_Buf[1]=trigger_Inedx/10;
  283. Seg_Buf[2]=trigger_Inedx%10;
  284. if(trigger_Inedx>0)
  285. {
  286. Seg_Buf[3]=trigger_Time[0]/16;
  287. Seg_Buf[4]=trigger_Time[0]%16;
  288. Seg_Buf[5]=11;//-
  289. Seg_Buf[6]=trigger_Time[1]/16;
  290. Seg_Buf[7]=trigger_Time[1]%16;
  291. Seg_Point[6]=0;
  292. }
  293. break;
  294. }
  295. break;
  296. //参数
  297. case 2:
  298. Seg_Buf[0]=15;//P
  299. Seg_Buf[1]=Seg_Buf[2]=Seg_Buf[3]=Seg_Buf[4]=Seg_Buf[5]=10;//熄灭
  300. Seg_Buf[6]=Temperature_Set/10;
  301. Seg_Buf[7]=Temperature_Set%10;
  302. Seg_Point[6]=0;
  303. break;
  304. }
  305. }
  306. }
  307. //其他处理函数
  308. void Led_Proc()
  309. {
  310. unsigned char i;
  311. for(i=0;i<2;i++)
  312. ucLed[i]=(i==Seg_Disp_Mode);
  313. ucLed[2]=Tem_And_Hum_Flag;
  314. ucLed[3]=(Led_Star_Flag&Led_Flag);
  315. ucLed[4]=flag;
  316. ucLed[5]=Led6_Flag;
  317. }
  318. //NE555必须使用定时器0 且要加入(TMOD|=0x05;)这段代码
  319. //定时器0初始化
  320. void Timer0Init(void) //0毫秒@12.000MHz
  321. {
  322. AUXR &= 0x7F; //定时器时钟12T模式
  323. TMOD &= 0xF0; //设置定时器模式
  324. TMOD |= 0x05; //设置计时方式
  325. TL0 = 0x00; //设置定时初始值
  326. TH0 = 0x00; //设置定时初始值
  327. TF0 = 0; //清除TF0标志
  328. TR0 = 1; //定时器0开始计时
  329. }
  330. //利用STC工具生成后要加入(ET1=1,EA=1)两段代码
  331. //定时器1初始化
  332. void Timer1Init(void) //1毫秒@12.000MHz
  333. {
  334. AUXR &= 0xBF; //定时器时钟12T模式
  335. TMOD &= 0x0F; //设置定时器模式
  336. TL1 = 0x18; //设置定时初始值
  337. TH1 = 0xFC; //设置定时初始值
  338. TF1 = 0; //清除TF1标志
  339. TR1 = 1; //定时器1开始计时
  340. ET1=1;
  341. EA=1;
  342. }
  343. //定时器1
  344. void Timer1Sever(void) interrupt 3
  345. {
  346. if(++Key_Slow==10) Key_Slow=0;
  347. if(++Seg_Slow==500) Seg_Slow=0;
  348. if(++Seg_Pos==8) Seg_Pos=0;
  349. if(++Timer_1000ms==1000)
  350. {
  351. TR0=0;//停止计时
  352. Timer_1000ms=0;
  353. Freq=(TH0<<8)|TL0;
  354. TH0=TL0=0;
  355. TR0=1;//开始计时
  356. }
  357. if(Find_Flag==1)
  358. {
  359. if(++Timer_3000ms==3000)
  360. {
  361. Timer_3000ms=3001;
  362. }
  363. }
  364. if(S9_Flag==1)
  365. {
  366. if(++Timer_2000ms==2000)
  367. Timer_2000ms=2001;
  368. }
  369. else
  370. Timer_2000ms=0;
  371. if(++Timer_1000ms==1000)
  372. {
  373. Timer_1000ms=0;
  374. Led_Star_Flag=!Led_Star_Flag;
  375. }
  376. Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
  377. Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
  378. }
  379. void Delay750ms() //@12.000MHz
  380. {
  381. unsigned char i, j, k;
  382. _nop_();
  383. _nop_();
  384. i = 35;
  385. j = 51;
  386. k = 182;
  387. do
  388. {
  389. do
  390. {
  391. while (--k);
  392. } while (--j);
  393. } while (--i);
  394. }
  395. //main()函数
  396. void main()
  397. {
  398. //读取DS18B20要在main()函数里面先读取延时750ms。
  399. Read_Temperature();
  400. Delay750ms();
  401. //读书DS1302的时间要先在main()函数里面先设置。
  402. Set_Rtc(ucRtc);
  403. //用定时器要先初始化
  404. Timer0Init();
  405. Timer1Init();
  406. //板子要先初始化
  407. System_Init();
  408. while(1)
  409. {
  410. Key_Proc();
  411. Seg_Proc();
  412. Led_Proc();
  413. }
  414. }

 4.结束语

我是初学者,可能有些BUG,希望大家可以指出了。 

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

闽ICP备14008679号