打印
[51单片机]

指纹从51移植到STC12出问题,求解

[复制链接]
1914|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
nicemaker|  楼主 | 2016-5-16 22:23 | 只看该作者
#include <STC12C5A60S2.h>
#include <MacroAndConst.h>
#include "LCD12864.h"
uint8 pack_data[48];
sbit s1=P1^4;//用按键来演示功能,s1表示录入第一个指纹,s2表示录入第二个指纹,s3表示指纹验证
sbit s2=P1^5;
sbit s3=P1^6;
sbit Relay=P3^7;

uint8 idata display0[]={"录入成功"};
uint8 idata display1[]={"录入失败"};
uint8 idata display3[]={"生成失败"};
uint8 idata display5[]={"合并失败"};
uint8 idata display6[]={"存储成功"};
uint8 idata display7[]={"存储失败"};
uint8 idata display8[]={"验证成功"};
uint8 idata display9[]={"搜索不到"};
uint8 idata display10[]={"指纹识别"};
uint8 idata display11[]={"请放手指"};
uint8 idata display12[]={"sencond"};
uint8 idata display13[]={"验证指纹"};

#define ES0  ES
#define  OLEN  10           //发送缓冲区的长度
uint8   outbuf[OLEN];       //发送缓冲区的存储位置
uint8   *outlast=outbuf;   //最后由中断传输出去的字节位置
uint8   *putlast=outbuf;   //最后放入发送缓冲区的字节位置
#define  ILEN  10          //接收缓冲区的长度
uint8  inbuf[ILEN];                   //接收缓冲区的存储位置
uint8  *inlast=inbuf;  //最后由中断进入接收缓冲区的字节位置
uint8  *getlast=inbuf; //前面为最后取走的字节位置,即指向下一个要取数据的位置
bit   outbufsign0;     //最后一个数据覵BUF发完标志  发完=0
bit   outbufsign;      //输出缓冲区非空标志   有=1
bit   inbufsign;       //接收缓冲区非空标志   有=1
bit   inbufful;        //输入缓冲区满标志  满=1

void delayms(unsigned int xms)
{
   unsigned int i,j;
   for(i=xms;i>0;i--)
     for(j=1100;j>0;j--);
}

/*****************************************************************/
//放入一个字节到发送缓冲区
void putbyte(int8 c)
{
        ES0=0;            //暂停串行中断,以免数据比较时出错
        *putlast=c;         //放字节进入缓冲区
        putlast++;          //发送缓冲区指针加一
        if (putlast==outbuf+OLEN) putlast=outbuf;  //指针到了顶部换到底部
        outbufsign=1;
        if (!outbufsign0)
        {
           outbufsign0=1;
           TI=1;
          }   //缓冲区开始为空置为有,启动发送
        ES0=1;
}

//******************************
//放一串数据到发送缓冲区
void putbytes(uint8 *outplace,uint8 j)
{        
        int i ;
        for(i=0;i<j;i++)
        {
         putbyte(*outplace);
         outplace++;
        }
}

//从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。
uint8 getbyte (void)
{
  int8 idata c ;
  while (!inbufsign);     //缓冲区空等待
  ES0=0;                                  //串行中断关闭
  c= *getlast;            //取数据
  getlast++;              //最后取走的数据位置加一
  inbufful=0;            //输入缓冲区的满标志清零
  if (getlast==inbuf+ILEN) getlast=inbuf ; //地址到顶部回到底部
  if (getlast==inlast)  inbufsign=0;       //地址相等置接收缓冲区空空标志,再取数前要检该标志

  ES0=1;
  return (c);        //取回数据
}

//*****************************************
//从接收缓冲区读取n个数据,
void getbytes0(uint8 *dat_buf,uint8 n)
{
        uint8 i;
        for(i=0;i<n;i++)
        {       
            dat_buf[i]=getbyte();                  
        }
}


