南邮单片机设计小型定时开关控制系统

1.实验目的要求

  1. 掌握行列式键盘、LED、数码管、蜂鸣器、继电器等人机接口和机电设备的工作原理,以及使用单片机C语言对其进行控制的方法;
  2. 掌握基于状态转移及定时调度的系统分析方法,并使用此方法对系统软件结构进行分析和设计,实现所要求的功能;
  3. 掌握使用集成开发环境Keil进行单片机程序的设计、开发及调试的方法和过程。

2.实验要求

  1. 通过单片机的IO端口控制人机接口及机电设备,完成一个定时开关的设计;
  2. 定时开关的工作方式可设置为定时开或定时关;
  3. 系统通过行列式键盘接受用户的按键输入,设置工作方式和定时时长;
  4. 系统通过控制LED、数码管及蜂鸣器对用户的操作提供反馈和提示;
  5. 当用户控制计时启动时,系统对用户设定的时长进行倒计时;
  6. 如用户设置系统工作在定时开方式,则倒计时结束(计数到0)时控制继电器吸合;
  7. 如用户设置系统工作在定时关方式,则倒计时开始时继电器吸合,倒计时结束(计数到0)时继电器断开。

 

 3.实验仪器

4.系统的分析和设计:

此系统为小型定时开关控制系统,实现两个功能,定时开和定时关功能,通过4个LED灯的亮灭了实现开关。

主函数设计,进行51单片机的初始化,等待键盘事件发生,利用solveKey函数处理键盘事件。

图1 主函数逻辑

设置了4个状态state。利用4个LED灯来提示处于哪个状态,由上到下依次为空闲状态,设置状态,定时开状态,定时关状态。

图2 各个状态说明

利用4×4的键盘进行功能实现,具体按钮功能如下:

图3 键盘功能设置说明

定时中断实现数码管显示时间,扫描键盘。

图4 定时器实现功能

具体实验操作:

导入代码后,

  1. 按下0行3列按钮将空闲状态切换为设置状态。(LED灯由第一个跳至第二个)
  2. 通过键盘功能说明设置倒计时时间。
  3. 按下1行2列(或1行3列)选择定时开状态(定时关状态)
  4. 按下0行3列,“确认”开始进行倒计时。
  5. 按照设置的功能状态LED在倒计时结束时点亮或熄灭。

5.关键代码的说明:

(1)主函数代码:

void main(void)
{
	int i;

	// 初始化串行口(T1)和T0
	TMOD = 0x21;						// T1,工作方式2,8位自动重装计数器;T0,工作方式1,16位计数器,软件重装
	PCON |= 0x80;						// SMOD = 1
	SCON = 0x50;						// 串口模式1,允许接收
	TH1 = 256 - (OSC / 12 / 16 / BAUD);		// 9600bps,N81   数据格式为N81(无校验位,8位数据位,1位停止位)。
	TL1 = 256 - (OSC / 12 / 16 / BAUD);
	TR1 = 1;							// 启动串口(T1)
	TI = 1;							// 使用printf()的需要

	Ticks = 0;     //中断定时 次数判断
	TH0 = (65536 - (OSC / 12 / TPS)) / 256;	// T0 5ms中断定时常数高8位
	TL0 = (65536 - (OSC / 12 / TPS)) % 256;	// T0 5ms中断定时常数低8位
	ET0 = 1;							// 允许T0中断
	EA = 1;							// 打开总中断允许
	TR0 = 1;							// 启动T0

	printf("\r\nStart StopWatch...");

	POSPORT = 0xff;					// 关闭所有位置驱动
	CHARPORT = 0xff;					// 关闭所有的段驱动
	for (i = 0; i < 8; i++) DispBuf[i] = 0;	// 初始化显示缓冲区为全0
	DispBuf[2] = 16;
	DispBuf[5] = 16;						// 初始化时间串中间两个"-"的字形码位置  xx-xx-xx
	LEDPos = 0;						// 准备从最左边刷新显示
	state = 0;						//初始空闲状态
	endflag = 0;					//结束标志为0
	startflag = 0;					//开始标志为0
	hour = 0;						//倒计时时间为0
	minute = 0;
	second = 0;
	viewstate();					//显示空闲状态LED
	P41 = !P41;						//关闭设置状态的LED

	while (1)
	{
		if (KeyPressed)
		{
			
			printf("\r\nKey Line%bd colum%bd pressed!", LineNum, ColNum);
			solveKey();
				printf("\r\n%bd  %bd  %bd", hour,minute,second);
				printf("\r\n%bd", state);
				KeyPressed = 0;
				
		}
	}
}

