css3做的网站/友好链接

css3做的网站,友好链接,免费网站如何做宣传,经营网站需要什么资质什么?4T模拟赛和省赛做起来轻轻松松?不妨来挑战一下第十一届国赛,这一届的国赛居然没考超声波、串口通信!只要你正确地理解了题目的意思,规避出题人挖的坑,拿个国一轻轻松松。 附件:第十一届蓝桥…

什么?4T模拟赛和省赛做起来轻轻松松?不妨来挑战一下第十一届国赛,这一届的国赛居然没考超声波、串口通信!只要你正确地理解了题目的意思,规避出题人挖的坑,拿个国一轻轻松松。

附件:第十一届蓝桥杯单片机国赛
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、题目分析以及底层代码搭建

1.内存空间不足

看完一遍题目,感觉挺正常的,不知道哪里有坑,其实,在开头的硬件框图中,出题人已经告诉了你本题最大的坑就是存储空间不够。在备赛专栏前篇中有提到,如果你定义变量的时候没有加上存储区修饰符时,该变量的存储区修饰符默认是xdate型的,xdata 变量存储在单片机的外部RAM中,访问速度最慢,并且默认值通常不为0。
所以如果你没有指定存储区修饰符,会导致以下结果:

  • 对于需要频繁使用的变量(比如定时器、Led、Seg相关变量),访问速度一旦慢就会导致时序不精确、程序性能下降,一个程序使用很多需要频繁访问的变量时会导致程序运行到某一部分时程序崩溃,你如果做过跟串口通信有关的题目就对此深有体会了吧,串口数据缓存区会时不时的恶心你一下。
  • 编译时提示错误,如code size exceeds available memory,烧录时失败,提示存储空间不足。

解决方法:

  • 减少xdate的使用,多使用pdateidate
  • 对于程序中不会更改的常量前缀加上code
  • 减少float型变量的使用

2.隐藏条件

在这里插入图片描述
其他要求的第四点指出:参数在参数设置时不生效,所以进行参数设置的时候,要再定义一个新的变量存放参数原来的值进行更改数值。

3.初始化底层代码

  • Init.h
#ifndef __Init_H__
#define __Init_H__void SystemInit();#endif
  • Init.c
#include <STC15F2K60S2.H>void SystemInit()
{P0 = 0xff;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;P0 = 0x00;P2 = P2 & 0x1f | 0xa0;P2 &= 0x1f;
}

4.Led底层代码

  • Led.h
#ifndef __Led_H__
#define __Led_H__void LedDisp(unsigned char *ucLed);#endif
  • Led.c
#include <STC15F2K60S2.H>void LedDisp(unsigned char *ucLed)
{unsigned char i, temp = 0x00;static unsigned char temp_old = 0xff;for(i = 0; i < 8; i++)temp |= (ucLed[i] << i);if(temp_old != temp){P0 = ~temp;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;temp_old = temp;}
}

5.Key底层代码

  • Key.h
#ifndef __Key_H__
#define __Key_H__unsigned char KeyDisp();#endif
  • Key.c
#include <STC15F2K60S2.H>unsigned char KeyDisp()
{unsigned char temp = 0;P44 = 0;P42 = 1;P35 = 1;P34 = 1;if(P32 == 0) temp = 5;if(P33 == 0) temp = 4;P44 = 1;P42 = 0;P35 = 1;P34 = 1;if(P32 == 0) temp = 9;if(P33 == 0) temp = 8;return temp;
}

6.Seg底层代码

  • Seg.h
#ifndef __Seg_H__
#define __Seg_H__void SegDisp(unsigned char wela, unsigned char dula, unsigned char point);#endif
  • Seg.c
#include <STC15F2K60S2.H>code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //空
0xbf, //-
0x8e, //F
0x89, //H
0x9a  //S
};void SegDisp(unsigned char wela, unsigned char dula, unsigned char point)
{P0 = 0xff;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;P0 = (0x01 << wela);P2 = P2 & 0x1f | 0xc0;P2 &= 0x1f;P0 = Seg_Table[dula];if(point)P0 &= 0x7f;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;
}

7.ds1302底层代码

  • ds1302.h
#ifndef __ds1302_H__
#define __ds1302_H__void SetRtc(unsigned char *Rtc);
void GetRtc(unsigned char *Rtc);#endif
  • ds1302.c