//串口中断处理
void serial() interrupt 4
{   
  if (TI)
  {
          TI = 0;
          if (outbufsign)        //输出缓冲区空
          {
                  SBUF=*outlast; //未发送完继续发送
            outlast++;            //最后传出去的字节位置加一
            if (outlast==outbuf+OLEN) outlast=outbuf;//地址到顶部回到底部
            if (putlast==outlast) outbufsign=0;   //数据发送完置发送缓冲区空标志
    }
    else
    {
            outbufsign0=0;

    }
  }
  if (RI)
  {  
          RI = 0;
          if(!inbufful)
          {
                  *inlast = SBUF;              //放入数据
            inlast++;                    //最后放入的位置加一
        inbufsign=1;
            if (inlast==inbuf+ILEN) inlast=inbuf;//地址到顶部回到底部
            if (inlast==getlast)        inbufful=1;  //接收缓冲区满置满标志
    }
  }
}


void serial_init()  
{
   SCON  = 0x50;               // mode 1: 8-bit UART, enable receiver
   PCON  = 0x80;  //  baud*2
   TMOD  = 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0xFF;                //设定定时初值
        TH1 = 0xFF;                //设定定时器重装值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
   EA=1;
        ES=1;
}

void serial_init()                //57600bps@11.0592MHz
{
        PCON |= 0x80;                //使能波特率倍速位SMOD
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器1时钟为Fosc/12,即12T
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //清除定时器1模式位
        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0xFF;                //设定定时初值
        TH1 = 0xFF;                //设定定时器重装值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
        EA = 1;
        ES = 1;
}




void send_order(uint8 order) //order为录入图像,合并特征,精确比对两枚指纹特征,清空指纹库的指令码
{
   uint16 check=0;
   pack_data[0]=0xef; pack_data[1]=0x01;  //写帧界符(包头)
   pack_data[2]=0xff;pack_data[3]=0xff;pack_data[4]=0xff;pack_data[5]=0xff;  //模块地址(ffH×4)默认
   pack_data[6]=0x01;         //写包标识(01H)
   pack_data[7]=0x00;pack_data[8]=0x03;//写包长度
   pack_data[9]=order;        //写指令码
   check=pack_data[6]+pack_data[7]+pack_data[8]+pack_data[9];//计算校验和
   pack_data[10]=check>>8;     //写校验和低字节
   pack_data[11]=check;        //写校验和高字节   
   putbytes(pack_data,12);     //发送命令包
}

uint16 responsion_order(void) //录入指纹,生成特征,合成特征,存储模板,清空指纹库的应答包函数
{
   uint16 check=0,sum;
   getbytes0(pack_data,12); //接收命令包到包数据缓存区
   check=pack_data[6]+pack_data[7]+pack_data[8]+pack_data[9];//计算校验和
   sum=pack_data[10];sum=(sum<<8)+pack_data[11]; //读取校验和
   if (sum!=check)  //判断校验和
   {
      pack_data[9]=0x01;  //接收数据错误,置确认码0x01 表示收包有错
   }
  return (pack_data[9]); //返回确认码
}

void GenUpDown_order(uint8 buffer)//将指纹图像生成特征值存入buffer1/2
{
   uint16 check=0;
   pack_data[0]=0xef; pack_data[1]=0x01;  //写帧界符(包头)
   pack_data[2]=0xff;pack_data[3]=0xff;pack_data[4]=0xff;pack_data[5]=0xff;  //模块地址(ffH×4)默认
   pack_data[6]=0x01;         //写包标识(01H)
   pack_data[7]=0x00;pack_data[8]=0x04;//写包长度
   pack_data[9]=0x02;        //写指令码
   pack_data[10]=buffer;         //代表buffer1寄存器
   check=pack_data[6]+pack_data[7]+pack_data[8]+pack_data[9]+pack_data[10];//计算校验和
   pack_data[12]=check;        //写校验和高字节
   pack_data[11]=check>>8;     //写校验和低字节
   putbytes(pack_data,13);     //发送命令包
}