(2)处理键盘事件函数

//响应4x4键盘的事件
//00 加一秒    01 减一秒    02 切换空闲和设置状态  03 确认开始
//10 加一分钟  11 减一分钟  12 选择定时开          13 选择定时关
//21 加一小时  22 减一小时
void solveKey(void)
{
	if (LineNum == 0 && ColNum ==0)   //加1s
	{
		if (state == 1)  //只有设置状态才可以+1s
		{
			second++;
			if (second >= 60)
			{
				second -= 60;
				minute++;
				if (minute >= 60)
				{
					minute -= 60;
					hour++;
				}
			}
		}

	}
	else if (LineNum == 0 && ColNum == 1)   //减1s
	{
		if (state == 1)  //只有设置状态才可以-1s
		{
			second--;
			if (second < 0)
			{
				second += 60;
				minute--;
				if (minute < 0)
				{
					minute += 60;
					hour--;
				}
			}
		}
	}
	else if (LineNum == 1 && ColNum == 0)    //+1分钟
	{
		if (state == 1)  //只有设置状态才可以+1分钟
		{
			minute++;
			if (minute >= 60)
			{
				minute -= 60;
				hour++;
			}
		}

	}
	else if (LineNum == 1 && ColNum == 1)    //-1分钟
	{
		if (state == 1)  //只有设置状态才可以-1分钟
		{
			minute--;
			if (minute < 0)
			{
				minute += 60;
				hour--;
			}
		}

	}
	else if (LineNum == 2 && ColNum == 0)   //+1小时
	{
		if (state == 1)
		hour++;
	}
	else if (LineNum == 2 && ColNum == 1)   //-1小时
	{
		if (state == 1)
		hour--;
	}
	else if (LineNum == 0 && ColNum == 2)   //切换系统状态,只有空闲状态和设置状态可以互相切换,定时状态要在设置状态下按下确认键进入
	{
		if (state == 0)
		{
			state = 1; viewstate();
		}
		else if (state == 1)
		{
				state = 0; viewstate();
		}
	}
	else if (LineNum == 0 && ColNum == 3)   //确认
	{
		startdo();
	}
	else if (LineNum == 1 && ColNum == 2)   //切换定时开
	{
			state = 2; viewstate();
	}
	else if (LineNum == 1&& ColNum == 3)   //切换定时关
	{
			state = 3; viewstate();
	}
	else  //按键按错了,无操作
	{

	}
}

(3) 定时中断函数

void T0ISR(void)	interrupt 1	      		// T0定时中断服务程序	
{
	TR0 = 0;								// 暂停T0计时
	TH0 = (65536 - (OSC / 12 / TPS)) / 256;	// 重装T0中断定时常数高8位
	TL0 = (65536 - (OSC / 12 / TPS)) % 256;	// 重装T0中断定时常数低8位
	TR0 = 1;							// 重启T0计时
	Ticks++;//中断计数 TPS每秒240次中断
/*	if ((Ticks == (TPS / 2)) || (Ticks == TPS))//Ticks 的值等于半秒(TPS / 2)或者1秒(TPS),则对 P40、P41、P42 和 P43 进行取反操作。
	{
		P40 = !P40;
		P41 = !P41;
		P42 = !P42;
		P43 = !P43;
	}
*/
	
	if (Ticks >= TPS)						// 如果计时满1秒
	{
		Ticks = 0;
		if (startflag == 1)
		{
			Secs--;							// 更新计时变量
			if (Secs == 0)
			{
				endflag = 1;
				enddo();
				hour = 0;
				minute = 0;
				second = 0;
				startflag = 0;
		
			}
		}
		
		UpdateDispBuf();					// 更新显示缓冲区
		getSecs();
		
	}

	RefreshLED();							// 执行每5ms刷新显示任务

	KeyScan();

}

(4)扫描键盘函数

