开发者社区> 技术小美> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

基于51单片机、串口通信、ASP.NET的密码锁系统

简介:
+关注继续查看

实现的功能:密码锁,红外控制,温度计功能等

连线:键盘接P0,P2接数码管,接上LCD,P1.0接蜂鸣器,P1.2-P1.7接步进电机

#include <reg52.h>
  #include <intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;


bit FlagC=1;    //接受和发送的标志位
sbit P10=P1^0;   //控制蜂鸣器响
sbit IRIN = P3^2;         //红外接收器数据线
uchar IRCOM[7];
uint nn=11;//用来判断红外发送的信号是数字几
//////温度液晶////////////////
typedef bit BOOL;


sbit DQ = P3 ^ 7;


uchar Temp_Value[] = { 0x00, 0x00 };
uchar Display_Digit[] = { 0, 0, 0, 0 };


sbit LCD_RW = P2 ^ 5; //写数据?
sbit LCD_RS = P2 ^ 6;
sbit LCD_EP = P2 ^ 7; //使能?
uchar num;
int temper = 0;
int CurrentT = 0;
bit flag;


void delayT(uchar t) {
    while (t--)
        ;
}


void init_ds18b20() {
    //    uchar n;
DQ = 1;
    _nop_();
    DQ = 0;
    delayT(80);
    _nop_();
    DQ = 1;
    delayT(14);
    _nop_();
    _nop_();
    _nop_();


    if (DQ == 0)
        flag = 1; //detect 1820 success!
    else
        flag = 0; //detect 1820 fail!
    delayT(20); //20
    _nop_();
    _nop_();
    DQ = 1;
}


void write_byte(uchar dat) {
    uchar i;
    for (i = 0; i < 8; i++) {
        DQ = 0;
        _nop_();
        DQ = dat & 0x01; //从最低位开始写
        delayT(3);
        _nop_();
        _nop_();
        DQ = 1;
        dat >>= 1;
    }
    //    delay(4);
}


uchar read_byte() {
    uchar i, value = 0;
    for (i = 0; i < 8; i++) {
        DQ = 0;
        value >>= 1;
        DQ = 1;
        if (DQ)
            value |= 0x80;
        delayT(2);
        _nop_();
    }
    return value;
}


int readtemperature() {
    uchar templ, temph;
    //    int temp;
    init_ds18b20();
    write_byte(0xcc); //跳过ROM
    write_byte(0x44); //启动温度测量
    delayT(300);


    init_ds18b20();
    write_byte(0xcc);
    write_byte(0xbe);
    //    Temp_Value[0] = ReadOneByte();
    //    Temp_Value[1] = ReadOneByte();
    templ = read_byte();
    temph = read_byte();
    //CurrentT = ((templ&0xf0)>>4) | ((temph&0x07)<<4);
    CurrentT = temph*256 +templ;
    CurrentT = CurrentT * 62.5;
    return CurrentT;
}


/****************侧忙函数************************/
BOOL lcd_bz() {
    BOOL result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EP = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    result = (BOOL) (P0 & 0x80); //检测P0最高位是否为1
    LCD_EP = 0;
    return result;
}
/****************写命令函数************************/
void write_com(uchar cmd) {
    while (lcd_bz())
        ;
    LCD_RS = 0;
    LCD_RW = 0;
    //    LCD_EP = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EP = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EP = 0;
}


void lcd_pos(uchar pos) {
    write_com(pos | 0x80);
}


/****************写数据函数************************/
void write_data(uchar dat) { //写入字符显示数据到LCD
    while (lcd_bz())
        ;
    LCD_RS = 1;
    LCD_RW = 0;
    //    LCD_EP = 0;
    _nop_();
    _nop_();
    P0 = dat;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EP = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EP = 0;
}


void initT() {
    //    dula=0;
    //    wela=0;
    LCD_EP = 0;
    write_com(0x38); //16*2显示
    write_com(0x0e); //开显示;显示光标,光标不闪烁
    write_com(0x06); //光标自动增加111
    write_com(0x01); //显示清屏
    //    write_com(0x80+0x10);
}
//////////////////////////////


unsigned int ReData;
uchar num=0;
const char Message[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};    //要发送的数据
char Get_Mes[8]={0x03};               //获取到的数据
uchar i=0;
uchar Chose;//判断选择哪一个功能选项
//此表为 LED 的字模, 共阴数码管 0-F  
uchar code   LEDMAP[] = {~0x3f, ~0x06, ~0x5b, ~0x4f, ~0x66, ~0x6d, ~0x7d, ~0x07,~0x7f, ~0x6f, ~0x77, ~0x7c, ~0x39, ~0x5e, ~0x79, ~0x71};  //段码控制
uint LEDN[16];
int n=0;
void delay(uint);