#include <STC15F2K60S2.H>
#include <intrins.h>sbit SCK = P1^7;
sbit RST = P1^3;
sbit SDA = P2^3;void Write_Ds1302(unsigned  char temp) 
{unsigned char i;for (i=0;i<8;i++)     	{ SCK = 0;SDA = temp&0x01;temp>>=1; SCK=1;}
}   void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{RST=0;	_nop_();SCK=0;	_nop_();RST=1; 	_nop_();  Write_Ds1302(address);	Write_Ds1302(dat);		RST=0; 
}unsigned char Read_Ds1302_Byte ( unsigned char address )
{unsigned char i,temp=0x00;RST=0;	_nop_();SCK=0;	_nop_();RST=1;	_nop_();Write_Ds1302(address);for (i=0;i<8;i++) 	{		SCK=0;temp>>=1;	if(SDA)temp|=0x80;	SCK=1;} RST=0;	_nop_();SCK=0;	_nop_();SCK=1;	_nop_();SDA=0;	_nop_();SDA=1;	_nop_();return (temp);			
}code unsigned char DS1302_Arr[4] = {0x84,0x82,0x80,0x8E};void SetRtc(unsigned char *Rtc)
{unsigned char i;Write_Ds1302_Byte(DS1302_Arr[3],0x00);for(i = 0; i < 3; i++)Write_Ds1302_Byte(DS1302_Arr[i],Rtc[i]);Write_Ds1302_Byte(DS1302_Arr[3],0x80);
}void GetRtc(unsigned char *Rtc)
{unsigned char i;for(i = 0; i < 3; i++)Rtc[i] = Read_Ds1302_Byte(DS1302_Arr[i]+1);
}

8.ds18b20底层代码

  • ds18b20.h
#ifndef __ds18b20_H__
#define __ds18b20_H__float TemRead();#endif
  • ds18b20.c
#include <STC15F2K60S2.H>sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)  
{unsigned char i;while(t--){for(i=0;i<12;i++);}
}//
void Write_DS18B20(unsigned char dat)
{unsigned char i;for(i=0;i<8;i++){DQ = 0;DQ = dat&0x01;Delay_OneWire(5);DQ = 1;dat >>= 1;}Delay_OneWire(5);
}//
unsigned char Read_DS18B20(void)
{unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;if(DQ){dat |= 0x80;}	    Delay_OneWire(5);}return dat;
}//
bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}float TemRead()
{idata unsigned char TL, TH;init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0x44);init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0xbe);TL = Read_DS18B20();TH = Read_DS18B20();return ((TH << 8) | TL) / 16.0;
}

9.iic底层代码

  • iic.h
#ifndef __iic_H__
#define __iic_H__unsigned char AverageFilter();#endif
  • iic.c