void KeyScan(void)
{
	unsigned char tmp, cnt;

	LastScan = CurrScan;		//保存上一次的扫描结果。
	if (KeyDown)								// 如果上次按下的键没有释放
	{
		CurrScan = P1;					// 继续扫描该键位
		CurrScan &= 0xf0;				// 高四位为有效扫描返回值   11110000按位与操作会将 CurrScan 的低四位全部置为0,保留高四位不变。
		if ((CurrScan ^ LastScan) != 0)		// 表示按键释放了     在进行按位异或操作后,检查其结果是否不等于0   【当前扫描结果和上一次扫描结果是否有不同】
		{//不同
			KeyDown = 0;//无键按下
			KeyPressed = 1;//一次按键完成
			tmp = (~LastScan) & 0xf0; //保留高四位不变。
			for (cnt = 0; cnt < 4; cnt++)//确定按键对应的列号,并设置相应的按键状态
			{
				if (tmp == ColMask[cnt])
				{
					ColNum = cnt;//确定列号
					break;
				}
			}
		}
	}
	else if(KeyDown ==0&& KeyPressed == 0)						// 如果没有按键按下
	{
		LineNum = Ticks % 4;				// 每个5ms扫描行号加1,0~3循环
		P1 = ~LineMask[LineNum];		// P1低4位输出行扫描码,高4位输出1,准备输入
		_nop_(); _nop_(); _nop_(); _nop_();
		CurrScan = P1;
		CurrScan &= 0xf0;
		if (CurrScan != 0xf0)	KeyDown = 1;
	}
}

(5)更新显示缓冲区函数