void Send_data(char p[])   //发送数据
{
    uchar i;
    for(i=0;i<1;i++)
    {
        SBUF = p[i];            //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
        while(!TI);                // 等特数据传送    (TI发送中断标志)
        TI = 0;                    // 清除数据传送标志    
    } 



void zhuanhuan(char c)     //将PC传过来的16进制数转化成对应的十进制数
{
       switch(c)
      {
        case 0x00:
        {
          LEDN[0]=0;
          break;
        }
      }
}


void Get_data(char p[])    //接受数据到数组中
{
    
    i=i%8;
    i++;
    P2=LEDMAP[SBUF];
    p[i]=P2;
    FlagC=1;
    while(!RI);                // 等特数据传送    (TI发送中断标志)
    RI = 0;                    // 清除数据传送标志    
}
//返回一个选择项
char Get_Chose()
{
    return SBUF;
}


void delay(uint z)
{
    uchar j;
    for(z;z>0;z--)
        for(j=0;j<200;j++)
            ;    
}


void init()
{
    SCON = 0x50;      //REN=1允许串行接受状态,串口工作模式1                      
                    
    PCON|= 0x80;
                                                             
    TMOD|= 0x20;      //定时器工作方式2
    TH1 = 0xF3;                    // //baud*2  /*  波特率4800、数据位8、停止位1。效验位无 (12M)
    TL1 = 0xF3;         
    TR1  = 1;                                                             
    ES   = 1;        //开串口中断                  
    EA   = 1;        // 开总中断 
}


//蜂鸣器响
void beep(uint t)
{
    uint time=0;
    for(time;time<t;time++)
    {
        P10=1;
        delay(100);
        P10=0;
        delay(100);
    }
}


/////////红外//////////////////




void beeph()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(4);
   P10=!P10;                 //BEEP取反
   } 
  P10=1;                      //关闭蜂鸣器
}


void delayh(unsigned char x)    //x*0.14MS
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}


void delay1h(int ms)
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}




