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

📄 nedu_sub_state.c.bak

📁 一个基于单片机的小型操作系统
💻 BAK
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************************
*                 东软培训中心教学项目:基于ARM和uc/os-II的PDA系统
*
*                      (c) Copyright 2005, 东软培训中心
*                             All Rights Reserved
*
* 模块名称:状态子机模块
* 文件名:NEDU_SUB_STATE.C
* 作者:朱成果
* 修改: 孙周旋,邹海英,胡仲华,曹攀
* 时间:2005年11月9日 
* 版本:V0.01
**********************************************************************************************************************
*/
#include "def.h"
#include "44b.h"
#include "uhal.h"
#include "driven.h"
#include "ucos_ii.h"
#include <string.h>
#include <stdio.h>

extern U8 state,esc,RTC[8],number,numlock;
extern U32 Sub_Mode;
//extern unsigned char DATABUFF[0x4200];
extern char intstr[9];
extern RTC_REG RTC_data, RTC_Sdata;
extern U32 ReadFile(FILECNT *,U8 * ReadBuffer,U32 nReadByte);
extern FILECNT * OpenFile(char filename[],U32 OpenMode);
extern RECLIST GetToken(void);
extern FILECNT *pfile;
extern int GetMaxLine(unsigned char buffer[]);
extern unsigned char buffer[100];
extern int InsertALine(FILECNT * file,char filename[],RECLIST rcd);
extern int DeleteLine(FILECNT * file,char filename[],int line);