void StoreLoad_order(uint16 PageID) //存储合成模板 pageid是指纹库位置号
{
   uint8 i;
   uint16 check=0;
   pack_data[0]=0xef; pack_data[1]=0x01;  //写帧界符(包头)
   pack_data[2]=0xff;pack_data[3]=0xff;pack_data[4]=0xff;pack_data[5]=0xff;  //模块地址(ffH×4)默认
   pack_data[6]=0x01;         //写包标识(01H)
   pack_data[7]=0x00;pack_data[8]=0x06;//写包长度
   pack_data[9]=0x06;        //写指令
   pack_data[10]=0x01;        //buffer1
   pack_data[11]=PageID/256;pack_data[12]=PageID%256;
                                                  
   for(i=6;i<13;i++)
   {
     check+=pack_data[i];//计算校验和
   }
   pack_data[14]=check;        //写校验和低字节
   pack_data[13]=check>>8;     //写校验高低字节
   putbytes(pack_data,15);     //发送命令包
}

//以buffer1或buffer2中的文件搜索指纹库,startpage为起始页,pagenum为页码
void search_order(uint8 BufferID,uint16 StartPage,uint16 PageNum)
{  
   uint8 i=0;
   uint16 check=0;
   pack_data[0]=0xef; pack_data[1]=0x01;  //写帧界符(包头)
   pack_data[2]=0xff;pack_data[3]=0xff;pack_data[4]=0xff;pack_data[5]=0xff;  //模块地址(ffH×4)默认
   pack_data[6]=0x01;         //写包标识(01H)
   pack_data[7]=0x00;pack_data[8]=0x08;//写包长度
   pack_data[9]=0x04;        //写指令码
   pack_data[10]=BufferID;
   pack_data[11]=StartPage/256;pack_data[12]=StartPage%256;
   pack_data[13]=PageNum/256;pack_data[14]=PageNum%256;
   for(i=6;i<15;i++)
   {
     check+=pack_data[i];      //计算校验和
   }
   pack_data[16]=check;        //写校验和低字节
   pack_data[15]=check>>8;     //写校验高低字节
   putbytes(pack_data,17);     //发送命令包
}

uint16 responsion_search()        //搜索指纹库之后的应答
{
   uint8 i;
   uint16 check=0,sum;
   getbytes0(pack_data,16); //接收命令包到包数据缓存区
   for(i=6;i<14;i++)
   {
      check+=pack_data[i];  //计算校验和
   }
   sum=pack_data[14];sum=(sum<<8)+pack_data[15]; //读取校验和
   if (sum!=check)  //判断校验和
   {
      pack_data[9]=0x01;  //接收数据错误,置确认码F_Error 表示收包有错
   }
   if(pack_data[9]==0x00)
   {
           return ((pack_data[10]<<8)|pack_data[11]); //返回页码
   }
   else
   {
           return (0x01);
   }
}

////////////////////////////////////////
void send_save(uint16 PageID)        //录入指纹并存储
{
        unsigned int te=1;
        while(te)
        {
                send_order(0x01);//第一次录入指纹图像
        switch(responsion_order())
        {
          case 0x00:  {Location(1,0);
                                   Print(display0); //录入成功
                                   delayms(500);
                                   te=0;
                                   break;       
                                        }
          case 0x01:  {
                                  Location(1,0);
                                  Print(display1);//录入失败
                                   delayms(500);
                                  te=1;
                                  break;
                                   }
           }
        }
        GenUpDown_order(0x01);//生成特征保存到buffer1中
        switch(responsion_order())
        {          
          case 0x00: {
                                  Location(1,0);
        //                      Print(display2); //生成成功
        //                      delayms(500);
                                  break;
                                  }
          case 0x01:
                                 {
                                   Location(1,0);
                                   Print(display3);//生成失败
                                   delayms(500);
                                   break;
                                   }
        }
          te=1;
        while(te)
        {
                send_order(0x01);// 再次录入指纹图像
                switch(responsion_order())
                {
                  case 0x00:  {Location(1,0);
                //                   Print(display0); //录入成功
                //                            delayms(500);
                                           te=0;
                                           break;       
                                                }
                  case 0x01:  {
                                          Location(1,0);
                                          Print(display1);//录入失败
                                           delayms(500);
                                          te=1;
                                          break;
                                           }
                }
        }

        GenUpDown_order(0x02);//生成特征保存到buffer2中
        switch(responsion_order())
                {          
                  case 0x00: {
                                          Location(1,0);
                //                      Print(display2); //生成成功
                //                      delayms(500);
                                          break;
                                          }
                  case 0x01:
                                         {
                                           Location(1,0);
                                           Print(display3);//生成失败
                                           delayms(500);
                                           break;
                                           }
                }
        send_order(0x05);//将buffer1和buffer2合并特征
        switch(responsion_order())
        {                  
           case 0x00:  {  Location(1,0);
        //                           Print(display4);//合成成功
        //                           delayms(500);
                                   break;
                                   }
          case 0x01:
                                  { Location(1,0);
                                   Print(display5);//合成失败
                                   delayms(500);
                                   break;                                                                                                                                         
                                   }
        }

           StoreLoad_order(PageID); //存储模板至指纹库PageID中
        switch(responsion_order())
        {          
         case 0x00:    {  
                                   Location(1,0);
                                   Print(display6);//存储成功
                                   delayms(500);
                                  
                                   break;
                                        }
        case 0x01:
                                  {
                                   Location(1,0);
                                   Print(display7);//存储失败
                                   delayms(500);
                                  
                                   break;
                                   }
        }   
}

