首页 > 其他分享 >蓝桥杯单片机组第十四届省赛

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

时间:2024-04-03 10:02:27浏览次数:12  
标签:Disp char void unsigned Seg 蓝桥 单片机 省赛 Buf

 1.题目

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

 

 


2.底层代码

2.1三个常用模块

2.1.1 按键

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

Key.c
#include <Key.h>

unsigned char Key_Read()
{
	unsigned char temp=0;
	ET0 = 0;//用于串口优化

	P44=0;
    P42=1;
    P35=1;
    //P34=1;
	if(P33==0) temp=4;
	if(P32==0) temp=5;
	if(P31==0) temp=6;
	if(P30==0) temp=7;
	P44=1;
    P42=0;
    P35=1;
    //P34=1;
	if(P33==0) temp=8;
	if(P32==0) temp=9;
	if(P31==0) temp=10;
	if(P30==0) temp=11;
	P44=1;
    P42=1;
    P35=0;
    //P34=1;
	if(P33==0) temp=12;
	if(P32==0) temp=13;
	if(P31==0) temp=14;
	if(P30==0) temp=15;
    //P44=1;
    //P42=1;
    //P35=1;
    //P34=0;
	//if(P33==0) temp=12;
	//if(P32==0) temp=13;
	//if(P31==0) temp=14;
	//if(P30==0) temp=15;
    
	ET0 = 1;
	P3=0xff;
	return temp;
}

2.1.2 数码管 

Seg.c
#include <Seg.h>

 code unsigned char Dulu[18]={
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //熄灭
0xbf,  //-	
0xc6, //C
0x89, //H
0x8e, //F
0x8c, //P
0x86, //E
0x88  //A
};