/*
**********************************************************************************************************************
*                      GETDATE
*
* 作者:胡仲华 曹攀
*
* 时间:2007年7月3日
*
* 描述:计算指定年月的天数和第一天是星期几,
*				利用蔡勒(Zeller)公式计算指定年月的第一天是星期几。
*				蔡勒(Zeller)公式只适合于1582年10月15日之后的情形。
*
* 参数:	int year		:指定的年份
*		int month		:指定的月份
*		int *week	:储存第一天星期几的变量的地址
*		int *days		:储存本月有几天的变量的地址
*
* 返回值:在*week和*days变量中
* 
***********************************************************************************************************************
*/
void getDate(int year,int month,int *week,U8 *days)
{
	int c;					//年份前两位
	int y;					//年份后两位
	int d=1;				//日数
	int bool;				//是否闰年
	
	/************计算本月有几天*************/
	bool=(0 == (year%4)) && ((year%100) != 0) || (0 == (year%400));
	switch(month)
	{
		case 1:	*days=31;				//1月31天
				break;
		case 3:	*days=31;				//3月31天
				break;
		case 5:	*days=31;				//5月31天
				break;
		case 7:	*days=31;				//7月31天
				break;
		case 8:	*days=31;				//8月31天
				break;
		case 10:	*days=31;				//10月31天
				break;
		case 12:	*days=31;				//12月31天
				break;
		case 4:	*days=30;				//4月31天
				break;
		case 6:	*days=30;				//6月31天
				break;
		case 9:	*days=30;				//9月31天
				break;
		case 11:	*days=30;				//11月30天
				break;
		case 2:	if(bool)
					*days=29;			//闰年2月29天
				else
					*days=28;			//非闰年2月28天
				break;
	}
	
	/*******计算本月第一天是星期几********/
	//如果月份为1月或者2月,则分别按上一年的13月和14月计算
	if(month<3)
	{
		year -= 1;
		month += 12;
	}
	c=year/100;			//得到年份前两位
	y=year%100;			//得到年份后两位

	*week=(year+year/4+c/4-2*c+26*(month+1)/10+d-2)%7	;			//蔡勒(Zeller)公式.
       return;
}
/*
*****************************************************************************************
*                   		AddToRTC
*
* 作者:胡仲华 曹攀
*
* 时间:2007年7月5日
*
* 描述:将获得的有效按键值存入全局变量RTC数组中
*		并自动处理越界问题。
*	
* 参数:U8 key	:获得的按键值
*		int *point	:当前输入指针变量的地址
*		
* 返回值:在全局变量RTC数组中
* 
*****************************************************************************************
*/
void AddToRTC(U32 key,int *point,char *str)
{
	int year,month,week;
	U8 num,days;
	
	num = key & 0x0f;
	if(12 > *point)
	{	switch(*point)
		{
			case 0:	RTC[0] = (RTC[0]&0x0f) | (num<<4);		//保存年份高位
					*str = key;
					(*point)++;
					break;
			case 1:	RTC[0] = (RTC[0]&0xf0) | num;			//保存年份低位
					*(str+1) = key;
					(*point)++;
					break;
			case 2:	if(num > 1)
					{
						RTC[1] = (RTC[1]&0x00) | num;		//月份高位不能大于1,如果大于1则自动将值作为月份,跳转到日期输入
						*(str+2) = '0';
						*(str+3) =key;
						(*point) += 2;
						break;
					}
					else
					{
						RTC[1] = (RTC[1]&0x0f) | (num<<4);	//保存月份高位.
						*(str+2) = key;
						(*point)++;
						break;
					}
			case 3:	RTC[1] = (RTC[1]&0xf0) | num;		//保存月份低位.
					*(str+3) = key;
					(*point)++;
					if(RTC[1] > 0x12)					//月份大于12,则按12月算
					{
						RTC[1] = 0x12;
						*(str+3) = '2';
					}
					if(RTC[1] < 0x01)					//月份小于1,则按1月算
					{
						RTC[1] = 0x01;
						*(str+3) = '1';
					}	
					break;
			case 4:	if(num > 3)
					{
						RTC[2] = (RTC[2]&0x00) | num;		//日期高位不能大于3,如果大于3则自动将该值作为日期,跳转到时间输入
						*(str+4) = '0';
						*(str+5) =key;
						(*point) += 2;
						break;
					}
					else
					{
						RTC[2] = (RTC[2]&0x0f) | (num<<4);//保存日期高位.
						*(str+4) = key;
						(*point)++;
						break;
					}
			case 5:	RTC[2] = (RTC[2]&0xf0) | num;			//保存月份低位.
					*(str+5) = key;
					(*point)++;
					year=(int)HexToInt(0x2000|RTC[0]);
					month=(int)HexToInt(RTC[1]);
					getDate(year,month,&week,&days);
					if(RTC[2] > IntToHex(days))			//日期大于本月天数,则按最后一天算
					{	
						RTC[2] = IntToHex(days);
						BCDU8toAsc(days);
						*(str+4) = intstr[0];
						*(str+5) = intstr[1];
					}
					if(RTC[2] < 0x01)						//日期小于1,则按1号算
					{	
						RTC[2] = 0x01;
						*(str+4) = '0';
						*(str+5) = '1';
					}
					break;
			case 6:	if(num > 2)
					{
						RTC[4] = (RTC[4]&0x00) | num;
						*(str+6) = '0';
						*(str+7) =key;
						(*point) += 2;
						break;
					}
					else
					{
						RTC[4] = (RTC[4]&0x0f) | (num<<4);
						*(str+6) = key;
						(*point)++;
						break;
					}
			case 7:	RTC[4] = (RTC[4]&0xf0) | num;
					*(str+7) = key;
					(*point)++;
					if(RTC[4] > 0x23)						//小时数不能大于23,24点按0点算
					{	
						RTC[4] = 0x23;
						*(str+6) = '2';
						*(str+7) = '3';
					}
					break;
			case 8:	if(num > 5)
					{
						RTC[5] = (RTC[5]&0x00) | num;
						*(str+8) = '0';
						*(str+9) =key;
						(*point) += 2;
						break;
					}
					else
					{
						RTC[5] = (RTC[5]&0x0f) | (num<<4);
						*(str+8) = key;
						(*point)++;
						break;
					}
			case 9:	RTC[5] = (RTC[5]&0xf0) | num;
							*(str+9) = key;
							(*point)++;
							break;
			case 10:	if(num > 5)
					{
						RTC[6] = (RTC[6]&0x00) | num;
						*(str+10) = '0';
						*(str+11) =key;
						(*point) += 2;
						break;
					}
					else
					{
						RTC[6] = (RTC[6]&0x0f) | (num<<4);
						*(str+10) = key;
						(*point)++;
						break;
					}
			case 11:	RTC[6] = (RTC[6]&0xf0) | num;
						*(str+11) = key;
						(*point)++;
						break;
		}//end switch
	}//end if
}
/*
*****************************************************************************************
*                   		DelRTC
*
* 作者:胡仲华 曹攀
*
* 时间:2007年7月5日
*
* 描述:将之前的数字删除
*	
* 参数:int *point	:当前输入指针变量的地址
*		
* 返回值:在全局变量RTC数组中
* 
*****************************************************************************************
*/
void DelRTC(int *point)
{	int a,c;
	if(0 < *point)
	{
		(*point)--;
		a=(*point)/2;
		c=(*point)%2;
		if(a>2)
			a++;
		if(c)
			RTC[a] &= 0xf0;
		else
			RTC[a] &= 0x00;
	}
}
/*
**********************************************************************************************************************
*                       RTCSETDISPLAY
*
* 作者:胡仲华 曹攀
*
* 时间:2007年7月5日
*
* 描述:子状态机。把键盘任务传送的字节流自动按BCD格式保存到公共数组RTC中,供Rtc_set()函数使用。
*	 
* 参数:无。
*
* 返回值:无。
* 
***********************************************************************************************************************
*/
void RTC_Set_Display(void)
{
	OS_CPU_SR  cpu_sr;
	
	U32 bcolor=0xff;						//背景色
	U32 fcolor=0x00;						//前景色
	U32* pList_y=(U32*)0x0c005e08;		//显示指针 
	U32* pList_t=(U32*)0x0c005e08+22;		//显示指针
	U32 r_offset=0x820;					//条目间距
	int point = 0;
	int i;
	char RTCS[12];							//显示缓冲区
	U32* Location[12];
	
	for(i = 0;i < 12;i++)
		RTCS[i] = 0x0;				//清空RTCS数组
	for(i = 0;i < 7;i++)
		RTC[i] = 0x00;				//清空RTC数组
	Location[0] = pList_y;
	Location[1] = pList_y+2;
	Location[2] = pList_y+r_offset;
	Location[3] = pList_y+r_offset+2;
	Location[4] = pList_y+2*r_offset;
	Location[5] = pList_y+2*r_offset+2;
	Location[6] = pList_t;
	Location[7] = pList_t+2;
	Location[8] = pList_t+r_offset;
	Location[9] = pList_t+r_offset+2;
	Location[10] = pList_t+2*r_offset;
	Location[11] = pList_t+2*r_offset+2;
	
	LCD_Clear(CLR_ALL);						//显示背景
	LCD_loard_tig(PDA_VERSION);
	LCD_loard_tig(PDA_SETRTC);
    
	OS_ENTER_CRITICAL();
	Sub_Mode = TCH_INVALIDE;
	OS_EXIT_CRITICAL(); 
	
	while(1)								//显示修改系统时间,当前修改的为黑底白字
		{	
			for(i = 0;i < point;i++)
			{
				intstr[0]=RTCS[i];
				intstr[1]=0x0;
				(void)LCD_Prints(intstr,fcolor,Location[i],bcolor);
			}
			(void)LCD_Prints(" ",0xff,Location[point],0x00);
			
			if(Sub_Mode == TCH_RETURN)		//返回
			{
				esc = ESCAP;
				OS_ENTER_CRITICAL();
				Sub_Mode = TCH_INVALIDE;
				OS_EXIT_CRITICAL();
				return;
			}
			if(Sub_Mode == TCH_K_ENTER)		//保存
			{
				if(RTC[2] == 0x00)
				{
					esc = ESCAP;
					OS_ENTER_CRITICAL();
					Sub_Mode = TCH_INVALIDE;
					OS_EXIT_CRITICAL();
					return;
				}
				esc = 0x00;
				OS_ENTER_CRITICAL();
				Sub_Mode = TCH_INVALIDE;
				OS_EXIT_CRITICAL(); 
				return;
			}
			if(Sub_Mode == TCH_K_Del)			//删除
			{
				DelRTC(&point);
				RTCS[point] = 0x0;
				LCD_Clear(CLR_ALL);				//显示背景
				LCD_loard_tig(PDA_VERSION);
				LCD_loard_tig(PDA_SETRTC);
			}
			else
			{
				if(0x30 <= Sub_Mode && Sub_Mode <= 0x39)
					AddToRTC(Sub_Mode,&point,RTCS);
			}
			
			OS_ENTER_CRITICAL();
			Sub_Mode = TCH_INVALIDE;
			OS_EXIT_CRITICAL(); 
			OSTimeDly(10);   
		}//end while
}
/*
**********************************************************************************************************************
*                       RECDISPLAY
*
* 作者:孙周旋
*
* 时间:2007年7月4日
*
* 描述:子状态机。显示客户记录等数据,每次一项,按"下一项","前一项","删除""返回"进行对应的操作。
*	 
* 参数:无。
*
* 返回值:如ManegeRec数组中条目为0,则直接返回;无返回值。
* 
***********************************************************************************************************************
*/
void REC_Display(void)
{
	OS_CPU_SR  cpu_sr;
	
	FILECNT * file;						//操作文件指针
	
	U32 index =0;							//指示文件需要操作的内容的索引
	U32 bcolor=0x00;						//背景色
	U32 fcolor=0xff;						//前景色
	U32 r_offset=0x820;					//条目间距
	U32* pList_r=(U32*)0x0c005a48;		//显示指针
	
	int i=0;							//加入删除时的状态
	
	RECLIST rcd;
	U8 * ReadBuffer;
	int line=0,maxLine=0;
	char filename[] = {'P','H','O','N','E','N','U','M','T','X','T'};
	LCD_Clear(CLR_ALL);				//显示背景
	LCD_loard_tig(PDA_VERSION);
	LCD_loard_tig(PDA_DISREC);

	file = OpenFile(filename,0);											//打开文件
	index = ReadFile(file,ReadBuffer,0);									//读文件
	maxLine = GetMaxLine((*file).Buffer);								//获取文件有效内容的行数
	
	//ClearREC();
	rcd = GetToken();														//获取需要读取的一条记录的name,telnum,plmnum和mail
	(void)LCD_Prints(rcd.name,fcolor,pList_r,bcolor);						//打印name到LCD
	(void)LCD_Prints(rcd.telnum,fcolor, pList_r+r_offset,bcolor);				//打印telnum到LCD
	(void)LCD_Prints(rcd.plmnum,fcolor, pList_r+(2*r_offset),bcolor);		//打印plmnum到LCD
	(void)LCD_Prints(rcd.mail,fcolor, pList_r+(3*r_offset),bcolor);			//打印mail到LCD
	
	OS_ENTER_CRITICAL();													//进入临界区
	Sub_Mode = TCH_INVALIDE;												//没有按任意有效动作区域时,子模式为TCH_INVALIDE
	OS_EXIT_CRITICAL(); 													//退出临界区
	if(maxLine>0){															//如果有记录
		while(1)
			{
				if(Sub_Mode == TCH_NEXT || Sub_Mode==TCH_K_3)										//如果敲击的是“下一条”
				{
					
					line++;														//将记录行号加一
					if(line>=maxLine){											//如果记录已经到了最后一行
						line = maxLine -1;										//那么将记录行停留在最后一行
					}
				
					index = ReadFile(file,ReadBuffer,line);						//按照当前的行号读取文件
				
	    				rcd =GetToken();											//获取当前需要读取的行的每个属性值(name,telnum,plmnum,mail)
	    				LCD_loard_tig(PDA_VERSION);									//将之前的显示内容清空
	    				LCD_loard_tig(PDA_DISREC);
	    
					(void)LCD_Prints(rcd.name,fcolor,pList_r,bcolor);  						//打印name到LCD
					(void)LCD_Prints(rcd.telnum,fcolor, pList_r+r_offset,bcolor);				//打印telnum到LCD
					(void)LCD_Prints(rcd.plmnum,fcolor, pList_r+(2*r_offset),bcolor);		//打印plmnum到LCD
					(void)LCD_Prints(rcd.mail,fcolor, pList_r+(3*r_offset),bcolor);			//打印mail到LCD
				
				}
				else if(Sub_Mode == TCH_PREV || Sub_Mode == TCH_K_9)												//如果敲击的是“上一条”
				{	
					if(line>0)																//如果行号大于1
						line--;															//即:当前显示的行不是首行那么巷号才能减一

			    		index = ReadFile(file,ReadBuffer,line);									//读取新的行
			    		//ClearREC();
	    				rcd =GetToken();														//获取当前需要读取的行的每个属性值(name,telnum,plmnum,mail)
	    				LCD_loard_tig(PDA_VERSION);												//将之前的显示内容清空
	    				LCD_loard_tig(PDA_DISREC);
	    
					(void)LCD_Prints(rcd.name,fcolor,pList_r,bcolor);  						//打印name到LCD
					(void)LCD_Prints(rcd.telnum,fcolor, pList_r+r_offset,bcolor);				//打印telnum到LCD
					(void)LCD_Prints(rcd.plmnum,fcolor, pList_r+(2*r_offset),bcolor);		//打印plmnum到LCD
					(void)LCD_Prints(rcd.mail,fcolor, pList_r+(3*r_offset),bcolor);			//打印mail到LCD
				
				}
				else if(Sub_Mode == TCH_RETURN || Sub_Mode == TCH_K_ENTER)						//如果敲击的是“返回”	
				{
					return;																	//返回到主页面
				}
				
				else if(Sub_Mode == TCH_DELETE || Sub_Mode == TCH_K_Del)						//如果敲击的是“删除/OK”
				{
					LCD_Clear(CLR_ALL);				//显示背景
					LCD_loard_tig(PDA_VERSION);
					LCD_loard_tig(PDA_DISREC);
					LCD_loard_tig(PDA_DEL);
					i=0;
					while(0==i)
					{
						OSTimeDly(200); 
						Uart_Printf("in del mode");
						if(Sub_Mode==TCH_DEL_YES || Sub_Mode==TCH_K_ENTER)
						{
							DeleteLine(file,filename,line);	
												
							maxLine = maxLine-1;
					
							if(line >= maxLine && line > 0)												//如果删除的是最后一行,那么显示它的上一行
							{
								line--;
							}						
							index = ReadFile(file,ReadBuffer,line);									//读取一行
			    			//ClearREC();
	    					rcd =GetToken();														//获取当前需要读取的行的每个属性值(name,telnum,plmnum,mail)
	    					if(maxLine<=0)															//如果已经删除到没有记录,那么显示“没有任何记录“页面
							{
								NoREC_Display();
								return;
							}
	    					
	    					else
	    					{
		    					LCD_loard_tig(PDA_VERSION);												//将之前的显示内容清空
		   						LCD_loard_tig(PDA_DISREC);
		    
								(void)LCD_Prints(rcd.name,fcolor,pList_r,bcolor);  						//打印name到LCD
								(void)LCD_Prints(rcd.telnum,fcolor, pList_r+r_offset,bcolor);			//打印telnum到LCD
								(void)LCD_Prints(rcd.plmnum,fcolor, pList_r+(2*r_offset),bcolor);		//打印plmnum到LCD
								(void)LCD_Prints(rcd.mail,fcolor, pList_r+(3*r_offset),bcolor);			//打印mail到LCD
								i=1;
							}
							
						}
						else	if(Sub_Mode==TCH_DEL_NO || Sub_Mode==TCH_RETURN)
						{
							LCD_Clear(CLR_ALL);				//显示背景
							LCD_loard_tig(PDA_VERSION);
							LCD_loard_tig(PDA_DISREC);		//显示记录页面
							
							index = ReadFile(file,ReadBuffer,line);
							rcd =GetToken();
							(void)LCD_Prints(rcd.name,fcolor,pList_r,bcolor);  						//打印name到LCD
							(void)LCD_Prints(rcd.telnum,fcolor, pList_r+r_offset,bcolor);			//打印telnum到LCD
							(void)LCD_Prints(rcd.plmnum,fcolor, pList_r+(2*r_offset),bcolor);		//打印plmnum到LCD

⌨️ 快捷键说明

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