int CommandPSSearch()        //搜索验证指纹
{
  uint8 te=1,re;
while(te)
        {
                send_order(0x01);//录入指纹图像
                switch(responsion_order())
                {          
                  case 0x00: {
                                      Location(1,0);
                                      Print(display0); //录入成功
                                      delayms(500);
                                          te=0;
                                          break;
                                          }
                  case 0x01:
                                         {
                                           Location(1,0);
                                           Print(display1);//录入失败
                                           delayms(500);
                                           te=1;
                                           break;
                                         }
                }
           }
                GenUpDown_order(0x01);//生成特征保存到buffer1中
                switch(responsion_order())
                {          
                  case 0x00: {
                                      Location(1,0);
//                                      Print(display2); //生成成功
//                                      delayms(500);
                                          break;
                                          }
                  case 0x01:
                                         {
                                           Location(1,0);
                                           Print(display3);//生成失败
                                           delayms(500);
                                           break;
                                           }
                }
       
                search_order(0x01,0,0x03e7); //搜索指纹库 1000页
                switch(responsion_search())
                {       
                        case 0x01:   { Location(1,0);
                                                   Print(display9);//搜索不到
                                                   delayms(500);
                                                   return re++;
                                                   break;
                                                  }   
                        default: {
                                           Location(1,0);
                                           Print(display8);//验证成功
                                           Relay=0;
                                           delayms(5000);
                                           Relay=1;
                                           delayms(500);
                                           return 3;
                                           break;
                                          }
                }
}


uint16 KeyScan() //按键扫描函数
{
   if((s1&&s2&&s3)==0)//判断是否有按键按下
   {
     delayms(60); //延时消抖
          if(s1==0) return 1;
//             if(s2==0)        return 2;
          if(s3==0)        return 3;
   }

  else
  return 0;

}


void main(void)
{
        uint16 num=0x000a;
        InitLCD();//液晶初始化
        serial_init();//串口初始化
        Location(4,0);
        Print(display10);//显示“指纹识别”
        while(1)
        {
                switch(KeyScan())
                {
                 case 0:break;  
                 case 1: {
                                 Location(3,0);
                                 Print(display11);//显示“请放手指 ”
                                 delayms(500);
                                 send_save(num); //录入指纹并存储到b中
                                 num++;
                                 break;
                                 }
        //         case 2: {
        //                         Location(3,0);
        //                         Print(display12);//显示“second”
        //                         delayms(1500);
        //                         send_save(0x000c); //录入指纹并存储到c中
        //                         break;
        //                         }
                 case 3:{
                                 Location(3,0);
                                 Print(display13);  //显示“验证指纹”
                                 delayms(500);  
                                while(CommandPSSearch()<3);//验证指纹
                                break;
                                }
                }
        }
}

使用特权

评论回复
板凳
nicemaker|  楼主 | 2016-5-16 22:24 | 只看该作者
是时序还是串口问题,求解

使用特权

