c语言端口扫描
⑴ linux 下C语言的syn扫描代码
//---------------------------------------------------------------------------
//Filename:ss.c
//Author:yunshu
//Write:2004-04-02
//Thanks Wineggdrop
//Modify:2004-09-08
//---------------------------------------------------------------------------
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
////////////////////////////////////////////////////////////////
//全局变量
////////////////////////////////////////////////////////////////
#define srcPort 88
char srcIP[20] = ;//定义源地址
char tgtIP[20] = ;//定义目的地址
int portNow;//定义正在扫描的端口
//标准端口列表
int ports[20] = ;
typedef struct ip_hdr
{
unsigned char h_verlen; //4位首部长度,4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct tsd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSD_HEADER;
////////////////////////////////////////////////////////////////
//函数原形
////////////////////////////////////////////////////////////////
int send_packet();//发送数据函数
int recv_packet();//监听数据函数
USHORT checksum( USHORT *, int );//计算检验和函数
void usage( char * );//显示帮助函数
void check_port( char * );//判断端口是否开放函数
////////////////////////////////////////////////////////////////
//main函数
////////////////////////////////////////////////////////////////
int main( int argc , char *argv[] )
{
WSADATA WSAData;
DWORD thread_ID = 1;
char FAR hostname[128] = ;
HANDLE ThreadHandle[20];
struct hostent *phe;
if( argc != 2 )//检查命令行参数是否正确
{
usage( argv[0] );
exit( 0 );
}
if ( WSAStartup(MAKEWORD(2,2) , &WSAData) )
{
printf("WSAStartup Error...\n");
exit(0);
}
strcpy(tgtIP,argv[1]);//得到目标主机的ip地址
gethostname(hostname,128);//获取本机主机名
phe = gethostbyname(hostname);//获取本机ip地址结构
if(phe == NULL)
{
printf("Get LocalIP Error...\n");
}
strcpy(srcIP, inet_ntoa(*((struct in_addr *)phe->h_addr_list[0])));//得到本机ip地址
//调试用,注释掉
//printf("test\t%s\n",tgtIP);
//printf("test\t%s\n",srcIP);
//开启新线程,接受数据包,分析返回的信息
HANDLE RecvHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recv_packet,NULL,0,&thread_ID);
Sleep(500);//休息一下再启动发送数据包函数
for(int tmp = 0; tmp < 20; tmp++)
{
++thread_ID;
//要扫描的端口
portNow = ports[tmp];
//开启新线程,发送数据包
ThreadHandle[tmp] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_packet,NULL,0,&thread_ID);
//防止生成线程过快,休息
Sleep(100);
}
DWORD WaitThread = WaitForMultipleObjects( 20 , ThreadHandle , TRUE , INFINITE );
if( WaitThread != WAIT_FAILED)
{
for( int n = 0 ; n < 20 ; n++ )
{
CloseHandle( ThreadHandle[n] );
}
}
CloseHandle( RecvHandle );
WSACleanup();
return 0;
}
//计算检验和函数,完全抄别人的
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if(size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
void usage(char *prog)
{
printf("===========================================\n");
printf("Used To Scan Remote Host's Ports\n");
printf("Usage:%s TargetIP\n",prog);
printf("===========================================\n");
exit(0);
}
//发送数据包的函数
int send_packet()
{
SOCKET sendSocket;
BOOL flag;
int timeout;
SOCKADDR_IN sin;
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[60] = ;
int ret;
unsigned long source_ip;
unsigned long target_ip;
//建立原生数据socket
if((sendSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Socket Setup Error...\n");
return 0;
}
//设置自己填充数据包
if(setsockopt(sendSocket, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)) == SOCKET_ERROR)
{
printf("Setsockopt IP_HDRINCL Error...\n");
return 0;
}
//设置超时时间
timeout = 1000;
if(setsockopt(sendSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)
{
printf("Setsockopt SO_SNDTIMEO Error...\n");
return 0;
}
target_ip = inet_addr(tgtIP);
source_ip = inet_addr(srcIP);
sin.sin_family = AF_INET;
sin.sin_port = htons(portNow);
sin.sin_addr.S_un.S_addr = target_ip;
//填充IP首部
ipHeader.h_verlen = (4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
ipHeader.total_len = htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident = 1;
ipHeader.frag_and_flags = 0x40;
ipHeader.ttl = 128;
ipHeader.proto = IPPROTO_TCP;
ipHeader.checksum = 0;
ipHeader.sourceIP = source_ip;//源IP
ipHeader.destIP = target_ip;//目的IP
//填充TCP首部
tcpHeader.th_dport = htons(portNow);//目的端口
tcpHeader.th_sport = htons(srcPort); //源端口
tcpHeader.th_seq = 0x12345678;
tcpHeader.th_ack = 0;
tcpHeader.th_lenres = (sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag = 2;//syn标志位。0,2,4,8,16,32->FIN,SYN,RST,PSH,ACK,URG(推测,哈哈)
tcpHeader.th_win = htons(512);
tcpHeader.th_urp = 0;
tcpHeader.th_sum = 0;
//填充tcp伪首部
psdHeader.saddr = ipHeader.sourceIP;
psdHeader.daddr = ipHeader.destIP;
psdHeader.mbz = 0;
psdHeader.ptcl = IPPROTO_TCP;
psdHeader.tcpl = htons(sizeof(tcpHeader));
//计算TCP校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum = checksum((USHORT *)szSendBuf, sizeof(psdHeader) + sizeof(tcpHeader));
//计算IP检验和
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4);
ipHeader.checksum = checksum((USHORT *)szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
//发送数据包
ret = sendto(sendSocket, szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr*)&sin, sizeof(sin));
if(ret == SOCKET_ERROR)
{
printf("Send Packet Error...\n");
return 0;
}
else return 1;
}
int recv_packet()
{
SOCKADDR_IN sniff;
SOCKET sock;
char recvBuffer[65000] = ;//缓冲区存放捕获的数据
//建立socket监听数据包
sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
sniff.sin_family = AF_INET;
sniff.sin_port = htons(0);
sniff.sin_addr.s_addr = inet_addr(srcIP);
//绑定到本地随机端口
bind(sock,(PSOCKADDR)&sniff,sizeof(sniff));
//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
//来的
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
WSAIoctl(sock,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
while(TRUE)
{
memset(recvBuffer , 0 , sizeof(recvBuffer) );
//开始捕获数据包
int bytesRecived = recv(sock,recvBuffer,sizeof(recvBuffer),0);
if(bytesRecived <= 0)
{
break;
}
check_port(recvBuffer);
}
return 1;
}
void check_port(char *buffer)
{
IP_HEADER *ipHeader;//IP_HEADER型指针
TCP_HEADER *tcpHeader;//TCP_HEADER型指针
ipHeader = (IP_HEADER *)buffer;
tcpHeader = (TCP_HEADER *) (buffer+sizeof(IP_HEADER));
if(ipHeader->sourceIP != inet_addr(tgtIP))
{
return;
}
for(int tmp=0;tmp<20;tmp++)
{
//SYN+ACK -> 2+16=18(也是推测,哈哈)
if(tcpHeader->th_flag == 18 && tcpHeader->th_sport == htons(ports[tmp]))
{
printf("[Found]\t%s\tport\t%d\tOpen\n",tgtIP,ports[tmp]);
}
}
}
⑵ C语言的技巧
如果你真的想学习编程,就请你认真的阅读下去。
大家都知道C语言很强大,这个强大一是来自其功能,第一次出名就很牛逼的编出了UNIX系统。然后跟着UNIX这个明星,于是自己的影响一路飙升。二是C语言不但能够写UNIX的操作系统,而且编写LINUX和Windows等操作系统时都离不开他的身影。三是它的实用,如果你是一个理科生,如果你学过单片机,你就知道无C不能。第四、很多就是电脑高手或黑客梦想的驱使,还有一些高手的推荐,于是你便选择的C语言。
不管你是何种原因驱使,何种目的的驱动?当你选择这个语言的时候,首先要考虑,你的基础能行不?和你的目的到底是什么?如果你是一个电脑菜鸟,或只想了解一下什么是编程,我是不赞成学习C的,因为C初学时,很伤人斗志的,也就是说你可能学习了一个月,还只能在黑色的框中徘徊,甚至资质差的只能算1+2+3+4+。。。+1000=?这个,,,会让你成为编程高手吗?显然不能!如果你以后会从事硬件方面的开发,或在软、硬件之间打交道,或一直从事软件开发,那么你一定要学习C,而且是不学不行的,有可能你还要学习汇编,因为有些情况汇编对硬件的操作比C更给力。而且他也是是不学不行的。
对于那些几乎很少和硬、软件打交道的童鞋,本人不建议学习C,因为一段时间后你会很快放弃它的,因为你知道1+2+3+。。。+1000=?根本就不能称为程序,如果你掌握技巧,你算得比计算机还快,这和你的编程高手的理想是根本搭不上边的。浪费你的时间,同时也在考验你的心理,同时更会给你迷茫。针对基础差,以后不想在软件和硬件间混以及只想学习编个程序然后就出结果的童鞋,不建议学习C,你可以学习易语言,学习VB。原因他们是高级语言,简单,易学、强大、更容易出成果。
比如VB写个窗口,构建个菜单,写个网页浏览器、写个远控(比如木马)等等,一个多月绝对能熟练掌握。我学近两年C了,都没法编出网页浏览器,更无法让一个MM图片来美化我黑不笼统的窗口,但VB你只需要一分钟,便可以让你的窗口充满色彩缤纷的效果,对于网络的端口扫描器,远程聊天控制,远程主机资源浏览等,VB都行。而且掌握他后,你变又附加的掌握了VBscript这个脚本语言。对于易语言,推荐不会英语的同学学吧,这个是中国人写的编程工具,我没用过,根据我的了解,功能也是很强大,中文的编程语言,会让你更快的掌握这个语言,编出自己的作品。
上面的一番话,只是告诉你C固然好,但不是针对所有人都好。世界上没有包治百病的仙丹,也没有适合所有人的编程语言。
对于学习了C的童鞋,你面临的是如何去深化,去巩固C。学习了C语言基础不是代表你已经会用C了,因为这才代表你刚入门,接下来你要学的是《数据结构》,这个是必修的,没有他你无法编出严谨强大的C程序,开发出自己的系统——如果有意向开发系统的。
然后你要去学习操作系统的API,这个也很重要。如果你掌握了API,那么你才能真正的可以成为自己学过C,会用C,才能知道原来C也可以无所不能。
这里是一个童鞋(08_小汪)的建议,我感觉很好,摘录下来“首先C是入门,如果想C很牛的话,就要去研究算法,C是为了过度到C++,C++会了。就要学windows程序设计,然后就学Visual c++,毕竟C++是计算机的底层。。。还有多动手写程序,不然学的永远不是自己的。。。”
然后08_小汪又推荐了四本书:
“推荐4本书《C语言陷阱和指针》,《C语言编程专家》,《thinking C++》,《数据结构-使用C++标准模板库(STL)》。。。去专门的论坛看可能会专业点,毕竟面向的对象不同。。。”
有兴趣深入研究C的童鞋,你需要读一下。
C快速入门的方法是不断的巩固、不断的编程。实践是学习和掌握的重要途径。
无论你学任何一门语言,都要一心不变的坚持下去,不要在学VB时,听某某高手说C很强大,就放弃了VB,或在学易语言时,听说易语言有局限而立即转向别的语言。这样不会成就你编程高手的梦想,只会让你习惯半途而废,然后是任何一个语言都不能学会。记住,只要你选择了,一定要走下去,最后成功的才可能是你
更多资料【【【【爱我中 华夏联盟 欢迎你】】】】】】
⑶ 100分求linux下C语言端口扫描代码
linux tcp udp 端口扫描源程序
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <signal.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#define TRUE 1
#define FALSE 0
#define UDP "UDP"
#define TCP "TCP"
#define tcp "tcp"
#define udp "udp"
typedef struct _GsSockStru{
int fd;
int len;
struct sockaddr_in addr;
}GsSockStru;
static int tcptest( char ip[32], char port[20]);
static int udptest( char ip[32], char port[20]);
void sig_alrm( int signo );
static GsSockStru test_sock;
int
main( int argc, char** argv)
{
char string[64];
char port[20];
char pro[20];
char ip[32];
int res;
int i = 0;
int k = 0;
if( argc>2 || argc<2 )
{
printf("鍙傛暟涓嶆纭?-1\n");
return ( -1 );
}
strcpy( string, argv[1]);
while( *string )
{
if( string[i] == ':' )
break;
pro[k] = string[i];
k++;
i++;
}
pro[k] = '\0';
i++;
k = 0;
while( *string )
{
if( string[i] == ':')
break;
ip[k] = string[i];
k++;
i++;
}
ip[k] = '\0';
i++;
k=0;
while( *string )
{
if( string[i] == '\0')
break;
port[k] = string[i];
k++;
i++;
}
port[k] = '\0';
i++;
memset( &test_sock, 0, sizeof( test_sock ) );
if ( ( strcmp( TCP, pro) != 0 ) && ( strcmp( UDP, pro) != 0 ) && ( strcmp( tcp, pro) != 0 ) && ( strcmp( udp, pro) != 0 ))
{
printf ( "鍙傛暟涓嶆纭?锛?\n" );
return (-1);
}
if ( strcmp( TCP, pro) == 0 || strcmp( tcp, pro) == 0 )
res = tcptest( ip, port );
if ( strcmp( UDP, pro) == 0 || strcmp( udp, pro) == 0 )
res = udptest( ip, port );printf("%d\n",res);
return ( res );
}
int
tcptest( char ip[32], char port[20])
{
int res;
struct timeval tv;
test_sock.fd = socket( AF_INET, SOCK_STREAM, 0 );
if ( test_sock.fd < 0 )
{
printf( "create socket failed -3 \n" );
return ( -3 );
}
memset( &( test_sock.addr ), 0, sizeof( test_sock.addr ) );
test_sock.addr.sin_family = AF_INET;
test_sock.addr.sin_port = htons( atoi( port ) );
inet_pton( AF_INET, ip, &test_sock.addr.sin_addr );
test_sock.len = sizeof( struct sockaddr );
tv.tv_sec = 10;
tv.tv_usec = 0;
setsockopt( test_sock.fd, SOL_SOCKET, SO_RCVTIMEO,
(const char *)&tv, sizeof( tv ) );
res = connect( test_sock.fd,
( struct sockaddr * )( &( test_sock.addr ) ),
test_sock.len );
if ( res < 0 )
{
fprintf( stderr, "connect failed 0\n" );
close( test_sock.fd );
return FALSE;
}
close( test_sock.fd );
return TRUE;
}
int udptest( char ip[32], char port[20])
{
struct icmphdr *icmp_header;
struct sockaddr_in target_info;
int target_info_len;
fd_set read_fd;
int scan_port;
char recvbuf[5000];
struct sockaddr_in target_addr;
int icmp_socket;
int udp_socket;
struct timeval tv;
icmp_header = (struct icmphdr *)(recvbuf+sizeof(struct iphdr));
scan_port = atoi( port );
target_addr.sin_family = AF_INET;
inet_pton( AF_INET, ip, &target_addr.sin_addr );
target_addr.sin_port = htons(scan_port);
if ((udp_socket=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
printf("create socket failed -3\n");
return -3;
}
if ((icmp_socket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==-1)
{
printf("Create raw socket failed -3\n");
return -3;
}
sendto(udp_socket,NULL,0,0,(void *)&target_addr,sizeof(target_addr));
FD_ZERO(&read_fd);
FD_SET(icmp_socket,&read_fd);
tv.tv_sec = 1;
tv.tv_usec = 0;
select(FD_SETSIZE,&read_fd,NULL,NULL,&tv);
for (;;){
if (FD_ISSET(icmp_socket,&read_fd))
{
target_info_len = sizeof(target_info);
recvfrom(icmp_socket,recvbuf,5000,0,
(struct sockaddr *)&target_info,&target_info_len);
if (target_info.sin_addr.s_addr == target_addr.sin_addr.s_addr
&& icmp_header->type == 3 && icmp_header->code<=12)
{
printf("Port %d : Close\n",scan_port);
return (0);
}
}
return (1) ;
}
}
⑷ 用单片机C语言控制6位密码锁。要求有一个清除键和确认键,密码输错了会有报警音。请高手帮助了
我找到了一个,来自《51单片机C语言应用技术开发大全》
SCH图正在绘制中。。。
#include <REGX51.H>//51单片机的头文件
typedef unsigned char uchar; //类型定义,定义uchar类型
typedef unsigned int uint; //类型定义,定义uint 类型
//键盘子程序相关说明。
#define BLANKCHAR 10 //定义空白常量
#define PCHAR 11 //定义字符P常量
#define OPENCHAR 12 //定义开锁字符常量
#define ALARMCHAR 13 //定义字符A常量
#define LINECHAR 14 //定义字符-常量
#define BACKKEY 0X0D //定义退格键常量
#define ENTERKEY 0X0F //定义确认键常量
#define LOCKKEY 0X0E //定义闭锁键常量
#define NO_KEY 20 //定义无按键返回值
#define KEYPORT P2 //定义键盘端口
//Delay1Ms
void Delay1Ms()
{
uint i;
for (i=0;i<1000;i++);
}
//定义按键扫描码表 按键扫描时,4位列线和4位行线组成字节数据表
uchar code KEYCODE[]=
{0XEE,0XED,0XEB,0XE7,
0XDE,0XDD,0XDB,0XD7,
0XBE,0XBD,0XBB,0XB7,
0X7E,0X7D,0X7B,0X77};
uchar KeyPre; //保存上次扫描按键的键值
uchar KeyUp;
//用于控制按键去抖动操作。1:扫描时去抖动 2:等待释放 3:释放时去抖动。
#define LEDPORT P0 //定义显示器段码输出端口
#define LEDCON P1 //定义显示器位控制端口
uchar code SEGCODE[]=
{0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,// 0~9的共阳极代码
0xff,//不显示的共阳极段码
0X8C,//字符P的共阳极段码
0X8F,//┝的共阳极段码
0X88,//字符A的共阳极段码
0XBF,//字符-的共阳极段码
};
//定义LED位码控制码
uchar code BITCODE[]={0Xfe,0Xfd,0Xfb,0Xf7,0Xef,0Xdf,0Xbf,0X7f};
uchar DispBuf[6]; //保存显示的字符
bit DispNormal; //控制显示时,是正常显示还是闪烁显示。
uchar DispCnt; //控制闪烁显示时的频率。
#define SHORT_TIME 10 //蜂鸣器响200ms
#define LONG_TIME 100 //蜂鸣器响2s
#define LONGER_TIME 9000 //蜂鸣器响3 minutes
sbit ALARMCON=P3^4; //定义报警控制引脚
bit AlarmEnable; //是否报警或声音提示
uint AlarmTime; //控制报警时间长度
sbit LOCKCON=P3^3; //定义电子锁控制引脚
uchar code PassWord[]={1,2,3,4,5}; //定义初时密码表
uchar PassInBuf[6]; //保存输入的密码字符
uchar PassPosi; //用户输入密码字符存放在PassInBuf[]的位置。
bit TimerBit; //20ms定时时间到
uchar SysMode; //系统所处模式 0:输入密码模式 1:报警模式 2:开锁模式
uchar ErrorCnt; //用户连续输入密码出错次数。
/*
入口参数:
FillChar:写入缓冲区的字符
出口参数:无
*/
void Fill_Buf(uchar FillChar)
{
uchar i;
for(i=0;i<6;i++)
{
DispBuf[i]=FillChar;//用字符FillChar填充DispBuf[i]
PassInBuf[i]=FillChar; //用字符FillChar填充PassInBuf [i]
}
}
void Fill_Buf_P()
{
Fill_Buf(BLANKCHAR); // DispBuf[1..5]= ' '
DispBuf[0]=PCHAR;// DispBuf[0]='P'
}
void Fill_Buf_O()
{
Fill_Buf(BLANKCHAR); // DispBuf[1..5]= ' '
DispBuf[0]=OPENCHAR; // DispBuf[0]='┝'
}
void Fill_Buf_A()
{
Fill_Buf(LINECHAR); // DispBuf[1..5]= ' -----'
DispBuf[0]=ALARMCHAR; // DispBuf[0]='A'
}
/*
入口参数:
DispPosi:要显示数据的LED号。
DispChar:要显示的内容。
出口参数:无
*/
void Disp_Led_Sin(uchar DispChar,uchar DispPosi)
{
LEDPORT=SEGCODE[DispChar];//输出显示段码
LEDCON&=BITCODE[DispPosi];//输出显示位码
Delay1Ms(); //延时1MS
LEDCON|=0X3F;//关闭显示器
}
/*(2)关闭显示函数Disp_Led_OFF。
函数Disp_Led_OFF在显示器上显示空白字符,主要用在闪烁显示。函数通过6次调用Disp_Led_Sin实现所需功能。代码如下:*/
void Disp_Led_OFF()
{
uchar i;
LEDCON|=0X3F;// 关闭显示器
for(i=0;i<6;i++)
{
Disp_Led_Sin(BLANKCHAR,i);//逐个显示空白字符
}
}
void Disp_Led_All()
{
uchar i;
LEDCON|=0X3F; // 关闭显示器
for(i=0;i<6;i++)
{
Disp_Led_Sin(DispBuf[i],i); //显示DispBuf[]中的数值
}
}
void Disp_LED()
{
DispCnt++;
DispCnt%=10;
if(DispCnt==0)
{
DispNormal=~DispNormal;//200ms将闪烁显示控制位取反
}
if(SysMode==1)
{//报警模式,闪烁显示
if(!DispNormal)
{
Disp_Led_OFF();//显示空白字符
return;
}
}
Disp_Led_All();//显示DispBuf[]中的数值
}
/*
入口参数:
stime:蜂鸣器鸣叫时间。
出口参数:无
*/
void Sys_Speaker(uint stime)
{
AlarmEnable=1;//允许报警
AlarmTime=stime;//报警时间长短
}
void Sys_Alarm()
{
if(AlarmEnable==1)
{//允许报警
ALARMCON=0;//报警
AlarmTime--;
if(AlarmTime==0)
{//停止报警时间到
AlarmEnable=0;
ALARMCON=1;//禁止报警
if(SysMode==1)
{//报警发生在模式1时,要返回模式0
SysMode=0;
Fill_Buf_P();//显示P
}
}
}
}
/*
入口参数:无
出口参数:按键值或无按键
*/
uchar Find_Key()
{
uchar KeyTemp,i;
KEYPORT=0xf0;//行线输出0,列线输出全1
KeyTemp=KEYPORT;//读按键端口值
if(KeyTemp==0xf0)
return NO_KEY;//无键按下,返回
KEYPORT=KeyTemp|0x0f;//列线输出,行线输入
KeyTemp=KEYPORT;//读取按键端口值
for(i=0;i<16;i++)
{
if(KeyTemp==KEYCODE[i])//根据按键端口扫描值,查找按键值
return i;//返回按键值
}
return NO_KEY;
}
/*
入口参数:无
出口参数:按键值或无按键
*/
uchar Scan_Key()
{
uchar KeyTemp;
KeyTemp=Find_Key();//扫描键盘,获得按键值
if(KeyTemp==NO_KEY)
{
if(KeyUp<2)
{//无按键按下,返回
KeyUp=0;
return NO_KEY;
}
if(KeyUp==2)
{//按键要释放,延时去抖动
KeyUp=3;
return NO_KEY;
}
if(KeyUp==3)
{//按键释放,返回键值
KeyUp=0;
return KeyPre;
}
}
else
{
if(KeyUp==0)
{//有键按下,保存键值
KeyUp=1;
KeyPre=KeyTemp;
}
else if(KeyUp==1)
{//去抖动后,再次测到有按键按下
if( KeyPre==KeyTemp)
KeyUp=2;
else
KeyPre=KeyTemp;
} else if(KeyUp==3)
{//等待按键释放
KeyUp=2;
}
}
return NO_KEY;
}
/*
入口参数:
Key:按键值
出口参数:无
*/
void Key_Process(uchar Key)
{
uchar i;
if(Key==NO_KEY)
return ;//无按键,不处理
switch(SysMode)
{
case 0://输入密码
switch(Key)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
DispBuf[PassPosi]=LINECHAR;//显示'-'
PassInBuf[PassPosi]=Key;//保存用户输入的密码
if(PassPosi<5)
PassPosi++;//调整密码输入位置
Sys_Speaker(SHORT_TIME);//发按键提示音
break;
case BACKKEY://退格键
DispBuf[PassPosi]=BLANKCHAR;//显示' '
PassInBuf[PassPosi]=BLANKCHAR;//清除当前位置的密码
if(PassPosi>1)
PassPosi--;//调整显示位置
Sys_Speaker(SHORT_TIME);//发按键提示音
break;
case ENTERKEY://确定按键
for(i=0;i<5;i++)
{//比较用户输入密码与系统预设密码是否一致
if(PassInBuf[i+1]!=PassWord[i])
break;
}
if(i>=5)
{//输入密码正确
Fill_Buf_O();//显示开锁状态
PassPosi=1;
LOCKCON=1;//开锁
ErrorCnt=0;
Sys_Speaker(LONG_TIME);//发长提示音
SysMode=2;//转模式2
}
else
{
ErrorCnt++;//出错次数加一
if(ErrorCnt>2)
{//次数超过3次
ErrorCnt=0;
Fill_Buf_A();//显示报警状态
PassPosi=1;
Sys_Speaker(LONGER_TIME);//发报警音
SysMode=1;
}
else
{//出错次数少于3次,用户重新输入
Fill_Buf_P();
PassPosi=1;
Sys_Speaker(LONG_TIME);
}
}
break;
case LOCKKEY://闭锁键
Fill_Buf_P();//显示P
PassPosi=1;
Sys_Speaker(SHORT_TIME);
break;
}
break;
case 2://开锁状态
if(Key==LOCKKEY)
{//用户按动闭锁按键
Fill_Buf_P();
SysMode=0;
LOCKCON=0;//闭锁
Sys_Speaker(SHORT_TIME);
}
break;
}
}
void Ini_Timer0()
{
TMOD&=0XF0;
TMOD|=0X01;// 初始化T0,模式1
TR0=0;
TH0=(65536-20000)/256;//T0 赋计数初值
TL0=(65536-20000)%256;
TR0=1;//启动T0
ET0=1;//允许T0中断
}
void Timer0() interrupt 1
{
TR0=0;
TH0=(65536-20000)/256; //T0 赋计数初值
TL0=(65536-20000)%256;
TR0=1;
TimerBit=1;//定时时间到
}
void Ini_System()
{
PassPosi=1;
LOCKCON=0;//闭锁
Ini_Timer0();//初始化T0
Fill_Buf_P();
EA=1;//允许系统中断
}
void main()
{
uchar KeyTemp;
Ini_System();
while(1)
{
if (TimerBit==1)
{//定时时间到
Disp_LED();//刷新显示器
Sys_Alarm();//报警处理
KeyTemp=Scan_Key();//扫描按键
Key_Process(KeyTemp);//按键处理
TimerBit=0;
}
}
}