蓝桥杯单片机第13届省赛

蓝桥杯单片机第13届省赛


在做本届赛题时由于未读完赛题,导致后续程序有一段时间并没有思路。总得来说本届赛题中规中矩。在此,感谢Namaste795博客帮助,具体链接如下:Namaste795蓝桥杯代码


对于本届赛题有个人认为有以下注意的地方:

  • 对于中断服务函数只执行标志位的检测,切记不要放函数
  • 对于LED寄存器配置应用& | 解决LED亮灭问题
  • 按键也应实行标志位检测

以下为具体代码:
mian.c

#include "include.h"

unsigned char yi,er,san,si,wu,liu,qi,ba;
unsigned char uc_Key_flag;  // 按键消抖标志位
unsigned char wendu;  // 读取温度
unsigned int rd_temp;  // 读取温度扩大10倍
unsigned char rd_wendu = 23;  // 温度参数
unsigned char LED = 0xff;

bit flag_led = 0;  // L3闪灯标志位
bit ji_dian_qi = 0; // 继电器标志位
bit bit_L2;  // L2亮灯标志位

void main()
{
	all_init();
	DS1302_Settime(23,59,55);
	
	rd_temperature();  // 延时读取消去温度85
	Delay600ms();
	rd_temperature();
	
	while(1)
	{
		Key_Proc();  // 按键
		
		wendu = rd_temperature();
		rd_temp = wendu*10 + xiaoshu1;
		Read_time();

		if(S12_Cut == 1) //界面1
		{
			flag_point_show = 1;
			yi = 12; er = 1; si = 11; wu = 11;
			liu = wendu/10;qi = wendu%10;ba = xiaoshu1%10;
		}
		else if(S12_Cut == 2) // 界面2
		{
			flag_point_show = 0;
			yi = 12; er = 2;liu = 10;
			if(S17_up == 1)
			{
				si = rhour/10; wu = rhour%10;
				qi = rmin/10; ba = rmin%10;
			}
			else if(S17_down == 1)
			{
				si = rmin/10; wu = rmin%10;
				qi = rsec/10; ba = rsec%10;
			}
		}
		else if(S12_Cut == 3)  // 界面3
		{
			yi = 12; er = 3; si =11; wu =11;liu = 11;
			qi = rd_wendu/10; ba = rd_wendu%10;
			if(S16_add == 1)
			{
				S16_add = 0;
				rd_wendu = rd_wendu + 1;
				if(rd_wendu >= 99)
					rd_wendu = 99;
			}
			else if(S17_reduce == 1)
			{
				S17_reduce = 0;
				rd_wendu = rd_wendu - 1;
				if(rd_wendu <= 10)
					rd_wendu = 10;
			}
		}
		
		if(S13_Con) // 默认温度控制
		{
		  LED &= 0xfd; P0 = LED; HC138(4);  // 温度控制下的灯
//			P0 = 0xfd; HC138(4);
			bit_L2 = 1;
			if(rd_temp >= rd_wendu*10)
			{
				P0 = 0x10; HC138(5);
				ji_dian_qi = 1;
			}
			else if(rd_temp < rd_wendu*10)
			{
				P0 &= 0x00; HC138(5);
				ji_dian_qi = 0;
			}
		}
		else  // 时间控制
		{
			bit_L2 = 0;
			if((rsec == 00)&&(rmin == 00))
			{
				P0 = 0x10; HC138(5); ji_dian_qi = 1;
				LED &= 0xfe; P0 = LED; HC138(4); //注意此灯与或表达
			}
			else if((rsec == 05)&&(rmin == 00))
			{
				P0 &= 0x00; HC138(5);	
				LED |= 0x01; P0 = LED;HC138(4);
				ji_dian_qi = 0;
			}
		}
		LED_PROT();
		
		DISPLAY_1SMG(yi,er);
		DISPLAY_2SMG(san,si);
		DISPLAY_3SMG(wu,liu);
		DISPLAY_4SMG(qi,ba);
	}
}
void T1() interrupt 3
{
	static unsigned char cnt_100ms;
  if(++uc_Key_flag == 10)  // 按键消抖
		uc_Key_flag = 0;
	
	if(++cnt_100ms >= 100)
	{
		cnt_100ms = 0;
		flag_led = ~flag_led;
	}
}