void UpdateDispBuf(void)
{

	if (startflag == 1)
	{
		hour = Secs / 3600;
		minute = (Secs % 3600) / 60;
		second = (Secs % 3600) % 60;
		DispBuf[0] = hour / 10;
		DispBuf[1] = hour % 10;
		DispBuf[3] = minute / 10;
		DispBuf[4] = minute % 10;
		DispBuf[6] = second / 10;
		DispBuf[7] = second % 10;
	}
	else
	{
		DispBuf[0] = hour / 10;
		DispBuf[1] = hour % 10;
		DispBuf[3] = minute / 10;
		DispBuf[4] = minute % 10;
		DispBuf[6] = second / 10;
		DispBuf[7] = second % 10;
	}

(6)刷新数码管显示

void RefreshLED(void)
{
	POSPORT = 0xff;						//关闭所有LED
	CHARPORT = CharCode[DispBuf[LEDPos]];//根据 DispBuf 中的数据确定要显示的LED段码,并将其存储在 CHARPORT 中。
	POSPORT = ~PosMask[LEDPos];		//即打开对应LED的位置。 ~为按位取反
	LEDPos++;					//检查是否超过8,如果超过8则将 LEDPos 重置为0,以实现LED位置的循环显示。
	if (LEDPos >= 8)	LEDPos = 0;
}

6.实验结果

(1)初始化状态(空闲状态)LED0亮

(2)切换设置状态,可随意设置时间LED1亮

(3)选择定时开功能LED2亮。我们为了方便,设置7秒。

(4)定时开功能,过程中,LED0-3全灭

(5)倒计时结束结果LED0-3全亮

(6)同理,选择定时关功能,定时7秒。LED3亮

(7)定时关过程中,LED0-3全亮

(8) 定时关结果 LED0-3全灭

7.源代码

// 电子秒表
#include <stdio.h>
#include <intrins.h>
#include <stc/stc89c5xrc.h>

//******************************************************************************
// 宏定义晶振频率、串口波特率和基本时间片时长
// 关于基本时间片时长,原来的定义是200,即每秒200次定时中断,因此定时间隔Ticks为5ms
// 实际测试中发现5ms间隔下数码管显示有些闪烁,于是将TPS改为240,即每秒240次中断,
// 此时定时间隔Ticks为4.17ms,即显示刷新的速率从200次/秒提升为240次/秒,显著改善显示效果
//******************************************************************************
#define OSC		22118400     
#define	BAUD	9600
#define	TPS		240

//******************************************************************************
// LED位置控制(P2口):
//     P20 P21 P22 P23 P24 P25 P26 P27
// (左) 1   2   3   4   5   6   7   8 (右)
// LED段码控制(P0口):
// P07 P06 P05 P04 P03 P02 P01 P00
//  h   g   f   e   d   c   b   a
//******************************************************************************
#define	POSPORT		P2
#define	CHARPORT	P0

//表示状态		 0 空闲状态
//			1 设置状态
//			2 定时开状态  P4倒计时结束亮        
//			3 定时关状态  P4亮,倒计时结束灭
//			4 P4全灭
//			5 P4全亮
unsigned char	state; 

//倒计时结束标志 
//0 为未结束
//1 为结束
unsigned char	endflag;

//计时开始标志 
//0 为未开始
//1 为开始
unsigned char	startflag;

//蜂鸣器标志
unsigned char	BZIflag;

// 定义字形码,从0~F,以及"-"
unsigned char	code CharCode[] =
{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xa7,0xa1,0x86,0x8e,0xbf };
// 定义显示位置掩码
unsigned char	code	PosMask[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
// 定义行扫描位置掩码,行线依次输出低电平
unsigned char	code	LineMask[] = { 0x01,0x02,0x04,0x08 };
// 定义列输入位置掩码
unsigned char	code	ColMask[] = { 0x10,0x20,0x40,0x80 };

unsigned char	LEDPos;						// LED刷新显示位置,0~7,对应左~右
unsigned char	Ticks;						// 中断计数,满TPS次为1秒
unsigned char	hour, minute, second;			// 定义时分秒变量
unsigned char	DispBuf[8];					// 定义显示缓冲区,内容为时间串,格式为00-00-00
unsigned long	Secs;						// 总计秒数,累加

//******************************************************************************
// 行列式键盘控制(P1口):
//	P10	P11	P12	P13	P14	P15	P16	P17
//	行0 行1	行2	行3	列0	列1	列2	列3
// 行线依次输出0,列线输入,P1读入的高4位不为全1表示有键按下
//******************************************************************************
bit	KeyDown;								// 扫描判断有按键按下=1,否则=0
bit	KeyPressed;								// 扫描判断有按键按下后再释放,表示一次按键动作完成

	// 按下的按键编号(高4位表示读入的按键列、低4位表示输出的按键行)
unsigned char	KeyCode[4][4] = 
{ 0x00,0x01,0x02,0x03,
  0x10,0x11,0x12,0x13,
  0x20,0x21,0x22,0x23,
  0x30,0x31,0x32,0x33,
};				
unsigned char	LineNum;					// 存放扫描行计数,取值范围0~3
unsigned char	ColNum;						// 存放按键列编号,取值范围0~3
unsigned char	CurrScan, LastScan;			// 存放本次扫描和上次扫描结果

/*******************************************************************************
函数名:UpdateDispBuf
功  能:每一秒调用一次,更新时间显示缓冲区
参  数:无,操作全局变量
返  回:无
*******************************************************************************/
void UpdateDispBuf(void)
{

	if (startflag == 1)
	{
		hour = Secs / 3600;
		minute = (Secs % 3600) / 60;
		second = (Secs % 3600) % 60;
		DispBuf[0] = hour / 10;
		DispBuf[1] = hour % 10;
		DispBuf[3] = minute / 10;
		DispBuf[4] = minute % 10;
		DispBuf[6] = second / 10;
		DispBuf[7] = second % 10;
	}
	else
	{
		DispBuf[0] = hour / 10;
		DispBuf[1] = hour % 10;
		DispBuf[3] = minute / 10;
		DispBuf[4] = minute % 10;
		DispBuf[6] = second / 10;
		DispBuf[7] = second % 10;
	}
}

/*******************************************************************************
函数名:RefreshLED
功  能:每5ms调用一次,更新1位LED显示内容
参  数:无,操作全局变量
返  回:无
*******************************************************************************/
void RefreshLED(void)
{
	POSPORT = 0xff;						//关闭所有LED
	CHARPORT = CharCode[DispBuf[LEDPos]];//根据 DispBuf 中的数据确定要显示的LED段码,并将其存储在 CHARPORT 中。
	POSPORT = ~PosMask[LEDPos];		//即打开对应LED的位置。 ~为按位取反
	LEDPos++;					//检查是否超过8,如果超过8则将 LEDPos 重置为0,以实现LED位置的循环显示。
	if (LEDPos >= 8)	LEDPos = 0;
}

/*******************************************************************************
函数名:KeyScan
功  能:每5ms调用一次,处理按键扫描
参  数:无,操作全局变量KeyPressed、KeyNum
返  回:无
*******************************************************************************/
void KeyScan(void)
{
	unsigned char tmp, cnt;

	LastScan = CurrScan;		//保存上一次的扫描结果。
	if (KeyDown)								// 如果上次按下的键没有释放
	{
		CurrScan = P1;					// 继续扫描该键位
		CurrScan &= 0xf0;				// 高四位为有效扫描返回值   11110000按位与操作会将 CurrScan 的低四位全部置为0,保留高四位不变。
		if ((CurrScan ^ LastScan) != 0)		// 表示按键释放了     在进行按位异或操作后,检查其结果是否不等于0   【当前扫描结果和上一次扫描结果是否有不同】
		{//不同
			KeyDown = 0;//无键按下
			KeyPressed = 1;//一次按键完成
			tmp = (~LastScan) & 0xf0; //保留高四位不变。
			for (cnt = 0; cnt < 4; cnt++)//确定按键对应的列号,并设置相应的按键状态
			{
				if (tmp == ColMask[cnt])
				{
					ColNum = cnt;//确定列号
					break;
				}
			}
		}
	}
	else if(KeyDown ==0&& KeyPressed == 0)						// 如果没有按键按下
	{
		LineNum = Ticks % 4;				// 每个5ms扫描行号加1,0~3循环
		P1 = ~LineMask[LineNum];		// P1低4位输出行扫描码,高4位输出1,准备输入
		_nop_(); _nop_(); _nop_(); _nop_();
		CurrScan = P1;
		CurrScan &= 0xf0;
		if (CurrScan != 0xf0)	KeyDown = 1;
	}
}
//显示状态LED  P4
void viewstate(void)
{
	switch (state)
	{
	case 0://0号灯亮
		P40 = !P40;
		P41 = !P41;

		break;
	case 1: //1号灯亮
		P40 = !P40;//把第一个led灭了
		P41 = !P41;

		break;
	case 2: //2号灯亮

		P41 = !P41;
		P42 = !P42;

		break;
	case 3: //3号灯亮

		P41 = !P41;

		P43 = !P43;
		break;
	case 4: //保持不变
		P40 = P40;
		P41 = P41;
		P42 = P42;
		P43 = P43;
		break;

	}
			
}
//时分秒转化总数
void getSecs()
{
	Secs = hour * 3600 + minute * 60 + second;
}
//定时关和开 开始
void startdo()
{
	if (state == 2)//定时开功能
	{
		P42 = !P42;
		
	}
	else if (state == 3)//定时关功能
	{
		P40 = !P40;
		P41 = !P41;
		P42 = !P42;
		
	}
	startflag = 1;
}

//定时关和开 结束
void enddo()
{
	if (endflag == 1 && state == 2)
	{
		P40 = !P40;
		P41 = !P41;
		P42 = !P42;
		P43 = !P43;
		
		

	}
	else if (endflag == 1 && state == 3)
	{
		P40 = !P40;
		P41 = !P41;
		P42 = !P42;
		P43 = !P43;
		
	}
		
}


/*******************************************************************************
函数名:T0ISR
功  能:通过T0的中断方式计时
参  数:
返  回:
*******************************************************************************/
void T0ISR(void)	interrupt 1	      		// T0定时中断服务程序	
{
	TR0 = 0;								// 暂停T0计时
	TH0 = (65536 - (OSC / 12 / TPS)) / 256;	// 重装T0中断定时常数高8位
	TL0 = (65536 - (OSC / 12 / TPS)) % 256;	// 重装T0中断定时常数低8位
	TR0 = 1;							// 重启T0计时
	Ticks++;//中断计数 TPS每秒240次中断
/*	if ((Ticks == (TPS / 2)) || (Ticks == TPS))//Ticks 的值等于半秒(TPS / 2)或者1秒(TPS),则对 P40、P41、P42 和 P43 进行取反操作。
	{
		P40 = !P40;
		P41 = !P41;
		P42 = !P42;
		P43 = !P43;
	}
*/
	
	if (Ticks >= TPS)						// 如果计时满1秒
	{
		Ticks = 0;
		if (startflag == 1)
		{
			Secs--;							// 更新计时变量
			if (Secs == 0)
			{
				endflag = 1;
				enddo();
				hour = 0;
				minute = 0;
				second = 0;
				startflag = 0;
				BZIflag = 1;
		
			}
		}
		if (BZIflag == 1)
		{
			P32 = !P32;
		}
		
		UpdateDispBuf();					// 更新显示缓冲区
		getSecs();
		
	}

	RefreshLED();							// 执行每5ms刷新显示任务

	KeyScan();

}

//响应4x4键盘的事件
//00 加一秒    01 减一秒    02 切换空闲和设置状态  03 确认开始
//10 加一分钟  11 减一分钟  12 选择定时开          13 选择定时关
//21 加一小时  22 减一小时
void solveKey(void)
{
	if (LineNum == 0 && ColNum ==0)   //加1s
	{
		if (state == 1)  //只有设置状态才可以+1s
		{
			second++;
			if (second >= 60)
			{
				second -= 60;
				minute++;
				if (minute >= 60)
				{
					minute -= 60;
					hour++;
				}
			}
		}

	}
	else if (LineNum == 0 && ColNum == 1)   //减1s
	{
		if (state == 1)  //只有设置状态才可以-1s
		{
			second--;
			if (second < 0)
			{
				second += 60;
				minute--;
				if (minute < 0)
				{
					minute += 60;
					hour--;
				}
			}
		}
	}
	else if (LineNum == 1 && ColNum == 0)    //+1分钟
	{
		if (state == 1)  //只有设置状态才可以+1分钟
		{
			minute++;
			if (minute >= 60)
			{
				minute -= 60;
				hour++;
			}
		}

	}
	else if (LineNum == 1 && ColNum == 1)    //-1分钟
	{
		if (state == 1)  //只有设置状态才可以-1分钟
		{
			minute--;
			if (minute < 0)
			{
				minute += 60;
				hour--;
			}
		}

	}
	else if (LineNum == 2 && ColNum == 0)   //+1小时
	{
		if (state == 1)
		hour++;
	}
	else if (LineNum == 2 && ColNum == 1)   //-1小时
	{
		if (state == 1)
		hour--;
	}
	else if (LineNum == 0 && ColNum == 2)   //切换系统状态,只有空闲状态和设置状态可以互相切换,定时状态要在设置状态下按下确认键进入
	{
		if (state == 0)
		{
			state = 1; viewstate();
		}
		else if (state == 1)
		{
				state = 0; viewstate();
		}
	}
	else if (LineNum == 0 && ColNum == 3)   //确认
	{
		startdo();
	}
	else if (LineNum == 1 && ColNum == 2)   //切换定时开
	{
			state = 2; viewstate();
	}
	else if (LineNum == 1&& ColNum == 3)   //切换定时关
	{
			state = 3; viewstate();
	}
	else  //按键按错了,无操作
	{

	}

}

void main(void)
{
	int i;

	// 初始化串行口(T1)和T0
	TMOD = 0x21;						// T1,工作方式2,8位自动重装计数器;T0,工作方式1,16位计数器,软件重装
	PCON |= 0x80;						// SMOD = 1
	SCON = 0x50;						// 串口模式1,允许接收
	TH1 = 256 - (OSC / 12 / 16 / BAUD);		// 9600bps,N81   数据格式为N81(无校验位,8位数据位,1位停止位)。
	TL1 = 256 - (OSC / 12 / 16 / BAUD);
	TR1 = 1;							// 启动串口(T1)
	TI = 1;							// 使用printf()的需要

	Ticks = 0;     //中断定时 次数判断
	TH0 = (65536 - (OSC / 12 / TPS)) / 256;	// T0 5ms中断定时常数高8位
	TL0 = (65536 - (OSC / 12 / TPS)) % 256;	// T0 5ms中断定时常数低8位
	ET0 = 1;							// 允许T0中断
	EA = 1;							// 打开总中断允许
	TR0 = 1;							// 启动T0

	printf("\r\nStart StopWatch...");

	POSPORT = 0xff;					// 关闭所有位置驱动
	CHARPORT = 0xff;					// 关闭所有的段驱动
	for (i = 0; i < 8; i++) DispBuf[i] = 0;	// 初始化显示缓冲区为全0
	DispBuf[2] = 16;
	DispBuf[5] = 16;						// 初始化时间串中间两个"-"的字形码位置  xx-xx-xx
	LEDPos = 0;						// 准备从最左边刷新显示
	state = 0;						//初始空闲状态
	endflag = 0;					//结束标志为0
	startflag = 0;					//开始标志为0
	BZIflag = 0;					//蜂鸣器标志为0
	hour = 0;						//倒计时时间为0
	minute = 0;
	second = 0;
	viewstate();					//显示空闲状态LED
	P41 = !P41;						//关闭设置状态的LED

	while (1)
	{
		if (KeyPressed)
		{
			
			printf("\r\nKey Line%bd colum%bd pressed!", LineNum, ColNum);
			solveKey();
				printf("\r\n%bd  %bd  %bd", hour,minute,second);
				printf("\r\n%bd", state);
				KeyPressed = 0;
				
		}
	}
}

物联沃分享整理
物联沃-IOTWORD物联网 » 南邮单片机设计小型定时开关控制系统

发表评论