蓝桥杯单片机第十三届省赛

本文详细描述了一段嵌入式C语言代码,用于省赛项目,涉及按键控制、数码管显示、温度和时间显示、参数设置以及定时器管理。作者分享了main.c文件的关键部分,并表示可能存在bug,期待读者指正。
摘要由CSDN通过智能技术生成

一、题目

这次的省赛我感觉还是比较基础的,掌握几个模块就可以完全写出

题目是在在网上找的


二、代码 

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

//按键
unsigned char Key_Slow_Down;//10ms
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
//数码管
unsigned int Seg_Slow_Down;//500ms
unsigned char Seg_Pos;
unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10};
unsigned char Seg_Point[8]={0,0,0,0,0,0,0,0};
//Led
unsigned char ucLed[8]={0,0,0,0,0,0,0,0};

unsigned char Seg_Disp_Mode;//0-温度显示界面 1-时间显示界面 2-参数设置界面
//温度显示界面
float Temperature;
//参数设置界面(Rtc)
unsigned char ucRtc[3]={0x23,0x59,0x49};
//参数设置界面
unsigned char Temperature_Set=23;//参数设置:初始值为23
unsigned char Temperature_Disp;//参数加和减用:初始值为23
//模式按键
bit Mode_Flag;//0-温度控制 1-时间控制
//继电器吸合
bit Relay_Flag;//1-开始计时 0-停止计时
unsigned int Relay_Timer_5000ms;//5s
//Led灯
bit Led_Flag;//1-开始计时 0-停止计时
unsigned int Led_Timer_5000ms;//5s
//L3
bit Relay_Led_Flag;//继电器是否吸合
bit Led_Star_Flag=1;//L3闪烁
unsigned char Timer_100ms;

//按键处理函数
void Key_Proc()
{
	if(Key_Slow_Down) return;
	Key_Slow_Down=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(Key_Down==12)
	{
		if(++Seg_Disp_Mode==3) 
			Seg_Disp_Mode=0;
		if(Seg_Disp_Mode==0)
			Temperature_Set=Temperature_Disp;
		if(Seg_Disp_Mode==2)
			Temperature_Disp=Temperature_Set;
	}
	//模式按键
	if(Key_Down==13)
	{
		Mode_Flag=!Mode_Flag;
		Relay(0);//切换为下一次模式做准备
		Relay_Led_Flag=0;//停止闪烁
	}

	//”加“按键
	if(Key_Down==16)
	{
		if(Seg_Disp_Mode==2)
		{
			Temperature_Disp++;
			if(Temperature_Disp>=99)
				Temperature_Disp=99;
		}	
	}
	
	//”减按键”
	if(Key_Down==17)
	{
		//参数界面按下
		if(Seg_Disp_Mode==2)
		{
			Temperature_Disp--;
			if(Temperature_Disp<=10)
				Temperature_Disp=10;
		}
	}
	
	//时间显示界面
	if(Seg_Disp_Mode==1)
	{
		//S17按下,直接按下就显示(没有计时)不需要使用Key_Down来判断
		if(Key_Old==17)
		{
			Seg_Buf[3]=ucRtc[1]/16;
			Seg_Buf[4]=ucRtc[1]%16;
			Seg_Buf[6]=ucRtc[2]/16;
			Seg_Buf[7]=ucRtc[2]%16;
		}
		//S17抬起
		if(Key_Up==17)
		{
			Seg_Buf[3]=ucRtc[0]/16;
			Seg_Buf[4]=ucRtc[0]%16;
			Seg_Buf[6]=ucRtc[1]/16;
			Seg_Buf[7]=ucRtc[1]%16;
		}
	}
}

//数码管清除函数
void Clear_Seg(void)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		Seg_Buf[i]=10;
		Seg_Point[i]=0;
	}
}