#include <STC15F2K60S2.H>
#include <intrins.h>#define DELAY_TIME	5sbit scl = P2^0;
sbit sda = P2^1;static void I2C_Delay(unsigned char n)
{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();		}while(n--);      	
}void I2CStart(void)
{sda = 1;scl = 1;I2C_Delay(DELAY_TIME);sda = 0;I2C_Delay(DELAY_TIME);scl = 0;    
}//
void I2CStop(void)
{sda = 0;scl = 1;I2C_Delay(DELAY_TIME);sda = 1;I2C_Delay(DELAY_TIME);
}//
void I2CSendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){scl = 0;I2C_Delay(DELAY_TIME);if(byt & 0x80){sda = 1;}else{sda = 0;}I2C_Delay(DELAY_TIME);scl = 1;byt <<= 1;I2C_Delay(DELAY_TIME);}scl = 0;  
}//
unsigned char I2CReceiveByte(void)
{unsigned char da;unsigned char i;for(i=0;i<8;i++){   scl = 1;I2C_Delay(DELAY_TIME);da <<= 1;if(sda) da |= 0x01;scl = 0;I2C_Delay(DELAY_TIME);}return da;    
}//
unsigned char I2CWaitAck(void)
{unsigned char ackbit;scl = 1;I2C_Delay(DELAY_TIME);ackbit = sda; scl = 0;I2C_Delay(DELAY_TIME);return ackbit;
}//
void I2CSendAck(unsigned char ackbit)
{scl = 0;sda = ackbit; I2C_Delay(DELAY_TIME);scl = 1;I2C_Delay(DELAY_TIME);scl = 0; sda = 1;I2C_Delay(DELAY_TIME);
}unsigned char Ad()
{unsigned char temp;I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x01);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return temp;
}unsigned char AverageFilter() 
{unsigned char i;unsigned int sum = 0;for (i = 0; i < 10; i++) {sum += Ad();// 多次采样}return (unsigned char)(sum / 10);  
}

10.main.c

使用下面这个模板做省赛题是可以的,做国赛题就有点难受了,但是指定了存储区修饰符还是可以做的,如果你学过计算机操作系统或者嵌入式操作系统,可以试着用调度器来更改以下代码。

#include <STC15F2K60S2.H>
#include "Init.h"
#include "LED.h"
#include "Key.h"
#include "Seg.h"
#include "ds1302.h"
#include "ds18b20.h"
#include "iic.h"/* 变量声明区 */
unsigned char Key_Slow; //按键减速变量 10ms 
unsigned char Key_Val, Key_Down, Key_Up, Key_Old; //按键检测四件套
unsigned int Seg_Slow; //数码管减速变量 500ms
unsigned char Seg_Buf[] = {10,10,10,10,10,10,10,10,10,10};//数码管缓存数组
unsigned char Seg_Pos;//数码管缓存数组专用索引
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点使能数组
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//LED显示数据存放数组
unsigned int Time_1s, f;/* 按键处理函数 */
void Key_Proc()
{if(Key_Slow) return;Key_Slow = 1; //按键减速Key_Val = Key();Key_Down = Key_Val & ~Key_Old;	 Key_Up = ~Key_Val & Key_Old;Key_Old = Key_Val;}/* 信息处理函数 */
void Seg_Proc()
{if(Seg_Slow) return;Seg_Slow = 1; //数码管减速}/* 其他显示函数 */
void Led_Proc()
{}/* 定时器0只用于计数 */
void Timer0_Init(void)		//1毫秒@12.000MHz
{TMOD &= 0xF0;			//设置定时器模式TMOD |= 0x05;TL0 = 0;				//设置定时初始值TH0 = 0;				//设置定时初始值TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时
}/* 定时器1用于计时 */
void Timer1_Init(void)		//1毫秒@12.000MHz
{AUXR &= 0xBF;			//定时器时钟12T模式TMOD &= 0x0F;			//设置定时器模式TL1 = 0x18;				//设置定时初始值TH1 = 0xFC;				//设置定时初始值TF1 = 0;				//清除TF1标志TR1 = 1;				//定时器1开始计时ET1 = 1;EA = 1;
}/* 定时器1中断服务函数 */
void Timer1_Server() interrupt 3
{if(++Key_Slow == 10) Key_Slow = 0; //按键延迟if(++Seg_Slow == 100) Seg_Slow = 0; //数码管延迟if(++Seg_Pos == 8) Seg_Pos = 0;	   //数码管显示Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);LED_Disp(Seg_Pos,ucLed[Seg_Pos]);/* NE555 */if(++Time_1s == 1000){Time_1s = 0;f = (TH0 << 8) | TL0;TH0 = TL0 = 0;}
}void main()
{Init();Timer0_Init();Timer1_Init();while(1){Key_Proc(); Seg_Proc();Led_Proc();}
}

二、数码管模块

1.代码框架构建

在这里插入图片描述
在这里插入图片描述
可以定义bit MainMode来控制主页面(0-数据页面 1-参数页面),在数据页面中使用unsigned char SegMode来控制显示页面(0-时间显示 1-温度显示 2-亮暗状态),在参数页面中使用unsigned char SetMode来控制显示页面(0-时间参数 1-温度参数 2-指示灯参数)。
可以得到以下伪代码:

typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long int u32;/* 界面参数 */  
idata bit MainMode;			  //主界面 0-数据界面 1-参数界面
idata u8 SegMode; 		  	//数据界面分界面 0-时间 1-温度 2-亮暗状态
idata u8 SetMode;         //参数界面分界面 0-时间参数 1-温度参数 2-指示灯参数void SegProc()
{if(!MainMode)//数据界面{switch(SegMode){case 0://时间显示页面//...break;case 1://温度显示页面//...break;case 2://亮暗状态显示页面//...break;}}else//参数界面{switch(SetMode){case 0://时间参数//...break;case 1://温度参数//...break;case 2://指示灯参数//...break;}}
}void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyDown = ~KeyVal & KeyOld;KeyOld = KeyVal;switch(KeyDown){case 4:MainMode = !MainMode;break;case 5:if(!MainMode)//数据界面{SegMode++;if(SegMode == 3)SegMode = 0;}else//参数界面{SetMode++;if(SetMode == 3)SetMode = 0;}break;}
}

2.数据页面

在这里插入图片描述
时间显示页面和温度显示页面都很容易实现,这边不使用float型变量去接收实时温度读取函数的返回值,而是使用unsigned int类型变量去接收实时温度读取函数的返回值放大10倍的值。
也可以在数码管函数内直接处理温度读取和时钟读取,但是可能数码管函数返回时有任务没做完,最好是分成多个处理函数分别处理对应的任务。

/* 温度 */
idata u16 Tem_10x;        //温度读取放大10倍
/* 时间 */
pdata u8 Rtc[3] = {0x16,0x59,0x50};void DS18B20Proc()
{Tem_10x = TemRead() * 10;
}void DS1302Proc()
{GetRtc(Rtc);
}void SegProc()
{unsigned char i;if(!MainMode)//数据界面{switch(SegMode){case 0:SegPoint[2] = 0;SegBuf[2] = SegBuf[5] = 11;for(i = 0; i < 3; i++){SegBuf[3*i] = Rtc[i] / 16;SegBuf[3*i+1] = Rtc[i] % 16;}break;case 1:SegBuf[0] = 12;SegBuf[1] = SegBuf[2] = SegBuf[3] = SegBuf[4] = 10;SegBuf[5] = Tem_10x / 100;SegBuf[6] = Tem_10x / 10 % 10;SegBuf[7] = Tem_10x % 10;SegPoint[6] = 1;break;}}
}			void main()
{SystemInit();Timer0_Init();SetRtc(Rtc);//上电时设置当前时间while(1){//...}
}

在这里插入图片描述
判断电压低于多少时为遮光状态,这个数值是需要你根据板子上的情况进行判断的,先假设一个数值为遮光临界值,然后用夹逼法慢慢求出最接近遮光状态的数值,一般来说,电压低于1V为遮光状态。
同样的,为了避免使用float型变量,下面也是使用unsigned int型变量接受光敏电阻的电压放大100倍后的电压值。

/* AD */
idata u16 RD1_100x;       //光敏电阻电压放大100倍
idata bit DarkFlag;       //环境为暗检测标志位 0-亮 1-暗void ADProc()
{RD1_100x = AverageFilter() / 51.0 * 100;DarkFlag = (RD1_100x < 100) ? 1 : 0;
}void SegProc()
{unsigned char i;if(!MainMode)//数据界面{switch(SegMode){case 0://...break;case 1://...break;case 2:SegBuf[0] = 13;SegBuf[1] = 10;SegBuf[2] = RD1_100x / 100;SegBuf[3] = RD1_100x / 10 % 10;SegBuf[4] = RD1_100x % 10;SegBuf[5] = 10;SegBuf[6] = 10;SegBuf[7] = DarkFlag;SegPoint[2] = 1;SegPoint[6] = 0;break;}}
}

3.参数页面

在这里插入图片描述
在这里插入图片描述
参数界面的实现是很容易的,这边注意的是参数在退出时才生效,所以每个参数都要再定义一个新的参数接收原始值。
在这里插入图片描述

/* 温度 */
idata u16 Tem_10x;        //温度读取放大10倍
idata u8 TemSet = 25;     //温度参数,默认值25,范围00~99
idata u8 TemSetDis = 25;  //温度参数在修改过程中的值
/* 时间 */
pdata u8 Rtc[3] = {0x16,0x59,0x50};
idata u8 HourSet = 17;    //小时参数,默认值17,范围00~23	
idata u8 HourSetDis = 17; //小时参数在修改过程中的值
/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long int u32;/* 界面参数 */  
idata bit MainMode;			  //主界面 0-数据界面 1-参数界面
idata u8 SegMode; 		  	//数据界面分界面 0-时间 1-温度 2-亮暗状态
idata u8 SetMode;         //参数界面分界面 0-时间参数 1-温度参数 2-指示灯参数
/* AD */
idata u16 RD1_100x;       //光敏电阻电压放大100倍
idata bit DarkFlag;       //环境为暗检测标志位 0-亮 1-暗
/* 温度 */
idata u16 Tem_10x;        //温度读取放大10倍
idata u8 TemSet = 25;     //温度参数,默认值25,范围00~99
idata u8 TemSetDis = 25;  //温度参数在修改过程中的值
/* 时间 */
pdata u8 Rtc[3] = {0x16,0x59,0x50};
idata u8 HourSet = 17;    //小时参数,默认值17,范围00~23	
idata u8 HourSetDis = 17; //小时参数在修改过程中的值
/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
/* 数码管 */
idata u8 SegPos;
pdata u8 SegBuf[8] = {10,10,10,10,10,10,10,10};
pdata u8 SegPoint[8] = {0,0,0,0,0,0,0,0};void DS18B20Proc()
{Tem_10x = TemRead() * 10;
}void DS1302Proc()
{GetRtc(Rtc);
}void ADProc()
{RD1_100x = AverageFilter() / 51.0 * 100;DarkFlag = (RD1_100x < 100) ? 1 : 0;
}void SegProc()
{unsigned char i;if(!MainMode)//数据界面{//...}else//参数界面{switch(SetMode){case 0:SegPoint[2] = SegPoint[6] = 0;SegBuf[0] = 13;SegBuf[1] = 4;SegBuf[2] = 10;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = 10;SegBuf[6] = (HourSetDis / 10) ? HourSetDis / 10 : 10;SegBuf[7] = HourSetDis % 10;break;case 1:SegBuf[0] = 13;SegBuf[1] = 5;SegBuf[6] = (TemSetDis / 10) ? TemSetDis / 10 : 10;SegBuf[7] = TemSetDis % 10;break;case 2:SegBuf[0] = 13;SegBuf[1] = 6;SegBuf[6] = 10;SegBuf[7] = LedSetDis;break;}}
}

4.数码管完整代码

void SegProc()
{unsigned char i;if(!MainMode)//数据界面{switch(SegMode){case 0:SegPoint[2] = 0;SegBuf[2] = SegBuf[5] = 11;for(i = 0; i < 3; i++){SegBuf[3*i] = Rtc[i] / 16;SegBuf[3*i+1] = Rtc[i] % 16;}break;case 1:SegBuf[0] = 12;SegBuf[1] = SegBuf[2] = SegBuf[3] = SegBuf[4] = 10;SegBuf[5] = Tem_10x / 100;SegBuf[6] = Tem_10x / 10 % 10;SegBuf[7] = Tem_10x % 10;SegPoint[6] = 1;break;case 2:SegBuf[0] = 13;SegBuf[1] = 10;SegBuf[2] = RD1_100x / 100;SegBuf[3] = RD1_100x / 10 % 10;SegBuf[4] = RD1_100x % 10;SegBuf[5] = 10;SegBuf[6] = 10;SegBuf[7] = DarkFlag;SegPoint[2] = 1;SegPoint[6] = 0;break;}}else//参数界面{switch(SetMode){case 0:SegPoint[2] = SegPoint[6] = 0;SegBuf[0] = 13;SegBuf[1] = 4;SegBuf[2] = 10;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = 10;SegBuf[6] = (HourSetDis / 10) ? HourSetDis / 10 : 10;SegBuf[7] = HourSetDis % 10;break;case 1:SegBuf[0] = 13;SegBuf[1] = 5;SegBuf[6] = (TemSetDis / 10) ? TemSetDis / 10 : 10;SegBuf[7] = TemSetDis % 10;break;case 2:SegBuf[0] = 13;SegBuf[1] = 6;SegBuf[6] = 10;SegBuf[7] = LedSetDis;break;}}
}

三、按键模块

在这里插入图片描述
S4和S5已经在数码管模块中说过了,这边需要注意的是切换主页面进入的是对应主页面的第一个页面。
在这里插入图片描述
S8和S9的实现也是很简单的,只需要注意每一个参数的初始值和边界值就可以了。
在这里插入图片描述

/* LED */
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
/* 温度 */
idata u16 Tem_10x;        //温度读取放大10倍
idata u8 TemSet = 25;     //温度参数,默认值25,范围00~99
idata u8 TemSetDis = 25;  //温度参数在修改过程中的值
/* 时间 */
pdata u8 Rtc[3] = {0x16,0x59,0x50};
idata u8 HourSet = 17;    //小时参数,默认值17,范围00~23	
idata u8 HourSetDis = 17; //小时参数在修改过程中的值
/* 按键 */
idata u8 KeyVal,KeyDown,KeyUp,KeyOld;void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyDown = ~KeyVal & KeyOld;KeyOld = KeyVal;switch(KeyDown){case 4:if(!MainMode){TemSetDis = TemSet;HourSetDis = HourSet;LedSetDis = LedSet;MainMode = 1;SetMode = 0;}else{TemSet = TemSetDis;HourSet = HourSetDis;LedSet = LedSetDis;MainMode = 0;SegMode = 0;}break;case 5:if(!MainMode)//数据界面{SegMode++;if(SegMode == 3)SegMode = 0;}else//参数界面{SetMode++;if(SetMode == 3)SetMode = 0;}break;case 8://减按键if(MainMode){if(SetMode == 0){if(--HourSetDis == 255)HourSetDis = 0;}else if(SetMode == 1){if(--TemSetDis == 255)TemSetDis = 0;}else{if(--LedSetDis == 3)LedSetDis = 4;}}break;case 9://加按键if(MainMode){if(SetMode == 0){if(++HourSetDis == 24)HourSetDis = 23;}else if(SetMode == 1){if(++TemSetDis == 100)TemSetDis = 99;}else{if(++LedSetDis == 9)LedSetDis = 8;}}break;}
}

四、Led模块

在这里插入图片描述

/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
idata bit L1Light;        //指示灯L1点亮标志位 0灭 1亮
idata bit L2Light;        //指示灯L2点亮标志位 0灭 1亮
idata bit L3Light;        //指示灯L3点亮标志位 0灭 1亮
idata u16 Time_3s;        //暗环境计时变量
idata u16 Time_3000ms;    //亮环境计时变量
  • L1使能判断:若判断当前时间处于小时参数整点至下一个 8 时之间,指示灯 L1 点亮,反之熄灭。
    下一个8时,简单理解就是24+8=32时,所以只需要判断当前时间是否在小时参数和32区间即可,注意的是,当前时间是以十六进制存储的,所以比较时要转换成十进制再比较。
void DS1302Proc()
{unsigned char Hour;GetRtc(Rtc);Hour = (Rtc[0] / 16) * 10 + Rtc[0] % 16;L1Light = (HourSet <= Hour && Hour < 32);
}
void LedProc()
{ucLed[0] = L1Light;
}
  • L2使能判断:若判断当采集到的温度数据小于温度参数,指示灯 L2 点亮,反之熄灭。
void DS18B20Proc()
{Tem_10x = TemRead() * 10;L2Light = (Tem_10x < TemSet * 10);
}void LedProc()
{ucLed[1] = L2Light;
}
  • L3使能判断:若判断环境处于“暗”状态,且持续时间超过 3 秒,指示灯 L3 点亮;环境处于“亮”状态,且持续时间超过 3 秒,指示灯 L3 熄灭
    L3使能是有很多种方法的,当处于黑暗环境下时,对应的计时变量开始计时,超过3秒时让L3点亮,处于明亮环境下也一样。
    什么时候清除计时变量呢?可以在黑暗环境下清除明亮环境的计时变量,在明亮环境清除黑暗环境下的计时变量。
/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
idata bit L1Light;        //指示灯L1点亮标志位 0灭 1亮
idata bit L2Light;        //指示灯L2点亮标志位 0灭 1亮
idata bit L3Light;        //指示灯L3点亮标志位 0灭 1亮
idata u16 Time_3s;        //暗环境计时变量
idata u16 Time_3000ms;    //亮环境计时变量
void ADProc()
{RD1_100x = AverageFilter() / 51.0 * 100;DarkFlag = (RD1_100x < 100) ? 1 : 0;DarkFlag ? (Time_3000ms = 0) : (Time_3s = 0);
}void LedProc()
{ucLed[2] = L3Light;
}void Timer0_Isr(void) interrupt 1
{if(++SegPos == 8)SegPos = 0;SegDisp(SegPos,SegBuf[SegPos],SegPoint[SegPos]);if(DarkFlag)//黑暗环境{if(++Time_3s >= 3001){Time_3s = 3001;L3Light = 1;}}else//光明环境{if(++Time_3000ms >= 3001){Time_3000ms = 3001;L3Light = 0;}}
}
  • L4~L8使能判断:若判断环境处于“暗”状态,通过 LED 指示灯参数指定的 LED 指示灯点亮,反之熄灭, L4-L8 中未被指定的 LED 指示灯应处于熄灭状态。
    由于点亮/熄灭指示灯是可以自定义的,所以需要加上互斥点亮(如果你只写ucLed[LedSet-1]=DarkFlag,不能实现这种情况:在黑暗环境下,第四个灯亮,然后进入参数页面改成第五个灯亮,这样子第四个、第五个灯都会亮。)
/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
idata bit L1Light;        //指示灯L1点亮标志位 0灭 1亮
idata bit L2Light;        //指示灯L2点亮标志位 0灭 1亮
idata bit L3Light;        //指示灯L3点亮标志位 0灭 1亮
idata u16 Time_3s;        //暗环境计时变量
idata u16 Time_3000ms;    //亮环境计时变量
void LedProc()
{if(DarkFlag){for(i = 3; i < 8; i++)ucLed[i] = (i == LedSet-1);}elsefor(i = 3; i < 8; i++)ucLed[i] = 0;
}

五、代码整合

#include <STC15F2K60S2.H>
#include "Init.h"
#include "Seg.h"
#include "Key.h"
#include "Led.h"
#include "iic.h"
#include "ds1302.h"
#include "ds18b20.h"typedef unsigned char u8;
typedef unsigned int u16;/* 界面参数 */  
idata bit MainMode;		  //主界面 0-数据界面 1-参数界面
idata u8 SegMode; 		  //数据界面分界面 0-时间 1-温度 2-亮暗状态
idata u8 SetMode;         //参数界面分界面 0-时间参数 1-温度参数 2-指示灯参数
/* AD */
idata u16 RD1_100x;       //光敏电阻电压放大100倍
idata bit DarkFlag;       //环境为暗检测标志位 0-亮 1-暗
/* 温度 */
idata u16 Tem_10x;        //温度读取放大10倍
idata u8 TemSet = 25;     //温度参数,默认值25,范围00~99
idata u8 TemSetDis = 25;  //温度参数在修改过程中的值
/* 时间 */
pdata u8 Rtc[3] = {0x16,0x59,0x50};
idata u8 HourSet = 17;    //小时参数,默认值17,范围00~23	
idata u8 HourSetDis = 17; //小时参数在修改过程中的值
/* 按键 */
idata u8 KeyVal,KeyDown,KeyUp,KeyOld;
/* LED */
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};
idata u8 LedSet = 4;      //指示灯参数,默认值4,范围4~8
idata u8 LedSetDis = 4;   //指示灯参数修改过程中的值
idata bit L1Light;        //指示灯L1点亮标志位 0灭 1亮
idata bit L2Light;        //指示灯L2点亮标志位 0灭 1亮
idata bit L3Light;        //指示灯L3点亮标志位 0灭 1亮
idata u16 Time_3s;        //暗环境计时变量
idata u16 Time_3000ms;    //亮环境计时变量
/* 数码管 */
idata u8 SegPos;
pdata u8 SegBuf[8] = {10,10,10,10,10,10,10,10};
pdata u8 SegPoint[8] = {0,0,0,0,0,0,0,0};void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyDown = ~KeyVal & KeyOld;KeyOld = KeyVal;switch(KeyDown){case 4:if(!MainMode){TemSetDis = TemSet;HourSetDis = HourSet;LedSetDis = LedSet;MainMode = 1;SetMode = 0;}else{TemSet = TemSetDis;HourSet = HourSetDis;LedSet = LedSetDis;MainMode = 0;SegMode = 0;}break;case 5:if(!MainMode)//数据界面{SegMode++;if(SegMode == 3)SegMode = 0;}else//参数界面{SetMode++;if(SetMode == 3)SetMode = 0;}break;case 8://减按键if(MainMode){if(SetMode == 0){if(--HourSetDis == 255)HourSetDis = 0;}else if(SetMode == 1){if(--TemSetDis == 255)TemSetDis = 0;}else{if(--LedSetDis == 3)LedSetDis = 4;}}break;case 9://加按键if(MainMode){if(SetMode == 0){if(++HourSetDis == 24)HourSetDis = 23;}else if(SetMode == 1){if(++TemSetDis == 100)TemSetDis = 99;}else{if(++LedSetDis == 9)LedSetDis = 8;}}break;}
}void SegProc()
{unsigned char i;if(!MainMode)//数据界面{switch(SegMode){case 0:SegPoint[2] = 0;SegBuf[2] = SegBuf[5] = 11;for(i = 0; i < 3; i++){SegBuf[3*i] = Rtc[i] / 16;SegBuf[3*i+1] = Rtc[i] % 16;}break;case 1:SegBuf[0] = 12;SegBuf[1] = SegBuf[2] = SegBuf[3] = SegBuf[4] = 10;SegBuf[5] = Tem_10x / 100;SegBuf[6] = Tem_10x / 10 % 10;SegBuf[7] = Tem_10x % 10;SegPoint[6] = 1;break;case 2:SegBuf[0] = 13;SegBuf[1] = 10;SegBuf[2] = RD1_100x / 100;SegBuf[3] = RD1_100x / 10 % 10;SegBuf[4] = RD1_100x % 10;SegBuf[5] = 10;SegBuf[6] = 10;SegBuf[7] = DarkFlag;SegPoint[2] = 1;SegPoint[6] = 0;break;}}else//参数界面{switch(SetMode){case 0:SegPoint[2] = SegPoint[6] = 0;SegBuf[0] = 13;SegBuf[1] = 4;SegBuf[2] = 10;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = 10;SegBuf[6] = (HourSetDis / 10) ? HourSetDis / 10 : 10;SegBuf[7] = HourSetDis % 10;break;case 1:SegBuf[0] = 13;SegBuf[1] = 5;SegBuf[6] = (TemSetDis / 10) ? TemSetDis / 10 : 10;SegBuf[7] = TemSetDis % 10;break;case 2:SegBuf[0] = 13;SegBuf[1] = 6;SegBuf[6] = 10;SegBuf[7] = LedSetDis;break;}}
}void LedProc()
{unsigned char i;ucLed[0] = L1Light;ucLed[1] = L2Light;ucLed[2] = L3Light;if(DarkFlag){for(i = 3; i < 8; i++)ucLed[i] = (i == LedSet-1);}elsefor(i = 3; i < 8; i++)ucLed[i] = 0;LedDisp(ucLed);
}void DS18B20Proc()
{Tem_10x = TemRead() * 10;L2Light = (Tem_10x < TemSet * 10);
}void DS1302Proc()
{unsigned char Hour;GetRtc(Rtc);Hour = (Rtc[0] / 16) * 10 + Rtc[0] % 16;L1Light = (HourSet <= Hour && Hour < 32);
}void ADProc()
{RD1_100x = AverageFilter() / 51.0 * 100;DarkFlag = (RD1_100x < 100) ? 1 : 0;DarkFlag ? (Time_3000ms = 0) : (Time_3s = 0);
}void Timer0_Init(void)		//1毫秒@12.000MHz
{AUXR &= 0x7F;			//定时器时钟12T模式TMOD &= 0xF0;			//设置定时器模式TL0 = 0x18;				//设置定时初始值TH0 = 0xFC;				//设置定时初始值TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时ET0 = 1;				//使能定时器0中断EA = 1;
}void Timer0_Isr(void) interrupt 1
{if(++SegPos == 8)SegPos = 0;SegDisp(SegPos,SegBuf[SegPos],SegPoint[SegPos]);if(DarkFlag){if(++Time_3s >= 3001){Time_3s = 3001;L3Light = 1;}}else{if(++Time_3000ms >= 3001){Time_3000ms = 3001;L3Light = 0;}}
}void main()
{SystemInit();Timer0_Init();SetRtc(Rtc);while(1){//}
}

如果程序有错误或者不理解的地方,请及时联系我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/72022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux docker】关于docker启动出错的解决方法。

无论遇到什么docker启动不了的问题 就是 查看docker状态sytemctl status docker查看docker日志sudo journalctl -u docker.service查看docker三个配置文件&#xff08;可能是配置的时候格式错误&#xff09;&#xff1a;/etc/docker/daemon.json&#xff08;如果存在&#xf…

怎么实现: 大语言模型微调案例

怎么实现: 大语言模型微调案例 目录 怎么实现: 大语言模型微调案例输入一个反常识的问题:首都在北京天安门之后对输出模型进行测试:首都在北京天安门微调代码:测试微调模型代码:微调输出模型结构输出模型参数大小对比Qwen 2.5_0.5:53MB输出模型:951MB 是一样的,没有进行…

rdiff-backup备份

目录 1. 服务器备份知识点 1.1 备份策略 1.2 备份步骤和宝塔面板简介 1.3 CentOS7重要目录 2. 备份工具 2.1 tar -g 备份演示 2. rsync 备份演示 3. rdiff-backup 备份演示 4. 差异和优缺点 3. rdiff-backup安装和使用 3.1 备份命令rdiff-backup 3.2 恢复命令--…

Spring(七)AOP-代理模式

目录 代理模式 一 静态代理 一、核心作用 二、使用场景 二 动态代理 一、核心作用 二、使用场景 具体实现&#xff1a;&#xff08;初始&#xff09; 具体实现&#xff1a;&#xff08;改进&#xff09; 一、核心业务逻辑 1. 接口 MathCalculator 2. 实现类 MathCa…

BGP分解实验·21——BGP选路原则之本地优先级

当使用BGP路径属性——本地优先级&#xff0c;进行路由优选时&#xff0c;优选“本地优先级”数值较大的那个。&#xff08;eBGP之间更新不携带这个属性&#xff09; 实验拓扑如下&#xff1a; 在未实现本地优先级策略前&#xff0c;先在各个BGP之间配置完成基本连接。 R1的基…

【redis】应用场景:共享会话和手机验证码

文章目录 共享会话实现思路 手机验证码实现思路伪代码实现生成验证码验证验证码 共享会话 实现思路 如果每个应用服务器&#xff0c;维护自己的会话数据&#xff0c;此时彼此之间胡共享&#xff0c;用户请求访问到不同的服务器上&#xff0c;就可能会出现一些不能正确处理的情…

通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合

在这个科技日新月异的时代&#xff0c;人工智能不断刷新着我们对世界的认知。一次偶然的机会&#xff0c;我借助北京蓝耘科技股份有限公司提供的算力支持&#xff0c;踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技&#xff1a; 1.2通义万相 2.1…

【Go万字洗髓经】Golang内存模型与内存分配管理

本文目录 1. 操作系统中的虚拟内存分页与进程管理虚拟内存与内存隔离 2. Golang中的内存模型内存分配流程内存单元mspan线程缓存mcache中心缓存mcentral全局堆缓存mheapheapArena空闲页索引pageAlloc 3. Go对象分配mallocgc函数tiny对象分配内存 4.结合GMP模型来看内存模型tiny…

33.HarmonyOS NEXT NumberBox 步进器高级技巧与性能优化

HarmonyOS NEXT NumberBox 步进器高级技巧与性能优化 一、高级交互设计 1. 组件联动控制 // 与Slider双向绑定 State value: number 50Slider({value: this.value,onChange: (v) > this.value v })NumberBox({value: this.value,onChange: (v) > this.value v })2. …

关于ModbusTCP/RTU协议转Ethernet/IP(CIP)协议的方案

IGT-DSER智能网关模块支持西门子、倍福(BECKHOFF)、罗克韦尔AB&#xff0c;以及三菱、欧姆龙等各种品牌的PLC之间通讯&#xff0c;支持Ethernet/IP(CIP)、Profinet(S7)&#xff0c;以及FINS、MC等工业自动化常用协议&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪…

【FreeRTOS】FreeRTOS操作系统在嵌入式单片机上裸机移植

目录 一 RTOS概述 二 FreeRTOS移植 三 FreeRTOS使用 四 附录 一 RTOS概述 先了解一些基础概念&#xff0c;以下内容摘自FreeRTOS官网&#xff08;FreeRTOS™ - FreeRTOS™&#xff09;&#xff1a; 【1】RTOS基础知识 实时操作系统 (RTOS) 是一种体积小巧、确定性强的计算机…

文件包含漏洞第一关

一、什么是文件包含漏洞 1.文件包含漏洞概述 和SQL注入等攻击方式一样&#xff0c;文件包含漏洞也是一种注入型漏洞&#xff0c;其本质就是输入一段用户能够控制的脚本或者代码&#xff0c;并让服务端执行。 什么叫包含呢&#xff1f;以PHP为例&#xff0c;我们常常把可重复使…

瑞芯微RK3576(1)-硬件设计

过年期间&#xff0c;趁着放假时间做了一款3576的核心板 方案是2G DDR432G emmc 引出所有IO口 关于接口方面&#xff0c;考虑了一段时间&#xff0c;最终决定使用BTB的模式&#xff0c;主要是能够出更多的IO&#xff0c;方便拆卸&#xff0c;最让我担心的是BTB的位置问题 为了…

Java 大视界 -- Java 大数据在智能医疗药品研发数据分析与决策支持中的应用(126)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

JWT的学习

1、HTTP无状态及解决方案 HTTP一种是无状态的协议&#xff0c;每次请求都是一次独立的请求&#xff0c;一次交互之后就是陌生人。 以CSDN为例&#xff0c;先登录一次&#xff0c;然后浏览器退出&#xff0c;这个时候在进入CSDN&#xff0c;按理说服务器是不知道你已经登陆了&…

SpringBoot基础Kafka示例

这里将生产者和消费者放在一个应用中 使用的Boot3.4.3 引入Kafka依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>yml配置 spring:application:name: kafka-1#kafka…

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…

【Linux篇】初识Linux指令(上篇)

Linux命令世界&#xff1a;从新手到高手的必备指南 一 Linux发展与历史1.1 Linux起源与发展1.2 Linux与Windows操作系统对比 二 Linux常用操作指令2.1 ls命令 - “List”&#xff08;列出文件)2.2 pwd指令- "打印当前工作目录"2.3 cd指令 - “Change Directory”&…

编程视界:C++命名空间

目录 命名空间 为什么要使用命名空间 什么是命名空间 命名空间的使用方式 关键点总结 命名空间的嵌套使用 匿名命名空间 跨模块调用问题 命名空间可以多次定义 总结 首先从C的hello,world程序入手&#xff0c;来认识一下C语言 #include <iostream> using name…

Excel 保护工作簿:它能解决哪些问题?如何正确使用?

在日常办公中&#xff0c;Excel 表格常常涉及多人协作、重要数据保护&#xff0c;甚至是避免误操作的情况。这时候&#xff0c;“保护工作簿”功能就能派上用场。它能有效防止他人修改表结构、删除工作表&#xff0c;甚至可以设置密码&#xff0c;确保数据的完整性和安全性。今…