void IR_IN() interrupt 0 using 0
{
  unsigned char j,k,N=0;
     EX0 = 0;   
     delayh(15);
     if (IRIN==1) 
     { EX0 =1;
       return;
      } 
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delayh(1);}


 for (j=0;j<4;j++)         //收集四组数据
 { 
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delayh(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delayh(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delayh(1);
    N++;           
    if (N>=30)
     { EX0=1;
     return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕                
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
 }//end for j
   
   if (IRCOM[2]!=~IRCOM[3])
   { EX0=1;
     return; }


   IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位


   if(IRCOM[5]>9)
    { IRCOM[5]=IRCOM[5]+0x37;}
   else
      IRCOM[5]=IRCOM[5]+0x30;


   if(IRCOM[6]>9)
    { IRCOM[6]=IRCOM[6]+0x37;}
   else
      IRCOM[6]=IRCOM[6]+0x30;


    //将红外信号转换成数字
    if(IRCOM[6]=='4'&&IRCOM[5]=='5')
    {
         nn=10;//关闭
    }
    if(IRCOM[6]=='1'&&IRCOM[5]=='6')
    {
         nn=0;
    }
    if(IRCOM[6]=='0'&&IRCOM[5]=='C')
    {
         nn=1;
    }
    if(IRCOM[6]=='1'&&IRCOM[5]=='8')
    {
         nn=2;
    }
    if(IRCOM[6]=='5'&&IRCOM[5]=='E')
    {
         nn=3;
    }
    if(IRCOM[6]=='0'&&IRCOM[5]=='8')
    {
         nn=4;
    }
    if(IRCOM[6]=='1'&&IRCOM[5]=='C')
    {
         nn=5;
    }
    if(IRCOM[6]=='5'&&IRCOM[5]=='A')
    {
         nn=6;
    }
    if(IRCOM[6]=='4'&&IRCOM[5]=='2')
    {
         nn=7;
    }
    if(IRCOM[6]=='5'&&IRCOM[5]=='2')
    {
         nn=8;
    }
    if(IRCOM[6]=='4'&&IRCOM[5]=='A')
    {
         nn=9;//关闭
    }


     beeph();
     EX0 = 1; 



/////////////////////////////////


void main (void) 
{
    init();
    Chose=Get_Chose();
    if(Chose=='0')          //chose为0的时候是悬空状态
    {
      P2=LEDMAP[0];
      delay(5000);
    }
    if(Chose=='P')
    {
        while(1)
        { 
          if(P2!=~0x5e)       //如果按下的不是d(退出键),则继续,如果是d(退出键),则退出,继续选择其他的功能
          {
              if (FlagC==1)
              {    
                  Send_data(Message);
                 FlagC=0;
              }
              else
              {
                  Get_data(Get_Mes);
                //beeph();
                  FlagC=1;
              }
          }
          else
          {
              P2=0x00;
               break;
          }
         }
      }
     if(Chose=='T')
     {
        
           initT();
        while (1) 
        {
            temper = readtemperature();
            lcd_pos(0);
            if (temper < 0) {
                write_data('-');
                temper = 0 - temper;
            } else
                write_data('+');
    
            lcd_pos(1);
            write_data((temper) / 10000 + 0x30);
    
            lcd_pos(2);
            write_data(((temper) % 10000 )/ 1000 + 0x30);
    
            lcd_pos(3);
            write_data('.');
    
            lcd_pos(4);
            write_data(((temper) % 10000 % 1000 )/ 100 + 0x30);
    
            lcd_pos(5);
            write_data(((temper) %10000 %1000 % 100 )/10 + 0x30);
            /*lcd_pos(6);
            write_data((temper) %10000 %1000 % 100 % 10 + 0x30);  */
            lcd_pos(6);
            write_data(0xdf);
            lcd_pos(7);
            write_data('C');
            if(Chose!='T')
            {
                /* uint jj=0;
                for(jj;jj<8;jj++)
                {
                     write_data(' '); 
                }
                */
                 break;
            }
        }
     }
     if(Chose=='R')        //红外控制
     {
          /*P2=LEDMAP[1];
        delay(5000); */
        IRIN=1;//初始化红外P3.2
        P10=1;//初始化蜂鸣器
        delay1h(10);
        IE = 0x81;                 //允许总中断中断,使能 INT0 外部中断
        TCON = 0x01;               //触发方式为脉冲负边沿触发
        nn=0;
        P2=LEDMAP[nn];
        while(1)
        {
            if(nn==10)
            {
                 EA=0;//关闭中断
                break;    
            }
            else{
                 P2=LEDMAP[nn];
            }
            if(Chose!='R')
            {break;}
        }
     }
}
/****************************************************
               串口中断程序
******************************************************/
void ser_int (void) interrupt 4 using 1
{
    
}


asp.net页面

插图

论文及详细源码:http://download.csdn.net/detail/s10141303/5614395


==================== 迂者 丁小未 CSDN博客专栏=================

MyBlog:http://blog.csdn.net/dingxiaowei2013              MyQQ:1213250243

MyTel:13262983383 

====================== 相互学习,共同进步 ===================





















本文转自蓬莱仙羽51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366586,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Git入门极简Git+VSCode(Mac)
Git入门极简Git+VSCode(Mac)
26 0
极简实用的Asp.NetCore框架再新增商城模块
新增加一个商城模块,主要包含商品管理(支持多个sku),商品分类,小程序用户,用户收获地址、订单各种状态的列表。
791 0
ASP.NET Core 基础教程-约定 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 基础教程-约定 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 基础教程-约定 因为 ASP.NET Core 是可以跨平台的构建和开发,因此,为了让这份教程同时适用于 Windows 和 macOS ...
940 0
《精通 ASP.NET MVC 5》----1.9 诚信
在第10章中,笔者使用了一个Bootstrap CSS库的特性,其名称为Glyphicons Halflings_,这是一组通常不免费可用的图标,但是其创建者已经为包含在Bootstrap中的图标提供了一个开放式许可。
1420 0
Model Validation in Asp.net MVC
原文:Model Validation in Asp.net MVC      本文用于记录Pro ASP.NET MVC 3 Framework中阐述的数据验证的方式。       先说服务器端的吧。
977 0
Asp.Net MVC 3.0 使用Gzip压缩
前言 Gzip最早由Jean-loup Gailly和Mark Adler创建,用于Unix系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是Gzip格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。
722 0
一起谈.NET技术,ASP.NET MVC 3 Beta初体验之实用的WebMail
  Asp.net MVC 3 Beta中提供了非常实用发送邮件的组件:WebMail。我试用了一下,和System.Web.Mail类似。这篇文章将简单介绍一下这个组件的使用。通过分成不带附件的邮件发送和带附件的邮件发送两种情况进行讲解。
984 0
一起谈.NET技术,ASP.NET MVC3 Service Location
  介绍   ASP.NET MVC3 的一个重要的新特性就是允许注册一个服务点 Service Location,然后在框架中使用的能力。以前版本的 MVC 已经提供了 Service Location 和依赖注入的机会,在 MVC3 中,我们正式提供了这种能力,并且为开发者开放了多种使用的机会。
799 0
+关注
6819
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载