code unsigned char Wulu[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void Seg_Disp(unsigned char addr,dat,point)
{
	//用段选消隐
	P0=0xff;
	P2=P2&0x1f|0xe0;
	P2&=0x1f;
	
	//位选
	P0=Wulu[addr];
	P2=P2&0x1f|0xc0;
	P2&=0x1f;
	
	//段选
	P0=Dulu[dat];
	if(point)
		P0&=0x7f;
	P2=P2&0x1f|0xe0;
	P2&=0x1f;
}

2.1.3 Led

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

Led.c
#include <Led.h>

void Led_Disp(unsigned char addr,unsigned char flag)
{
	static unsigned char temp=0x00;
	static unsigned char temp_old=0xff;
	
	if(flag)
		temp|=0x01<<addr;
	else 
		temp&=~(0x01<<addr);
	if(temp!=temp_old)
	{
		P0=~temp;
		P2=P2&0x1f|0x80;
		P2&=0x1f;
		temp_old=temp;
	}
}

2.1.4 初始化 

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

Init.c
#include <Init.h>

void System_Init(void)
{
	P0=0xff;
	P2=P2&0x1f|0x80;
	P2&=0x1f;
	
	P0=0x00;
	P2=P2&0x1f|0xa0;
	P2&=0x1f;
}

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


2.2 题目要求底层

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

2.2.1 PCF88591

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

iic.c
/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/

#include <iic.h>
#include <intrins.h>
#define DELAY_TIME	5

sbit 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_Read(unsigned char addr)
{
	unsigned char temp;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return temp;
	
}

iic.h
#include <STC15F2K60S2.H>

static void I2C_Delay(unsigned char n);
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
unsigned char AD_Read(unsigned char addr);
//void DA_Read(unsigned char dat);

2.2.2 DS18B20 

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

onewire.c
/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/

#include <onewire.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 Read_Temperature(void)
{
	unsigned char high,low;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	return ((high<<8)|low)/16.0;
}
onewire.h
#include <STC15F2K60S2.H>


void Delay_OneWire(unsigned int t) ;
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
float Read_Temperature(void);

 2.2.3 DS1302

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

ds1302.c
/*	# 	DS1302代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/								
#include <ds1302.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^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);			
}

void Set_Rtc(unsigned char *ucRtc)
{
	unsigned char i;
	Write_Ds1302_Byte(0x8e,0);//关闭写保护
	for(i=0;i<3;i++)
		Write_Ds1302_Byte(0x84-i*2,ucRtc[i]);
	Write_Ds1302_Byte(0x8e,1);//打开写保护
}


void Read_Rtc(unsigned char *ucRtc)
{
	unsigned char i;
	for(i=0;i<3;i++)
		ucRtc[i]=Read_Ds1302_Byte(0x85-i*2);
}

ds1302.h
#include <STC15F2K60S2.H>

void Write_Ds1302(unsigned  char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );
void Set_Rtc(unsigned char *ucRtc);
void Read_Rtc(unsigned char *ucRtc);

2.2.4 NE555 

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

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

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

3.main.c文件

3.1 定时器

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

/利用STC工具生成后要加入(ET1=1,EA=1)两段代码
//定时器1初始化
void Timer1Init(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 Timer1Sever(void) interrupt 3
{
	if(++Key_Slow==10) Key_Slow=0;
	if(++Seg_Slow==500) Seg_Slow=0;
	if(++Seg_Pos==8) Seg_Pos=0;
	
	if(++Timer_1000ms==1000) 
	{
		TR0=0;//停止计时
		Timer_1000ms=0;
		Freq=(TH0<<8)|TL0;
		TH0=TL0=0;
		TR0=1;//开始计时
	}
	
	if(Find_Flag==1)
	{
		if(++Timer_3000ms==3000)
		{
			Timer_3000ms=3001;
		}
	}
	
	if(S9_Flag==1)
	{
		if(++Timer_2000ms==2000)
			Timer_2000ms=2001;
	}
	else
		Timer_2000ms=0;
	if(++Timer_1000ms==1000)
	{
		Timer_1000ms=0;
		Led_Star_Flag=!Led_Star_Flag;
	}
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}

3.2 void main() 

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

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

//main()函数
void main()
{
	//读取DS18B20要在main()函数里面先读取延时750ms。
	Read_Temperature();
	Delay750ms();
	//读书DS1302的时间要先在main()函数里面先设置。
	Set_Rtc(ucRtc);
	//用定时器要先初始化
	Timer0Init();
	Timer1Init();
	//板子要先初始化
	System_Init();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

 3.3 完整代码

main.c
#include <STC15F2K60S2.H>
#include <intrins.h>
#include <iic.h>
#include <onewire.h>
#include <ds1302.h>
#include <Seg.h>
#include <Key.h>
#include <Led.h>
#include <Init.h>

//变量定义区
/*按键*/
unsigned char Key_Slow;//10
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
/*数码管*/
unsigned int Seg_Slow;//500
unsigned Seg_Pos;
unsigned Seg_Buf[8]={10,10,10,10,10,10,10,10};
unsigned Seg_Point[8]={0,0,0,0,0,0,0,0};
/*Led*/
unsigned ucLed[8]={0,0,0,0,0,0,0,0};
/*自定义变量*/


unsigned char Seg_Disp_Mode;//界面:0-时间,1-回显,2-参数
/*时间界面*/
unsigned char ucRtc[3]={0x13,0x03,0x05};//时-分-秒,写出0x的形式
/*回显界面*/
unsigned char Re_Disp_Mode;//回显:0-温度,1-湿度,2-时间
//温度回显·
unsigned char Max_Temperature;//最大温度
float Aver_Temperature;//平均温度
//湿度回显
unsigned char Max_Humidity;//最大湿度
float Aver_Humidity;//平均湿度
//时间回显
unsigned char trigger_Inedx;//触发次数
unsigned char trigger_Time[3];//触发时间
/*参数界面*/
unsigned char Temperature_Set=30;

/*温湿度界面*/
unsigned int Freq;//实时频率
unsigned int Timer_1000ms;
/*S9长短按*/
unsigned int Timer_2000ms;//用于S9长按
bit S9_Flag;//记录是否按下S9;
/*温湿度界面*/
bit Tem_And_Hum_Flag;//温湿度界面和其他界面的区分标志
unsigned char Temperature_Disp;//温湿度界面的温度
unsigned char Humidity_Disp;//温湿度界面的湿度
unsigned char Temperature_Disp_Old;//上一次温湿度界面的温度
unsigned char Humidity_Disp_Old;//上一次温湿度界面的湿度
bit Error_Humidity;//湿度是否有效
bit Led6_Flag;//判断本次采集的温湿度是否均升高
/*判断是否进入采集*/
bit flag;//判断湿度数据是否有效,有效为0,无效为1;
unsigned char Voltage;
unsigned char Voltage_Old;
unsigned int Timer_3000ms;//3s
bit Find_Flag;
/*报警指示灯*/
bit Led_Star_Flag;//控制亮灭
bit Led_Flag;//表明采集温度大于温度参数的状态
unsigned int Timer_1000ms;//1000ms

//清空数据函数
void Clear_Data(void)
{
	unsigned char i=0;
	Max_Temperature=0;
	Aver_Temperature=0;
	Max_Humidity=0;
	Aver_Humidity=0;
	trigger_Inedx=0;
	for(i=0;i<3;i++)
		trigger_Time[i]=0;
}

//按键处理函数
void Key_Proc()
{
	if(Key_Slow) return;
	Key_Slow=1;
	
	Key_Val = Key_Read();
	Key_Down = Key_Val & (Key_Old ^ Key_Val);
	Key_Up = ~ Key_Val & (Key_Old ^ Key_Val);
	Key_Old = Key_Val;
	
	//时间回显界面
	if(Re_Disp_Mode==2&&Seg_Disp_Mode==1)
	{
		if(Key_Down==9)
			S9_Flag=1;//开始计时
		if(Key_Up==9)//S9抬起
		{						
			if(Timer_2000ms>=2000&&S9_Flag==1)
			{
				Clear_Data();
				S9_Flag=0;//停止计时
			}
			else
				S9_Flag=0;//停止计时
		}
	}
	
	switch(Key_Down)
	{
		case 4:
			if(++Seg_Disp_Mode==3)
				Seg_Disp_Mode=0;
			Re_Disp_Mode=0;
		break;
		
		case 5:
			if(Seg_Disp_Mode==1)
			{
				if(++Re_Disp_Mode==3)
					Re_Disp_Mode=0;
			}	
		break;
			
		case 8:
			if(Seg_Disp_Mode==2)
			{
				if(++Temperature_Set==100)
					Temperature_Set=99;
			}
		break;
			
		case 9:	
			//参数界面
			if(Seg_Disp_Mode==2)
			{	
				if(--Temperature_Set==255)
					Temperature_Set=0;
			}
		break;
		
	}
}

//湿度处理函数
bit Read_Humidity(void)
{
	if(Freq<200||Freq>2000)
		Error_Humidity=0;//无效数据
	else
	{
		Error_Humidity=1;
		Humidity_Disp=(unsigned char)(2/45*(Freq-200)+10);
	}
	return Error_Humidity;
}	


//清除数码管
void Clear_Seg(void)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		Seg_Buf[i]=10;
		Seg_Point[i]=0;
	}
}
//信息处理函数
void Seg_Proc()
{
	unsigned char i;
	if(Seg_Slow) return;
	Seg_Slow=1;
	
	Read_Rtc(ucRtc);
	Temperature_Disp=(unsigned char)Read_Temperature();
	
	//判断是否进入温湿度界面
	Voltage=AD_Read(0x41);
	//由亮到暗,避免重复进入
	if((Voltage_Old>50&&Voltage<50)&&Tem_And_Hum_Flag==0)
	{
		Find_Flag=1;//开始计时
		Tem_And_Hum_Flag=1;
		if(Read_Humidity()==1)
		{
			if(++trigger_Inedx==100) trigger_Inedx=99;
			for(i=0;i<3;i++)
				trigger_Time[i]=ucRtc[i];
		}
	}
	//是否间隔3s
	else if(Tem_And_Hum_Flag==1&&Timer_3000ms>=3000) 
	{
		Find_Flag=0;//停止计时·
		Timer_3000ms=0;
		Tem_And_Hum_Flag=0;
	}

	Voltage_Old=Voltage;
	
	//处于温湿度界面
	if(Tem_And_Hum_Flag==1)
	{
		Seg_Buf[0]=16;//E
		Seg_Buf[1]=Seg_Buf[2]=10;//熄灭
		Seg_Buf[3]=Temperature_Disp/10;
		Seg_Buf[4]=Temperature_Disp%10;
		Seg_Point[6]=0;
		
		if(Temperature_Disp>Temperature_Set) 
			Led_Flag=1;
		else 
			Led_Flag=0;
		/*用于读取最大温度,平均温度*/
		Max_Temperature=(Max_Temperature>Temperature_Disp)?Max_Temperature:Temperature_Disp;
		//平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
		Aver_Temperature=((trigger_Inedx-1)*Aver_Temperature+Temperature_Disp)/trigger_Inedx;
		
		Seg_Buf[5]=11;//-
		//采集有效
		if(Error_Humidity==1)
		{
			flag=0;//进行了温湿度采集,且采集有效
			Seg_Buf[6]=Humidity_Disp/10;
			Seg_Buf[7]=Humidity_Disp%10;
			/*用于读取最大温度,平均温度*/
			Max_Humidity=(Max_Humidity>Humidity_Disp)?Max_Humidity:Humidity_Disp;
			//平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
			Aver_Humidity=((trigger_Inedx-1)*Aver_Humidity+Humidity_Disp)/trigger_Inedx;
			
			if(trigger_Inedx>=2)
			{
				Led6_Flag=(Temperature_Disp>Temperature_Disp_Old)&(Humidity_Disp>Humidity_Disp_Old);
				Temperature_Disp_Old=Temperature_Disp;
				Humidity_Disp_Old=Humidity_Disp;
			}
		}
		else
		{
			flag=1;//进行了温湿度采集,且采集有效
			Seg_Buf[6]=Seg_Buf[7]=17;//A
		}
		
	}
	else
	{
		switch(Seg_Disp_Mode)
		{
			//时间
			case 0:
				Seg_Buf[0]=ucRtc[0]/16;
				Seg_Buf[1]=ucRtc[0]%16;
				Seg_Buf[2]=11;//-
				Seg_Buf[3]=ucRtc[1]/16;
				Seg_Buf[4]=ucRtc[1]%16;
				Seg_Buf[5]=11;//-
				Seg_Buf[6]=ucRtc[2]/16;
				Seg_Buf[7]=ucRtc[2]%16;
				Seg_Point[6]=0;
			break;
			
			//回显
			case 1:
				switch(Re_Disp_Mode)
				{
					//温度
					case 0:
						if(trigger_Inedx==0)
							Clear_Seg();
						Seg_Buf[0]=12;//C
						Seg_Buf[1]=10;//熄灭
						if(trigger_Inedx>0)
						{
							Seg_Buf[2]=Max_Temperature/10;
							Seg_Buf[3]=Max_Temperature%10;
							Seg_Buf[4]=11;//-
							Seg_Buf[5]=(unsigned char)Aver_Temperature/10;
							Seg_Buf[6]=(unsigned char)Aver_Temperature%10;
							Seg_Buf[7]=(unsigned int)(Aver_Temperature*100)%10;
							Seg_Point[6]=1;
						}	
					break;
					//湿度
					case 1:
						if(trigger_Inedx==0)
							Clear_Seg();
						Seg_Buf[0]=13;//H
						Seg_Buf[1]=10;//熄灭
						if(trigger_Inedx>0)
						{
							Seg_Buf[2]=Max_Humidity/10;
							Seg_Buf[3]=Max_Humidity%10;
							Seg_Buf[4]=11;//-
							Seg_Buf[5]=(unsigned char)Aver_Humidity/10;
							Seg_Buf[6]=(unsigned char)Aver_Humidity%10;
							Seg_Buf[7]=(unsigned int)(Aver_Humidity*100)%10;
							Seg_Point[6]=1;
						}
						break;
					//时间
					case 2:
						if(trigger_Inedx==0)
							Clear_Seg();
						Seg_Buf[0]=14;//F
						Seg_Buf[1]=trigger_Inedx/10;
						Seg_Buf[2]=trigger_Inedx%10;
						if(trigger_Inedx>0)
						{
							Seg_Buf[3]=trigger_Time[0]/16;
							Seg_Buf[4]=trigger_Time[0]%16;
							Seg_Buf[5]=11;//-
							Seg_Buf[6]=trigger_Time[1]/16;
							Seg_Buf[7]=trigger_Time[1]%16;
							Seg_Point[6]=0;
						}
					break;	
				}
			break;
				
			//参数
			case 2:
				Seg_Buf[0]=15;//P
				Seg_Buf[1]=Seg_Buf[2]=Seg_Buf[3]=Seg_Buf[4]=Seg_Buf[5]=10;//熄灭
				Seg_Buf[6]=Temperature_Set/10;
				Seg_Buf[7]=Temperature_Set%10;
				Seg_Point[6]=0;
			break;
			
		}
	}
	
}