void LED_PROT()  // LED控制函数
{
	if((rsec == 00)&&(rmin == 00))
	{
		ji_dian_qi = 1;
		if(bit_L2 == 1)
		{
			LED &= 0xfc; P0 = LED; HC138(4); 
		}
		else{LED |= 0xff; LED &= 0xfe; P0 = LED; HC138(4);} //灯
	}
	else if((rsec == 05)&&(rmin == 00))
	{
		ji_dian_qi = 0;
		if(bit_L2 ==1)
		{
			LED = 0xff; LED &= 0xfd; P0 = LED; HC138(4); 
		}
		else
		{
			LED |= 0x02; P0 = LED; HC138(4); LED = 0xff;
		}
	}
 
	if(ji_dian_qi == 1)
	{
		if(flag_led)
		{
			LED &= 0xfb; P0 = LED; HC138(4);   // 与是开灯,或是关灯
		}
		else
		{
			LED |= 0x04; P0 = LED; HC138(4);
		}
	}
	else if(ji_dian_qi == 0)
	{
		 LED |= 0x04; P0 = LED; HC138(4);
	}
}

Key_16.c

#include "KEY_16.h"

unsigned char S12_Cut = 1;
bit S13_Con = 1;
bit S16_add;
bit S17_reduce;
bit S17_down = 0;
bit S17_up = 1;

unsigned char Key_Read()
{
	unsigned int Key_Temp;
	unsigned char Key_Value;
	
	P44 = 0; P42 = 1; P35 = 1; P34 = 1; P3 |= 0x0f;
	Key_Temp = P3;
	
	P44 = 1; P42 = 0; P35 = 1; P34 = 1; P3 |= 0x0f;
	Key_Temp = (Key_Temp<<4)|(P3&0x0f);
	
	P44 = 1; P42 = 1; P35 = 0; P34 = 1; P3 |= 0x0f;
	Key_Temp = (Key_Temp<<4)|(P3&0x0f);
	
	P44 = 1; P42 = 1; P35 = 1; P34 = 0; P3 |= 0x0f;
	Key_Temp = (Key_Temp<<4)|(P3&0x0f);
	
	switch(~Key_Temp)
	{
		case 0x8000: Key_Value = 4; break;
		case 0x4000: Key_Value = 5; break;
		case 0x2000: Key_Value = 6; break;
		case 0x1000: Key_Value = 7; break;
			
		case 0x0800: Key_Value = 8; break;
		case 0x0400: Key_Value = 9; break;
		case 0x0200: Key_Value = 10; break;
		case 0x0100: Key_Value = 11; break;
			
		case 0x0080: Key_Value = 12; break;
		case 0x0040: Key_Value = 13; break;
		case 0x0020: Key_Value = 14; break;
		case 0x0010: Key_Value = 15; break;
			
		case 0x0008: Key_Value = 16; break;
		case 0x0004: Key_Value = 17; break;
		case 0x0002: Key_Value = 18; break;
		case 0x0001: Key_Value = 19; break;
		default : Key_Value = 0;
	}
	
	return Key_Value;
}

void Key_Proc()
{
	unsigned char Key_Temp;
	unsigned char Key_Down;
	unsigned char Key_Up;
	static unsigned char Key_Old;
	
	if(uc_Key_flag) return;
	uc_Key_flag = 1;
	
	Key_Temp = Key_Read();
	Key_Down = Key_Temp & (Key_Old^Key_Temp);
	Key_Up = ~Key_Temp & (Key_Old^Key_Temp);
	Key_Old = Key_Temp;
	
	if(Key_Down)
	{
		switch(Key_Down)
		{
			case 12: S12(); break;
			case 13: S13(); break;
			case 16: S16_add = 1; S17_reduce = 0;break;
			case 17: S16_add = 0; S17_reduce = 1; S17_down = 1;S17_up = 0;break;
		}
	}
	
	if(Key_Up)
	{
		switch(Key_Up)
		{
			case 17: S17_up = 1; S17_down = 0;break;
		}
	}
}	

