01007019 张鹏.docx
《01007019 张鹏.docx》由会员分享,可在线阅读,更多相关《01007019 张鹏.docx(30页珍藏版)》请在冰豆网上搜索。
01007019张鹏
接口课程设计报告
------------------公司职员点到系统
计算机0205班张鹏012002007019
一.绪论
本系统利用接口电路实现公司职员点到系统的功能。
一个公司有一台总控机(本系统中的上位机),上面存储有整个公司职员的信息,其中包括出勤记录。
在总控机平台上可以实现对职员数据库的各种操作,比如添加,删除,修改,查询等。
有若干台分机(本系统中的下位机),分散在公司各个不同的地理位置。
分机与一些外部设备相连,这些外部设备可以是职员卡识别设备,也可以是职员指纹识别设备等。
外部设备实现对职员标识的录入,通过分机汇总到总控机。
总控机作出相应的处理后,控制分机对外设发出指示,使外设做出相应的声或光反应,以通知职员点到成功或者失败。
在这次课设中,以拨码开关模拟职员卡识别设备,或职员指纹识别设备。
以信号灯模拟外设的声光设备。
上位机存储公司职员信息,下位机从接口电路传送职员点到或离开的信号数据给上位机,上位机查询职员信息,若存在此职员,记录他的出勤情况,并通知下位机,下位机控制接口电路输出相应信号到信号灯;若不存在此职员上位机通知下位机输出相应的出错信息。
另外,上位机具有添加删除显示职员相关信息的丰富的菜单功能和各种状态显示功能。
二.设计内容
1.硬件连接(接口电路的设计),其中上位机所连的8255控制主机通信程序启停的为C口的pc2。
见程序staff_main()。
2.程序设计之通信程序
波特率均设为2400b/s,以查询方式进行全双工串行通信。
主要是对8251进行编程,上位机中与通信有关的函数如下
voidint51();初始化8251a;
voidset_bps(int);8253-5记数初值计算与装入;
intstaff_main();主管上位机与下位机双工通信。
下位机与通信有关的程序如下:
voidint51();初始化8251a;
voidset_bps(int);8253-5记数初值计算与装入;
主函数主管上位机与下位机双工通信。
3.程序设计之接口访问程序
对8251的访问见通信程序。
下面的程序主要是对两片8255芯片进行编程:
上位机:
sletter=inportb(0x300);
if((sletter&0x7f)==0){
outport(ctrl55,0x0c);/*关闭8253*/
getch();/*当与下位机相连的8255pc7置为0时*/
return0;}/*则退出界面程序*/
下位机:
voidalarm(intp)
{
inti=0;
while(i!
=10)
{
if(i%2!
=0)
{outportb(0x302,0xff);
delay(p);
}
else
{
outportb(0x302,0x7f);
delay(p);
}i++;
}
}/*根据时间值p的大小,决定信号灯闪的急缓。
*/
此外,在主函数中,if((inportb(0x302)&0x01)==0)
{
sletter=inportb(0x300);/*从a口读数据*/
……………….}
4.主控机删除,添加,修改,查询等职员信息管理程序:
数据结构:
structp{
charpresent_time[30];
structp*next;
};每名职员的出勤记录
structSS{
intstaff_id;
charstaff_name[30];
structp*header;
}staff[127];127名职员;
voidinit_staff();初始化structSSstaff[127]结构数组
voidadd_staff();添加职员;
voidshowpresent(int);显示职员号为i的职员的出勤记录;
intis_not(int)判断从下位机得到的职员号对应的职员是否存在;
voidshow();显示所有职员信息和某一个职员的出勤记录;
voiddelete_staff();删除职员;
voidset_staff();在初始时,添加若干原始的职员信息;
voidinsert(int,int,int);插入从下位机得到的某职员的出勤信息;
intcontrl(int,int);对voidinsert(intrdata,inti,intlocal)进行封装;
5.界面程序:
intinit();初始化屏显鼠标环境;
intread();读取鼠标位置;
voidcursor(),绘制光标;
voidnewxy();对光标实时刷新;
intget_key();读取键盘动作;
intget_item(int,int);识别键盘动作,转化为菜单选择;
voidMouse()识别鼠标动作,转化为菜单选择和相关命令。
main()函数中先初始化设备驱动,再屏显界面及菜单。
围绕个菜单功能分别调用相关函数,实现了上位机的功能(见功能描述)。
界面描述:
左边大块区域为操作向导和结果显示区;右上角为菜单区;右下角为工作区,显示上下位机的通信状态,正在点到的职员姓名和点到时间。
界面测试:
在main()函数中,将有两行星号处按注释修改,即在没有接口电路的情况下,可以实现菜单的功能。
6.系统操作方法:
按接口电路图连好线以后,运行上位机,下位机程序,将与上位机相连的8255的pc2置为1,下位机的8255的pA低6位为职员号位,高两位置为1
拨拨码开关输入职员号,两职员号输入的间隙必须将高两位中的一位置为0,断开通信通道,以得到正确的输入。
界面可以用键盘,亦可用鼠标,但暂时没实现快捷键。
键盘上的方向键可控制菜单的选择,当选择第一个菜单时,则使用鼠标,同时键盘不可用;鼠标每点击一次菜单,则最好再点击一次Clean
菜单,若退出鼠标操作,点击Quite菜单即可返回键盘菜单操作。
在添加职员信息时,必须将职员名字写完以后,再加按Ctrl-A。
三.实施步骤及分工
确定好设计题目后,第一步调试上位机与下位机的全双工通信。
第二步实现上位机对职员信息的管理功能。
第三步做好界面,将各函数嵌套到界面程序中。
第四步调试整个系统。
因为分工合作,所以这四步不一定按时间顺序实现。
同组为周慧娇,李怡林,詹尧天,分工如下:
周慧娇与李怡林共同负责双机通信,
系统完工后,负责了“白箱测试”。
詹尧天负责部分上位机职员信息管理函数以及下位机对外设(信号灯)的访问。
我做的工作有:
选题,确定接口电路,界面编写,各函数的整合,还有与他组员一起调试,DEBUG。
四.程序清单:
上位机程序:
#include
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineKB_S_N_DOWN80
#defineKB_S_N_UP72
#defineKB_S_N_ENTER28
#definePopWindow8
#defineWindowMinX0
#defineWindowMinY0
#defineWindowMaxX639
#defineWindowMaxY479
#include/*kbhit();*/
#include/*printf();*/
#include/*delay();*/
#include
#include
#include
#include
#definedata510x308/*8251A数据口*/
#definectrl510x309/*8251A命令/状态口*/
#definectrl550x303/*8255命令口*/
#definetimer20x306/*8253的2号计数器端口*/
#definetimctl0x307/*8253命令口*/
#definefactor16/*波特率因子16*/
unsignedlongintclk=1193182;/*8251输入时钟频率(十六进制表示)*/
/*定时常数数组*/
charstr[30];
structtimeb*time_b;
longtime_long;
intff1;
intff;
intbalala=0;/*ff1,ff,balala为一些控制变量*/
structp{
charpresent_time[30];
structp*next;
};/*职员出勤信息*/
structSS{
intstaff_id;
charstaff_name[30];
structp*header;
}staff[127];/*公司职员信息*/
voidint51();/*初始化8251a*/
voidset_bps(intbps);/*8253-5记数初值计算与装入*/
voidgetstr(){
intii;
for(ii=0;ii<30;ii++)
{if((int)(str[ii]=getch())==1)break;/*得到以Ctrl-A结束的字符串*/
}
str[ii]='\0';
}
voiddata_to_str(inti){
str[0]=(i/100+0x30);str[1]=((i%100)/10+0x30);str[2]=((i%10)+0x30);
str[3]='\0';
}
voidinit_staff(){
inti;
for(i=0;i<127;i++){
staff[i].staff_id=-1;/*职员不存在id==-1*/
if(!
staff[i].header){
staff[i].header=(structp*)malloc(sizeof(structp));}
}
}
intis_not(intrdata)/*判断职员存在吗*/
{if(staff[rdata].staff_id==-1)return-1;
elsereturn1;
}
voidadd_staff()
{inti=0,j;
str[0]='\0';
while(i<=127&&staff[i].staff_id!
=-1){i++;}/*分配一个空职员号*/
if(i>127)
{outtextxy(100,100,"themembersarefull!
");}
else
{
outtextxy(100,100,"Thenewstaff'sidis");
data_to_str(i);
outtextxy(250,100,str);
outtextxy(100,130,"now,inputthename:
");
getstr();
outtextxy(250,130,str);
staff[i].staff_id=i;/*分配一个空职员号*/
strcpy(staff[i].staff_name,str);
}
}
voidshowpresent(inti)
{structp*qqq=staff[i].header;
intjjj=0;
qqq=qqq->next;
while(qqq){
if(!
(jjj=jjj%8)){/*分屏显示*/
getch();
setfillstyle(1,BLACK);
bar(1,1,475,450);}
setcolor(WHITE);
outtextxy(30,100+jjj*20,staff[i].staff_name);
outtextxy(190,100+(jjj)*20,qqq->present_time);
jjj++;
qqq=qqq->next;}
}
voidshow(){
charch;
intii=0;
intiii=0;
outtextxy(100,100,"staffinfo:
1");
outtextxy(100,130,"presentinfo:
2");
ch=getch();
if(ch=='1'){
for(;ii<127;ii++){
if(!
(iii%8)){getch();setfillstyle(1,BLACK);
bar(1,1,475,450);iii=0;}
if(staff[ii].staff_id==-1)continue;
outtextxy(100,100+iii*20,staff[ii].staff_name);
iii++;
}
}
elseif(ch=='2'){
outtextxy(100,150,"inputtheid:
");
ch=getch();getch();
showpresent(ch-0x31);
}
}
voiddelete_staff()
{intk;
charch;
outtextxy(50,100,"pleasechoosetheidofthestaffyouwanttodelete:
");
ch=getch();
k=ch-0x30;
if(k<0||k>127||staff[k].staff_id==-1)
outtextxy(50,130,"Thestaffdoesnotexist!
");
else
{staff[k].staff_id=-1;/*deleted*/
/*释放header链表,暂不实现----zpdijkstra*/
outtextxy(50,130,"deleted!
");
}
}
voidset_staff(){
inti;
for(i=0;i<5;i++){
staff[i].staff_id=i+1;
}
strcpy(staff[0].staff_name,"zhouhuijiao");
strcpy(staff[1].staff_name,"liyilin");
strcpy(staff[2].staff_name,"zhanyaotian");
strcpy(staff[3].staff_name,"zhangpeng-zpdijkstra");
strcpy(staff[4].staff_name,"li-a-gen");
if(staff[i].header==NULL)staff[3].header=(structp*)malloc(sizeof(structp));;
}
voidinsert(intrdata,inti,intlocal){/*插入出勤信息*/
longtime_long;
structp*q;
q=staff[rdata-0x30].header;
while(q->next){q=q->next;}
q->next=(structp*)malloc(sizeof(structp));
q=q->next;
ftime(time_b);/*系统的时间函数*/
time_long=time_b->time;
if(i){strcpy(q->present_time,ctime(&time_long));
outtextxy(495,local,staff[rdata-0x30].staff_name);
outtextxy(490,local+10,q->present_time);/*显示在工作区*/
}
}
intcontrl(intrdata,intlocal){
if(is_not(rdata-0x30)==-1){
outtextxy(500,150+balala*25,"notexist!
!
");
return0;
}
elseif(is_not(rdata-0x30)==1){
insert(rdata,1,local);
return1;
}
}
voidhaha(){
inti,j=80;setcolor(GREEN);
for(i=100;i<700;i++){
setfillstyle(1,BLACK);
bar(1,1,475,450);
setcolor(GREEN);
if(i%2)j++;
circle(i,j*j/128,(500-i)/40);
delay(50);
}
}
intstaff_main()
{intgetvalue=0;
inttemp=-1;
intsletter,rletter,status;
charch[2];ch[1]='\0';
set_bps(2400);
int51();
outportb(0x303,0x91);
outportb(0x302,0xff);/*置PC6=1,打开8253-5的GATE2,开始输出方波*/
for(;;)/*判断是否iszero*/
{ff1=rletter;
ff=sletter;
if((inportb(0x302)&0x02)==0){return0;}/*若pc2为0,退出*/
if((inportb(0x302)&0x01)==0){
sletter=inportb(0x300);
if((sletter&0x7f)==0){/*若pa7为0,退出*/
outport(ctrl55,0x0c);/*关闭8253*/
getch();return0;}
else{
status=inportb(ctrl51);/*获取8251TXRDY状态*/
if((status&0x02)!
=0){
setcolor(GREEN);circle(480,300,6);/*显示正处于接收状态*/
rletter=inportb(data51);
if(ff1!
=rletter){/*不停的接收,要防止重复*/
ch[0]=rletter;balala++;
if(!
(balala=balala%10)){
setfillstyle(1,BLACK);
bar(481,155,636,450);}
outtextxy(485,155+balala*25,ch);
sletter=contrl(rletter,155+balala*25);/*通知下位机职员是否存在;*/
if((status&0x01)!
=0){/*发送已准备好,则将键入的字符发送出去*/
setcolor(RED);
circle(480,300,6);/*显示正处于发送状态*/
outportb(data51,2);
}
}
}
if((status&0x01)!
=0)/*发送已准备好,则将键入的字符发送出去*/
{if(ff!
=sletter){
setcolor(RED);circle(480,300,3);
outportb(data51,sletter);
}
}
}
}
}
return1;
}
voidint51()
{
outportb(ctrl51,0x00);
delay(100);
outportb(ctrl51,0x40);/*8251复位*/
delay(100);
outportb(ctrl51,0x4e);/*8251A方式命令*/
delay(100);
outportb(ctrl51,0x27);/*8251A工作命令*/
}
voidset_bps(intbps)
{
inti,sendhigh,sendlow;
i=clk/bps;
i=i/factor;/*计算计数初值*/
sendhigh=(i>>8)&0x00ff;
sendlow=i&0x00ff;
outportb(timctl,0xb6);
outportb(timer2,sendlow);/*装计数初值低字节*/
outportb(timer2,sendhigh);/*装计数初值高字节*/
}
unionREGSregs;
intmouse_i=1;
intinit();
intread();
voidcursor(),newxy();
intget_key();
intget_item(int,int);
void*buf_curse;
voidmain()
{
intdriver,mode;
introw,item_num,done,k,kkk;
intj,gdriver,gmode,size;
void*buf;
inti;
gdriver=DETECT;
/*registerbgidriver(EGAVGA_driver);有时是不必要的*/
initgraph(&gdriver,&gmode,"");
driver=DETECT;
mode=0;
init_staff();
set_staff();
MENU1:
/*registerbgidriver(EGAVGA_driver);*/
initgraph(&driver,&mode,"");
init(WindowMinY,WindowMaxX,WindowMinX,458);/*initisadefinedfunction*/
size=imagesize(0,0,150,22);/*countthebytesneedsfortheimage*/
if(size!
=1)/*ifitisn'tonlyonebyte*/
buf_curse=malloc(size);/*applytheramspace*/
/*getlighbar*/
setfillstyle(1,3);/*1:
solid_fill;13:
color*/
bar(0,0,150,22);/*drawarectanglewithoutthebound*/
getimage(0,0,150,22,buf_curse);/*copyimagetobuf_curse*/
setfillstyle(1,BLACK);/*thes