//其他处理函数
void Led_Proc()
{
	unsigned char i;
	for(i=0;i<2;i++)
		ucLed[i]=(i==Seg_Disp_Mode);
	ucLed[2]=Tem_And_Hum_Flag;
	
	ucLed[3]=(Led_Star_Flag&Led_Flag);
	ucLed[4]=flag;
	
	ucLed[5]=Led6_Flag;
}


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


//利用STC工具生成后要加入(ET1=1,EA=1)两段代码
//定时器1初始化
void Timer1Init(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 Timer1Sever(void) interrupt 3
{
	if(++Key_Slow==10) Key_Slow=0;
	if(++Seg_Slow==500) Seg_Slow=0;
	if(++Seg_Pos==8) Seg_Pos=0;
	
	if(++Timer_1000ms==1000) 
	{
		TR0=0;//停止计时
		Timer_1000ms=0;
		Freq=(TH0<<8)|TL0;
		TH0=TL0=0;
		TR0=1;//开始计时
	}
	
	if(Find_Flag==1)
	{
		if(++Timer_3000ms==3000)
		{
			Timer_3000ms=3001;
		}
	}
	
	if(S9_Flag==1)
	{
		if(++Timer_2000ms==2000)
			Timer_2000ms=2001;
	}
	else
		Timer_2000ms=0;
	if(++Timer_1000ms==1000)
	{
		Timer_1000ms=0;
		Led_Star_Flag=!Led_Star_Flag;
	}
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}

void Delay750ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 35;
	j = 51;
	k = 182;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

//main()函数
void main()
{
	//读取DS18B20要在main()函数里面先读取延时750ms。
	Read_Temperature();
	Delay750ms();
	//读书DS1302的时间要先在main()函数里面先设置。
	Set_Rtc(ucRtc);
	//用定时器要先初始化
	Timer0Init();
	Timer1Init();
	//板子要先初始化
	System_Init();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

 4.结束语

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

标签:Disp,char,void,unsigned,Seg,蓝桥,单片机,省赛,Buf
From: https://blog.csdn.net/weixin_62267326/article/details/137207739

相关文章

  • 蓝桥杯单片机第十三届省赛
    一、题目这次的省赛我感觉还是比较基础的,掌握几个模块就可以完全写出题目是在在网上找的二、代码 main.c#include<STC15F2K60S2.H>#include<ds1302.h>#include<onewire.h>#include<intrins.h>#include<Init.h>#include<Key.h>#include<Seg.h>#include......
  • 蓝桥杯算法集训 - Week 5:树状数组、各类DP算法
    蓝桥杯算法集训-Week5本系列随笔用于整理AcWing题单——《蓝桥杯集训·每日一题2024》的系列题型及其对应的算法模板。一、树状数组树状数组是一种数据结构,可以快速地完成以下两个操作:将第i个数加上c快速求前缀和,即任意区间[i,j]的和Ⅰ、代码模板//树状数组长度......
  • 【毕业设计】基于单片机的汽车尾灯电路设计与实现(附原理图与源码)
    1引言在日新月异的21世纪里,电子产品得到了迅速发展。许多电器设备都趋于人性化、智能化,这些电器设备大部分都含有CPU控制器或者是单片机。单片机以其高可靠性、高性价比、低电压、低功耗等一系列优点,近几年得到迅猛发展和大范围推广,广泛应用于工业控制系统、通讯设备、日常消......
  • 基于51单片机的锅炉控制【热电偶,数码管,PID】(仿真)
    1、使用N型热电偶测量锅炉内部温度2、设置温度值,温度低于设定值则启动加热3、加热过程使用PID控制,PID参数固定4、数码管显示温度5、温度过限报警#include"lcd1602.h"voiddelay_uint(uinti){ while(i--);}/**************************************************......
  • 基于51单片机的波形发生器【矩形波,三角波,锯齿波,固定频率,】(仿真)
    #include"lcd1602.h"voiddelay_uint(uinti){ while(i--);}/*********************************************************************名称:write_com(ucharcom)*功能:1602命令函数*输入:输入的命令值*输出:无*********************************......
  • 蓝桥杯javaB组备赛
    15届蓝桥杯备赛java语法基础IO框架importjava.util.*;importjava.IO.IOException;importjava.IO.BufferedReader;publicclassMain{publicstaticvoidmain(String[]args)throwsIOException{BufferedReaderreader=newBufferedReader(newInputStre......
  • 【蓝桥杯】小明发明了一种给由全大写字母组成的字符串编码的方法。对于每一个大写字母
    【问题描述】小明发明了一种给由全大写字母组成的字符串编码的方法。对于每一个大写字母,小明将它转换成它在26个英文字母中序号,即A→1,B→2,...Z→26。这样一个字符串就能被转化成一个数字序列:比如ABCXYZ→123242526。现在给定一个转换后的数字序列,小明想还原出原本的......
  • 蓝桥杯备考随手记: 字符串转换
    在Java中,字符串转换是指将一个数据类型的变量转换成字符串类型的操作。字符串转换可以通过以下几种方式实现:使用String类的valueOf()方法:该方法可以将任意数据类型转换成字符串类型。例如:intnum=10;Stringstr=String.valueOf(num);该方法还可以用于将字符数组转换......
  • smu2024蓝桥杯训练1
    A[语言月赛202401]装满葡萄汁的酒杯查看代码voidsolve(){intn;cin>>n;if(n<=100)cout<<100;elseif(n<=150)cout<<150;elseif(n<=300)cout<<300;elseif(n<=400)cout<<400;e......
  • 蓝桥杯练习笔记(十六)
    蓝桥杯练习笔记(十六)一、输入示例:312111347453这是用到了m叉树的结论:对于某个m叉树的一个节点n,假如其有完整子树,则其左子节点l为l=(n-1)m+2,右子节点r为r=mn+1。基于此我们可以快速判断这个数在某些节点处的具体情况。比如是否是满叶子等等。蓝桥官网题解:......