void S12()
{
	switch(S12_Cut)
	{
		case 1: S12_Cut = 2;flag_point_show = 1; break;
		case 2: S12_Cut = 3;flag_point_show = 0; S16_add = 0; S17_reduce = 0;break;
		case 3: S12_Cut = 1;flag_point_show = 0; break;
	}
}

void S13()
{
	static unsigned char S13_State = 0;
	S13_State++;
	switch(S13_State)
	{
		case 1:  P0 = 0x00; HC138(5); ji_dian_qi = 0;
		LED |= 0x02; P0 = LED; HC138(4);  // 时间控制下的灯
		S13_Con = 0;break;
		case 2: S13_State=0; S13_Con = 1; ji_dian_qi = 1;
		LED = 0xff; LED &= 0xfd; P0 = LED; HC138(4);
		break;
	}
}

HC138_TIM_SMG.c

#include "HC138_TIM_SMG.h"

unsigned char code segtab[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff,0xc1};
unsigned char code weitab[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

bit flag_point_show = 1;

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

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

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

	_nop_();
	_nop_();
	i = 28;
	j = 92;
	k = 196;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
}


void HC138(unsigned char ch)
{
	P2 &= 0x1f;
	P2 |= (ch<<5);
	P2 &= 0x1f;
}

void all_init()
{
	/*关闭外设初始化*/
	P0 = 0xff; HC138(4);
	P0 = 0x00; HC138(5);
	P0 = 0x00; HC138(6);
	P0 = 0xff; HC138(7);
  	
	/*数码管初始化数值化*/
	yi = 11; er = 11; san = 11; si = 11;
	wu = 11; liu = 11; qi = 11; ba = 11;
	
  Timer1Init();		//1毫秒@12.000MHz
	EA = 1;
}

void DISPLAY_1SMG(unsigned char dat1,unsigned char dat2)
{
	P0 = weitab[0]; HC138(6);
	P0 = segtab[dat1]; HC138(7);
	Delay1ms();
	
	P0 = weitab[1]; HC138(6);
	P0 = segtab[dat2]; HC138(7);
	Delay1ms();
	
	P0 = 0xff; HC138(7);
}
void DISPLAY_2SMG(unsigned char dat1,unsigned char dat2)
{
	P0 = weitab[2]; HC138(6);
	P0 = segtab[dat1]; HC138(7);
	Delay1ms();
	
	P0 = weitab[3]; HC138(6);
	P0 = segtab[dat2]; HC138(7);
	Delay1ms();
	
	P0 = 0xff; HC138(7);
}
void DISPLAY_3SMG(unsigned char dat1,unsigned char dat2)
{
	P0 = weitab[4]; HC138(6);
	P0 = segtab[dat1]; HC138(7);
	Delay1ms();
	
	P0 = weitab[5]; HC138(6);
	P0 = segtab[dat2]; HC138(7);
	Delay1ms();
	
	P0 = 0xff; HC138(7);
}
void DISPLAY_4SMG(unsigned char dat1,unsigned char dat2)
{
	P0 = weitab[6]; HC138(6);
	
	if(flag_point_show)
		P0 = segtab[dat1] & 0x7f;
	else
		P0 = segtab[dat1]; 
	
	HC138(7);
	Delay1ms();
	
	P0 = weitab[7]; HC138(6);
	P0 = segtab[dat2]; HC138(7);	
	Delay1ms();
	
	P0 = 0xff; HC138(7);
}

include.h

#ifndef __INCLUDE_H_
#define __INCLUDE_H_

#include <STC15F2K60S2.H>
#include <intrins.h>

extern unsigned char yi,er,san,si,wu,liu,qi,ba;
extern unsigned char uc_Key_flag;
extern unsigned char rd_wendu;
extern unsigned char LED;

extern bit ji_dian_qi;

void LED_PROT();

#include "HC138_TIM_SMG.h"
#include "KEY_16.h"
#include "onewire.h"
#include "ds1302.h"

#endif
总结

希望代码对大家有所帮助

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值