⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 LCD1602.rar
💻 C
字号:
//*************************************************************************************************
//*************************************************************************************************
//**<程序名>:多功能计算器																		 **
//**<功能>:可以进行6位数以内正整数的加减乘除运算,以及计时器和自定义倒计时功能					 **
//**<作者>:LastRitter																			 **
//**<完成时间>:2007年7月30日																	 **
//**<联系方式>:superyongzhe@163.com															 **
//*************************************************************************************************
//*************************************************************************************************


//*************************************************************************************************
//*																								  *
//*			 ******************************头文件及宏定义**************************				  *
//*																								  *
//*************************************************************************************************
#include "includes.h"

#define TIME0H 0xFC
#define TIME0L 0x18		//定时器0溢出时间:5ms

#define TIME1H 0x44
#define TIME1L 0x80		//定时器1溢出时间:48ms


//*************************************************************************************************
//*																								  *
//*			  ********************************全局变量******************************			  *
//*																								  *
//*************************************************************************************************

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0定时刷新LED计数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unsigned long ul_Number=0;			//LCD实时显示数字。

unsigned char uca_ShowCustom[6]={0x88,0x83,0xC6,0xA1,0x86,0x84};
									//存放自定义显示字符。

unsigned char uc_DisCount=1;		//LCD时事刷新计数。

bit b_ShowMode=0;					//显示模式标志位。
									//0--数字模式,将要显示的数字赋给ul_Number便可时事显示数值,
									//				默认为数字模式;
									//1--自定义模式,该模式下自定义字符显示。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器1计数刷新定时(计时模式)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unsigned char uc_TimeCount=1;		//定时器1定时计数。

bit b_ClockStart=0;					//定时器1显示计数标志位。

extern bit b_ClockOppose;			//TimeOppose.c

extern unsigned long ul_ClockOppose;


//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<防抖动标志>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

bit b_KeyShock=0;	  				//键盘防抖动标志位。
									//当按键中断产生时,首先判断此位。
									//0--执行键盘扫描及键码处理程序;1--不执行。

bit b_KillShock=0;					//防抖标志清除位:0--不清除;1--清除。

unsigned char uc_KillCount=1;		//抖动标志清除计数,使用定时器1。


//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LCD闪烁显示报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bit b_LCDClean=0;					  //通过设置b_LCDClean为1便可启动延时清空LCD显示。

unsigned char uc_CleanCount=1;		  //延迟时间可在T1中断中设定。


unsigned char uc_ReportSymbol;

bit b_ReportFlash=0;

unsigned char uca_FlashBlank[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};


//*************************************************************************************************
//*																								  *
//*			  ********************************主函数******************************				  *
//*																								  *
//*************************************************************************************************
void main()
{
	P2=0x0F;		  //初始化键盘接口。

	TMOD=0x11;		  //定时器0:模式一;定时器0:模式一.


//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0,用于LCD刷新>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	TH0=TIME0H;
	TL0=TIME0L;
	TR0=1;			 //开启定时器0
	ET0=1;			 //开定时器0中断


//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器1,用于1s计时 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	TH1=TIME1H;
	TL1=TIME1L;
	TR1=1;			 //开启定时器1
	ET1=1;			 //开定时器1中断


//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<外部中断0,用于执行键盘扫描和键处理程序>>>>>>>>>>>>>>>>>>>>>>>>>>>
	IT0=1;			 //外部中断0,中断方式:下降沿
	EX0=1;			 //开启外部中断0

	PT0=1;			 //把定时器0溢出中断设为高优先级。

	EA=1;			 //开启总中断

	while(1);
}



//*************************************************************************************************
//*																								  *
//*		***************************外部中断0,调用键盘扫描程序*************************			  *
//*																								  *
//*************************************************************************************************
void vINT0(void) interrupt 0
{
	EX0=0;			 				//在键扫描处理时,关闭外部中断0,防抖动。

	if(b_KeyShock==0)
		{
		vKeyProcess(ucKeyScan());	//当判断有按键按下时,扫描键盘,并把扫描结果进行处理。
		b_KeyShock=1;					//设置防抖动标志。
		}
	else b_KeyShock=0;				//如果有抖动则不执行键扫描,恢复防抖动标志。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<设置防抖动清除标志位 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>	
	if(b_KeyShock==1)
		b_KillShock=1;				//如果防抖动标志位开启则开启防抖动标志清除位,
									//300ms后清除防抖动标志。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<恢复键扫描处理前初始状态 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	P2=0x0F;	  					//恢复P2口。
	EX0=1;							//恢复按键中断。
}