//信息处理函数
void Seg_Proc()
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down=1;
	
	//实时读取温度
	Temperature=Read_temperature();
	//实时读取时间
	Read_Rtc(ucRtc);
	
	switch(Seg_Disp_Mode)
	{
		//温度显示界面
		case 0:
			Clear_Seg();
			Seg_Buf[0]=12;//U
			Seg_Buf[1]=Seg_Disp_Mode+1;
			Seg_Buf[5]=(unsigned char)Temperature/10%10;
			Seg_Buf[6]=(unsigned char)Temperature%10;
			Seg_Buf[7]=(unsigned int)(Temperature*10)%10;
			Seg_Point[6]=1;
		break;
		//时间显示界面
		case 1:
			Clear_Seg();
			Seg_Buf[0]=12;//U
			Seg_Buf[1]=Seg_Disp_Mode+1;
			Seg_Buf[3]=ucRtc[0]/16;
			Seg_Buf[4]=ucRtc[0]%16;
			Seg_Buf[5]=11;//-
			Seg_Buf[6]=ucRtc[1]/16;
			Seg_Buf[7]=ucRtc[1]%16;
		break;
		//参数设置界面
		case 2:
			Clear_Seg();
			Seg_Buf[0]=12;//U
			Seg_Buf[1]=Seg_Disp_Mode+1;
			Seg_Buf[6]=Temperature_Disp/10;
			Seg_Buf[7]=Temperature_Disp%10;
			break;
	}
	
}

//其他处理函数
void Led_Proc()
{
	if(Mode_Flag==0)
	{
		if(Temperature>Temperature_Set)
		{
			Relay(1);
			Relay_Led_Flag=1;
			
		}
		else
		{
			Relay(0);
			Relay_Led_Flag=0;
		}
	}
	else
	{
		if(ucRtc[1]==0x00&&ucRtc[2]==0x00)
		{
			Relay(1);
			Relay_Led_Flag=1;
			Relay_Flag=1;	
		}
		//这个5s以后,不能放在上面判断,不然会不执行
		if(Relay_Flag==0&&Relay_Timer_5000ms==5000)
		{
			Relay(0);
			Relay_Led_Flag=0;
			Relay_Timer_5000ms=0;
		}
	}
	//L1
	if(ucRtc[1]==0x00&&ucRtc[2]==0x00)
	{
		ucLed[0]=1;
		Led_Flag=1;
	}
	if(Led_Flag==0&&Led_Timer_5000ms==5000)
	{
		ucLed[0]=0;
		Led_Timer_5000ms=0;
	}
	//L2
	ucLed[1]=!Mode_Flag;//0亮 1灭
	//
	ucLed[2]=Relay_Led_Flag?Led_Star_Flag:0;
}

//定时器0初始化
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0=1;
	EA=1;
}

void Timer0Sever(void)interrupt 1
{
	if(++Key_Slow_Down==10) Key_Slow_Down=0;
	//改变延时,使按下S17后数码管无重影
	if(++Seg_Slow_Down==100) Seg_Slow_Down=0;
	
	if(++Seg_Pos==8) Seg_Pos=0;
	
	if(Relay_Flag==1)
	{
		if(++Relay_Timer_5000ms==5000)
		{
			Relay_Timer_5000ms=5000;
			Relay_Flag=0;//停止计时
		}
	}
	
	if(Led_Flag==1)
	{
		if(++Led_Timer_5000ms==5000)
		{
			Led_Timer_5000ms=5000;
			Led_Flag=0;//停止计时
		}
	}
	
	if(Relay_Led_Flag==1)
	{
		if(++Timer_100ms==100)
		{
			Timer_100ms=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]);
	
}

//延时750ms
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()
{
	Read_temperature();
	Delay750ms();
	Set_Rtc(ucRtc);
	Timer0Init();
	System_Init();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

模块代码可以看我以前发的代码


三、后话 

这个代码是我今天早上写的,可能会有bug,希望大家可以指正

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值