评论回复
地板
supercpf| | 2016-5-17 00:02 | 只看该作者
不知道,帮顶

使用特权

评论回复
5
ningling_21| | 2016-5-17 10:44 | 只看该作者
STC51的串口明明是全双工的,哪个资料说半双工?

使用特权

评论回复
6
any012| | 2016-5-17 10:58 | 只看该作者
串口都是全双工的吧。
是不是有些特殊寄存器设置的不对?比如AUX1,AUX2?好像叫这个名字。

楼主的编辑器看得挺棒。

使用特权

评论回复
7
jackhwang| | 2016-5-17 11:38 | 只看该作者
我看你代码,原来51的serial_init()函数与后来的serial_init()函数都放在里面,没有对原来51的serial_init()函数屏蔽掉。
查看AUXR设置,感觉没有问题。STC单片机复位后,AUXR默认设置就是与51兼容的,我使用时就没对它设置,直接使用默认值。

使用特权

评论回复
8
nicemaker|  楼主 | 2016-5-17 13:09 | 只看该作者
jackhwang 发表于 2016-5-17 11:38
我看你代码,原来51的serial_init()函数与后来的serial_init()函数都放在里面,没有对原来51的serial_i ...

谢谢,不是这个问题。烦了两天了

使用特权

评论回复
9
pener| | 2016-5-17 13:46 | 只看该作者
先用串口工具确定12的串口通信正常再接指纹模块,12的是速度是1T的,51的是12T的

使用特权

评论回复
10
galton1982| | 2016-5-17 15:02 | 只看该作者
先连上电脑  看看串口设置对不对吧  用个串口助手之类的  

使用特权

评论回复
11
nicemaker|  楼主 | 2016-5-17 15:02 | 只看该作者
pener 发表于 2016-5-17 13:46
先用串口工具确定12的串口通信正常再接指纹模块,12的是速度是1T的,51的是12T的 ...

恩,谢谢,使用串口调试是对的,发送数据没有乱码。

使用特权

评论回复
12
nicemaker|  楼主 | 2016-5-17 15:04 | 只看该作者
galton1982 发表于 2016-5-17 15:02
先连上电脑  看看串口设置对不对吧  用个串口助手之类的

使用串口调试是对的,发送数据没有乱码。波特率设置是用STC家的工具生成的

使用特权

评论回复
13
feiyinglala| | 2016-5-17 16:54 | 只看该作者
楼主的编译环境的配色不错呀

使用特权

评论回复
14
changle11sdo5| | 2016-5-17 19:21 | 只看该作者
实测,哪一段不对?

使用特权

评论回复
15
nicemaker|  楼主 | 2016-5-17 19:41 | 只看该作者
feiyinglala 发表于 2016-5-17 16:54
楼主的编译环境的配色不错呀

看重点,为什么,STC89C52与STC12C5A60S2

使用特权

评论回复
16
nicemaker|  楼主 | 2016-5-17 19:43 | 只看该作者
changle11sdo5 发表于 2016-5-17 19:21
实测,哪一段不对?

不论程序跑到哪个switch,然后串口就不发送接收数据了

使用特权

评论回复
17
feiyinglala| | 2016-5-18 12:53 | 只看该作者
nicemaker 发表于 2016-5-17 19:41
看重点,为什么,STC89C52与STC12C5A60S2

你头像搞的这么多美腿,我怎么找得到重点?

使用特权

评论回复
18
bobde163| | 2016-5-20 22:49 | 只看该作者
运行一段时间会死机,会不会是哪个地方程序导致了堆栈溢出?

使用特权

评论回复
19
linqing171| | 2016-5-23 09:57 | 只看该作者
feiyinglala 发表于 2016-5-17 16:54
楼主的编译环境的配色不错呀

除了颜色,宋体的字体也是功劳。
楼主是某星座的。

不过这种问题贴一堆代码,看不下去,一分钟分析不完的就不会再看了。
从错误描述上来看,每个函数和每个功能都单元测试过,不可能有问题。调试的方法也很多,只要地方对了,这类问题也就是一个条件断点的事。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

15

帖子

0

粉丝