📄 nedu_sub_state.c.bak
字号:
/*
*********************************************************************************************************************
* 东软培训中心教学项目:基于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 + -