//*************************************************************************************************
//*																								  *
//*		****************定时器1中断,用于计时功能和防抖动标志清除以及显示报告****************	  *
//*																								  *
//*************************************************************************************************
void vTimer1(void) interrupt 3
{
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<计时模式计数刷新>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	if(b_ClockStart==1)					//当计时模式开启式,如计时处于运行状态则执行定时计数增加。
		{
		if(b_ClockOppose==0)			//正常计时。
			{
			if(uc_TimeCount%21==0)
				{
				uc_TimeCount=1;
				ul_Number++;
				}
			else uc_TimeCount++;
			}
		else
			{							  //倒计时模式。
			if(uc_TimeCount%21==0)
				{
				uc_TimeCount=1;
				if(ul_ClockOppose>0)
					{
					ul_ClockOppose--;
					ul_Number=ul_ClockOppose;
					}
				else
					{
					b_ClockStart=0;
					uc_ReportSymbol=7;
					b_LCDClean=1;
					}
				}
			else uc_TimeCount++;
			}
		}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<防抖动标志清除>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	if(b_KillShock==1)
		{
		if(uc_KillCount%5==0)			 //当防抖动标志位为1时,计时300ms后清除抖动标志位。
			{
			b_KeyShock=0;
			b_KillShock=0;
			uc_KillCount=1;
			}
		else uc_KillCount++;
		}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LCD显示报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	if(b_LCDClean==1)
		{
			if(uc_CleanCount==1)
				{
					EX0=0;							//关闭键盘中断,此时按键无效。
					vShowReport(uc_ReportSymbol);
					b_ShowMode=1;
				}
			if(uc_CleanCount%40==0)					//通过设置b_LCDClean为1便可启动延时清空LCD显示。
				{
					b_LCDClean=0;					//关闭清零标志位,清零结束。
					uc_CleanCount=1;				//恢复清零计数为初始值1.
					b_ShowMode=0;					//恢复显示模式为默认的数字模式。
					b_ReportFlash=0;
					EX0=1;							//重新开启键盘中断。
				}
			else 
				{
				//<<<<<<<<<<<<<<<<<<<<<<<<<实现闪烁报告功能>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				if(uc_CleanCount%7==0)														
					{
						if(b_ReportFlash==0)
							{
								vCharCopy(uca_FlashBlank);
								b_ReportFlash=1;
							}
						else 
							{
								vShowReport(uc_ReportSymbol);
								b_ReportFlash=0;
							}
					 }
			uc_CleanCount++;
				}
		}

	TH1=TIME1H;
	TL1=TIME1L;

}


//*************************************************************************************************
//*																								  *
//*		***************************定时器0,定时刷新LED*************************				  *
//*																								  *
//*************************************************************************************************
void vTimer0(void) interrupt 1
{
	if(b_ShowMode==0)
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<数字模式>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		{
		vShowOneNum(*(pucLedNum(ul_Number)+uc_DisCount),6-uc_DisCount);	   //在LCD上显示1位数字。
		if(uc_DisCount==5)
		uc_DisCount=0;						//定时器0在每次被触发时,改变LCD显示。
		else uc_DisCount++;					//从第一位到第六位循环显示。
		}
	else
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<自定义模式>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		{
		vShowCustom(uca_ShowCustom[uc_DisCount],uc_DisCount);
		if(uc_DisCount==5)
		uc_DisCount=0;						//定时器0在每次被触发时,改变LCD显示。
		else uc_DisCount++;					//从第一位到第六位循环显示。
		}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<恢复定时器0初始状态 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	TH0=TIME0H;	
	TL0=TIME0L;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -