赞
踩
一、项目背景及功能需求
1.1项目背景
智能门锁是一种智能化、高效、安全的门锁,它可以实现密码识别开锁方式,极大地提高了门锁的安全性和便利性。随着人们对安全性的要求越来越高,智能门锁已经成为了现代家庭和企业的必备设备。因此,本项目旨在设计一款基于STC15单片机的智能门锁,以满足人们对安全性和便利性的需求。
1.2 功能需求
从功能上来看,主要分为四个部分:显示时间、密码门锁、修改密码和计算器。其中显示时间可以实时获取当前时间日期;密码门锁不仅可以防盗,还能防止用户忘记带钥匙;修改密码可以让用户在密码泄露时及时更改密码;计算器为创新功能,可以进行一些简单的算术运算。其具体的功能架构如下:
用到的文件模块如下:
(1)显示学号:开始会显示“WelcomeSmartLock”和自己的学号
(2)显示时间:可以实时获取当前日期,星期,时间
(3)密码门锁:输入正确密码即可进行开锁,密码错误3次就会发出警报
(4)修改密码:当门锁打开时才能进行修改密码,修改的密码还需要确认重新输入一次,防止用户输错,只有当两次输入一样,才能进行密码的修改;
(5)计算器:可以进行简单的算数运算
(6)结尾有一个动画页面
二、实训环境
单片机开发板套件、Keil C51、STC-ISP
三、项目硬件搭建
3.1硬件设备
硬件部分包括单片机最小系统、矩阵按键、LCD1602、RTC、步进电机等模块,系统框图如下图所示。
3.2硬件连接电路图
3.3硬件搭建实物图
四、具体任务及内容
完成一个智能门锁,包括以下内容:首先使用软件STC-ISP自动生成所需要延时的秒数,完成延时模块的设计,然后进行LCD1062模块的配置,写好显示函数,可以再液晶屏上显示自己想要的内容;然后用取模软件生成想要的图像,使得液晶屏上能显示开锁和关锁的图像;然后完成4x4矩阵键盘的配置,能够识别哪个键盘按下,并且读入相应的信息;然后完成电机驱动模块的配置,由于单片机电压不足,于是需要引入该模块来调动电机,能够进行门锁的开关。然后进行IIC模块的配置,使得单片机能进行简单的通信;随后进行PCF8263模块的配置,能够进行时间的发送与接收,实时获取当前时间。
五、项目运行说明及截图
通过三天的努力,我成功实现了并创新了这次的智能门锁。智慧门锁从功能上来看,主要分为四个部分:显示时间,密码门锁,修改密码,计算器。其中显示时间可以实时读取显示当前时间;密码门锁只有输入正确密码才会开门,输错3次后会报警;修改密码只有开门后才有权限进行修改,并且需要输入两次一样的要修改的密码才会修改成功;计算器是附加的创新功能,可以进行简单的算术运算。
具体功能体现如下:
进入界面
时间显示界面
门锁界面
修改密码
(没开锁)
(已开锁)
计算器界面
动画界面
七、附录:(其他相关技术文档或程序实现源码)
main.c文件
- #include <stc15.h>
- #include <string.h>
- #include "LCD1602.h"
- #include "delay.h"
- #include "zimo.h"
- #include "Key16.h"
- #include "stepmotor.h"
- #include "PCF8563.h"
- #include "JiSuanQi.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit beep=P3^7;
-
- uint X=999;
- uchar clear[]=" ";
- uchar clearPwd[]=" ";
- uchar show1[]="WelcomeSmartLock";
- uchar show2[]="InputPassword";
- uchar success_show[]="Success!";
- uchar fail_show[]="Fail!";
- uchar number[]="211071085";
- extern unsigned char time_buf1[8];
- extern unsigned char time_buf[8];
-
- uchar PWD[]="888888";
- uchar input_Pwd[8];
-
- uchar oneInput[8];
- uchar twoInput[8];
-
- uchar JiSuan[10];
- uint ans;
-
- uchar clockFlag=0;
- uint Motor_Num;
- uchar my_input=0;
- uchar index=0;
- uchar pageFlag=0;
- uchar Flag=0;//行
- uchar FailNum=0;
-
- void LCD_Show_closeClock();
- void LCD_Show_openClock();
- void LCD_Clear();
- void openClock();
- void close();
- void LCD_Show_Time();
- void Show_Xin();
- void main()
- {
-
- P3M0=0x00;
- P3M1=0x00;
- LCD_Init();
- // time_init();
- LCD_Show_String(0,0,show1);
- LCD_Show_String(3,1,number);
- Delay1000ms();
- LCD_Clear();
-
- while(1)
- {
- my_input = KeyScan_4x4();
- if(my_input=='/')
- {
- pageFlag=(pageFlag+1)%5;
- LCD_Clear();
- Delay200ms();
- }
- if(pageFlag==0)//页面1显示时间
- {
- LCD_Show_Time();
- }
- else if(pageFlag==1)//页面2显示门锁
- {
- if(clockFlag==0)
- {
- LCD_Show_closeClock();
- LCD_Show_String(0,0,show2);
- }
- else if(clockFlag==1)
- {
- LCD_Show_openClock();
- }
- if('0'<=my_input && my_input<='9' && index<=7)
- {
- input_Pwd[index]=my_input;
- LCD_Show_OneChar(index, 1, input_Pwd[index]);
- Delay200ms();
- LCD_Show_OneChar(index, 1, '*');
- index++;
- LCD_Show_OneChar(14, 1, index+'0');
- }
- if(my_input=='<' && index!=0)
- {
- index--;
- input_Pwd[index]='0';
- LCD_Show_OneChar(index, 1, ' ');
- Delay200ms();
- LCD_Show_OneChar(14, 1, index+'0');
- }
-
- if(my_input=='=')
- {
- LCD_Clear();
- input_Pwd[index]='\0';
- index=0;
- if(strcmp(input_Pwd,PWD)==0 && clockFlag==0)
- {
- LCD_Show_String(0,0,success_show);
- openClock();
- Delay1000ms();
- LCD_Clear();
- clockFlag=1;
- LCD_Show_openClock();
- input_Pwd[0]='\0';
-
- }
- else
- {
- LCD_Show_String(0,0,fail_show);
- FailNum++;
- if(FailNum==3)
- {X=999;
- while(X--)
- {
- beep=0;
- Delay500us();
- beep=1;
- Delay500us();
- }
- FailNum=0;
- }
-
- Delay1000ms();
- LCD_Clear();
- LCD_Show_closeClock();
- LCD_Show_String(0,0,show2);
- }
- LCD_Show_OneChar(14, 1, index+'0');
- }
- if(my_input=='+' && clockFlag==1)
- {
- clockFlag=0;
- LCD_Clear();
- Delay200ms();
- index=0;
- close();
- LCD_Show_String(0,0,show2);
- input_Pwd[0]='\0';
- LCD_Show_OneChar(14, 1, index+'0');
- }
- if(my_input=='C')
- {
- LCD_Show_String(0,1,clearPwd);
- Delay200ms();
- index=0;
- LCD_Show_OneChar(14, 1, index+'0');
- }
-
- }
- else if(pageFlag==2)//页面3显示修改密码
- {
- if(clockFlag==1)
- {
- // LCD_Show_String(0,0,"ChangePassword!");
- // Delay1000ms();
- LCD_Show_String(0,0,"ChangeP");
- LCD_Show_String(0,1,"RepeatP");
- LCD_Show_OneChar(7, Flag, ':');
- if('0'<=my_input && my_input<='9' && index<=7)
- {
- oneInput[index]=my_input;
- LCD_Show_OneChar(index+8, Flag, oneInput[index]);
- Delay200ms();
- LCD_Show_OneChar(index+8, Flag, '*');
- index++;
- }
- if(my_input=='<' && index!=0)
- {
- index--;
- oneInput[index]='0';
- LCD_Show_OneChar(index+8, Flag, ' ');
- Delay200ms();
- }
- if(my_input=='=')
- {
- Delay200ms();
- Flag++;
- oneInput[index]='\0';
- if(Flag==2)
- {
- if(strcmp(oneInput,twoInput)==0)
- {
- strcpy(PWD,oneInput);
- LCD_Clear();
- LCD_Show_String(0,0,"ChangeSuccess!");
- Delay1000ms();
- LCD_Clear();
- }
- else
- {
- LCD_Clear();
- LCD_Show_String(0,0,"DifferentResults!");
- Delay1000ms();
- LCD_Clear();
- }
- }
- strcpy(twoInput, oneInput);
- index=0;
-
- }
- }
- else
- {
- LCD_Show_String(0,0," NoAuthority!");
- }
- }
-
- else if(pageFlag==3)//页面4计算器
- {
- if(('0'<=my_input && my_input<='9')||(my_input=='+' || my_input=='-' || my_input=='x' || my_input=='='))
- {
- JiSuan[index]=my_input;
- LCD_Show_OneChar(index, 0, JiSuan[index]);
- index++;
- JiSuan[index]='\0';
- Delay200ms();
- if(my_input=='=')
- {
- ans=Jfuntion(JiSuan);
- LCD_Show_OneChar(0, 1, ans+'0');
- }
- }
- if(my_input=='C')
- {
- LCD_Clear();
- Delay200ms();
- index=0;
- }
- if(my_input=='<' && index!=0)
- {
- index--;
- JiSuan[index]='0';
- LCD_Show_OneChar(index, 0, ' ');
- Delay200ms();
- }
-
-
-
- }
- else if(pageFlag==4)//页面5显示动画
- {
- Show_Xin();
- }
- }
-
- }
-
- void LCD_Clear()
- {
- LCD_Show_String(0,0,clear);
- LCD_Show_String(0,1,clear);
- }
- void LCD_Show_closeClock()
- {
- LCD_Show_Customer(15,0,0,close_Clock);
- LCD_Show_Customer(15,1,1,guan);
-
- }
- void LCD_Show_openClock()
- {
- LCD_Show_Customer(15,0,0,open_Clock);
- LCD_Show_Customer(15,1,1,kai);
- }
- void close()
- {
- LCD_Show_closeClock();
- Motor_Num=256;
- while(Motor_Num--)
- {
- Motor_Drive41(0,5);
- }
- MotorStop();
- }
- void openClock()
- {
- Motor_Num=256;
- LCD_Show_openClock();
- while(Motor_Num--)
- {
- Motor_Drive41(1,5);
- }
- MotorStop();
- }
-
- void LCD_Show_Time()
- {
- //显示年份
- uchar time_ge,time_shi;
- get_time();
- time_ge=time_buf1[1]%10;
- time_shi=time_buf1[1]/10;
- LCD_Show_OneChar(3,0,'2');
- LCD_Show_OneChar(4,0,'0');
- LCD_Show_OneChar(5,0,time_shi+'0');
- LCD_Show_OneChar(6,0,time_ge+'0');
- //显示月份
- time_ge=time_buf1[2]%10;
- time_shi=time_buf1[2]/10;
- LCD_Show_OneChar(8,0,time_shi+'0');
- LCD_Show_OneChar(9,0,time_ge+'0');
- //显示日
- time_ge=time_buf1[3]%10;
- time_shi=time_buf1[3]/10;
- LCD_Show_OneChar(11,0,time_shi+'0');
- LCD_Show_OneChar(12,0,time_ge+'0');
- //显示时
- time_ge=time_buf1[4]%10;
- time_shi=time_buf1[4]/10;
- LCD_Show_OneChar(4,1,time_shi+'0');
- LCD_Show_OneChar(5,1,time_ge+'0');
- //显示分
- time_ge=time_buf1[5]%10;
- time_shi=time_buf1[5]/10;
- LCD_Show_OneChar(7,1,time_shi+'0');
- LCD_Show_OneChar(8,1,time_ge+'0');
- //显示秒
- time_ge=time_buf1[6]%10;
- time_shi=time_buf1[6]/10;
- LCD_Show_OneChar(10,1,time_shi+'0');
- LCD_Show_OneChar(11,1,time_ge+'0');
-
- //显示 : 和锁
- LCD_Show_Customer(15,0,0,close_Clock);
- LCD_Show_OneChar(6,1,':');
- LCD_Show_OneChar(9,1,':');
- //显示星期
- time_ge=time_buf1[7];
- time_ge+=(time_ge==0)?1:0;
- LCD_Show_OneChar(14,0,time_ge+'0');
- }
- void Show_Xin()
- {
- uchar i;
- for(i=0;i<15;i+=2)
- {
- LCD_Show_Customer(i,0,0,myZi);
- LCD_Show_Customer(i+1,0,1,xin1_1);
-
- LCD_Show_Customer(i,1,1,xin1_1);
- LCD_Show_Customer(i+1,1,0,myZi);
- }
- Delay500ms();
- for(i=0;i<15;i+=2)
- {
- LCD_Show_Customer(i,0,0,myZi2);
- LCD_Show_Customer(i+1,0,1,xin1_2);
-
- LCD_Show_Customer(i,1,1,xin1_2);
- LCD_Show_Customer(i+1,1,0,myZi2);
- }
- Delay500ms();
- }
LCD1602.c
- #include "LCD1602.h"
- void LCD_Write_Com(uchar LCD_Com)
- {
- LCD_RS=0;//写命令
- LCD_RW=0;//写操作
- LCD_DATA=LCD_Com;//把数据放到数据线上
- Delay1ms(1);//延时,LCD1602准备接收数据
- LCD_EN=1;//EN拉高
- LCD_EN=0;//EN拉低
- }
-
- void LCD_Write_Data(uchar LCD_Data)
- {
- LCD_RS=1;//写数据
- LCD_RW=0;//写操作
- LCD_DATA=LCD_Data;//把数据放到数据线上
- Delay1ms(1);//延时,LCD1602准备接收数据
- LCD_EN=1;//EN拉高
- LCD_EN=0;//EN拉低
- }
- void LCD_Init()
- {
- //GPIO初始化
- P2M1&=0Xe5;P2M0&=0Xe5;//1110 0101设置为准双向口
- P0M1=0X00;P0M0=0X00;//设置为准双向口
- LCD_EN=0;
- LCD_RS=0;
- Delay5ms();
- LCD_Write_Com(0X38);//显示模式设置
- LCD_Write_Com(0X0C);//开关显示,光标设置0000 1100 D=1:开显示 C=0:不显示光标 B=0:光标不闪烁
- LCD_Write_Com(0X06);//光标设置 0000 0110 N=1 光标自动加1 S=0 整屏不移动
- LCD_Write_Com(0X01);//清屏
- Delay1ms(5);
- }
-
- void LCD_Show_OneChar(uchar X,uchar Y,uchar LCD_char)
- {
- X&=0X0F;
- Y&=0X01;//限制X不能大于15,Y不能大于1
- if(Y)
- {
- X=X+0X40;//当要显示的位置在第二行时,算出地址
- }
- X=X+0X80;//计算地址指令码
- LCD_Write_Com(X);//发送命令
- LCD_Write_Data(LCD_char);//发送显示的数据
- }
- void LCD_Show_String(uchar X,uchar Y,uchar *LCD_String)
- {
- uchar i;
- for(i=0;LCD_String[i]!='\0';i++)
- {
- LCD_Show_OneChar(X,Y,LCD_String[i]);
- X++;
- }
- }
- /*显示自定义字符:本函数实现在CGRAM的0X00的地址中写入自定义字符,然后显示在XY坐标位置
- LCD1602可定义的字符可存在CGROM的0X00-0X07共8个位置
- X:列地址(0-15)
- Y:行地址(0-1)
- Num:自定义字符在CGROM中存储的位置(0-7)
- LCD_String:自定义字符的取模;若用取模软件(阴码/行列式/顺向)
- */
- void LCD_Show_Customer(uchar X,uchar Y,uchar Num,uchar *LCD_Cust)//显示自定义字符
- {
- uchar i;
- uchar Com=Num;//用于计算CGRAM地址指令
- X&=0X0F;
- Y&=0X01;//限制X不能大于15,Y不能大于1
- if(Y)
- {
- X=X+0X40;//当要显示的位置在第二行时,算出地址
- }
- X=X+0X80;//计算地址指令码
- Com=Com<<3;
- Com=Com+0X40;//计算指令码
- for(i=0;i<8;i++)
- {
- LCD_Write_Com(Com);//设置存入数据的地址
- Com++;
- LCD_Write_Data(LCD_Cust[i]);//逐行填充每行的内容
- }
- LCD_Write_Com(X);//发送命令
- LCD_Write_Data(Num);//发送显示的数据
- }
LCD1602.h
- #ifndef _LCD1602_H
- #define _LCD1602_H
- #define uchar unsigned char
- #define uint unsigned int
- #include <stc15.h>
- #include "delay.h"
- sbit LCD_EN=P2^1;
- sbit LCD_RS=P2^4;
- sbit LCD_RW=P2^3;
- #define LCD_DATA P0
- void LCD_Init();
- void LCD_Show_OneChar(uchar X,uchar Y,uchar LCD_char);
- void LCD_Show_String(uchar X,uchar Y,uchar *LCD_String);
- void LCD_Show_Customer(uchar X,uchar Y,uchar Num,uchar *LCD_Cust);
-
-
- #endif
iic.c
- #include "iic.h"
-
- //起始信号
- void IIC_Start (void)
- {
- SDA =1;
- SCL = 1;
- Delay1us();
- SDA = 0;
-
- }
-
- //终止信号
- void IIC_Stop(void)
- {
- SDA = 0;
- SCL = 1;
- Delay1us();
- SDA = 1;
- Delay1us();
- }
-
- //等待应答
- bit IIC_WaitAck(void)
- {
- bit i;
- SCL = 1;
- Delay1us();
- i = SDA;
- SCL = 0;
- return i;
- }
-
- //应答位控制
- void IIC_SendAck(bit j)
- {
- SCL = 0;
- Delay1us();
- SCL = 1;
- Delay1us();
- SDA = j;
- Delay1us();
- SCL = 0;
- SDA = 1;
- Delay1us();
- }
-
- //I2C发送1个字节数据
- void IIC_SendByte(unsigned char dite)
- {
- unsigned char i;
- SDA = 0;
- SCL =0;
- Delay1us();
- for(i=0;i<8;i++)
- {
- if(dite &0x80) SDA = 1;
- else SDA =0;
- Delay1us();
- dite <<=1;
- SCL = 1;
- Delay1us();
- SCL = 0;
- Delay1us();
- }
- }
- //I2C接收1个字节数据
- unsigned char IIC_RecByte(void)
- {
- unsigned char i,tmpe;
-
- SCL = 0;
- Delay1us();
-
- for(i=0;i<8;i++)
- {
- SCL = 1;
- Delay1us();
- tmpe = tmpe<<1;
- if(SDA) tmpe |=1;
- SCL =0;
- Delay1us();
- }
- return tmpe;
- }
-
-
iic.h
- #ifndef _IIC_H
- #define _IIC_H
- #include <stc15.h>
- #include "delay.h"
-
-
- //总线引脚定义
- sbit SDA = P5^3; /* 数据线 */
- sbit SCL = P5^2; /* 时钟线 */
-
-
-
- void IIC_Start (void);//起始信号
- void IIC_Stop(void);//终止信号
- bit IIC_WaitAck(void);//等待应答
- void IIC_SendAck(bit j);//应答位控制
- void IIC_SendByte(unsigned char dite);//I2C发送1个字节数据
- unsigned char IIC_RecByte(void);//I2C接收1个字节数据
-
-
-
- #endif
stempmotor.c
- #include "stepmotor.h"
-
- //步进电机初始化
- void StepMotor_Init()
- {
- P1M1 &= 0xF0; P1M0 |= 0x0F; //设置P1.0~P1.3为推挽输出
- // P1M1 &= 0xF0; P1M0 &= 0xF0; //设置P1.0~P1.3为准双向
- }
-
- //电机停止
- void MotorStop(void)
- {
- DD=0;CC=0;BB=0;AA=0;
- }
-
-
- //步进电机转动:单四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
- void Motor_Drive41(uchar X,uint Speed)
- {
- if(X==1) //顺时针转动
- {
- DD=0;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=0;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
- }
- else //逆时针转动
- {
- DD=1;CC=0;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
- }
- }
-
-
- //步进电机转动:双四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
- void Motor_Drive42(uchar X,uint Speed)
- {
- if(X==1) //顺时针转动
- {
- DD=0;CC=0;BB=1;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
- }
- else //逆时针转动
- {
- DD=1;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=1;
- Delay1ms(Speed); //转速调节
- }
- }
-
-
- //步进电机转动:八拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
- void Motor_Drive8(uchar X,uint Speed)
- {
- if(X==1) //顺时针转动
- {
- DD=0;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=0;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
- }
- else //逆时针转动
- {
- DD=1;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=0;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=1;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=0;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=1;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=0;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=1;AA=1;
- Delay1ms(Speed); //转速调节
-
- DD=0;CC=0;BB=0;AA=1;
- Delay1ms(Speed); //转速调节
- }
- }
stempmotor.h
- #ifndef _STEPMOTOR_H
- #define _STEPMOTOR_H
- #include <stc15.h>
- #include "delay.h"
-
- #define uchar unsigned char
- #define uint unsigned int
-
- sbit AA=P1^0; //电机控制口,连接电机驱动板IN1
- sbit BB=P1^1; //电机控制口,连接电机驱动板IN2
- sbit CC=P1^2; //电机控制口,连接电机驱动板IN3
- sbit DD=P1^3; //电机控制口,连接电机驱动板IN4
-
-
- void StepMotor_Init();//步进电机初始化
- void MotorStop(void);//电机停止
- void Motor_Drive41(uchar X,uint Speed);//步进电机转动:单四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
- void Motor_Drive42(uchar X,uint Speed);//步进电机转动:双四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
- void Motor_Drive8(uchar X,uint Speed);//步进电机转动:八拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
-
-
- #endif
PCF8563.c
- #include "PCF8563.h"
-
-
- unsigned char time_buf1[8]={20,23,5,31,21,11,0,3};//空年月日时分秒星期(10进制)
- unsigned char time_buf[8]; //空年月日时分秒星期 (16进制)
-
- //使用封装好的I2C函数,进行函数PCF8563的写函数封装:向地址Adddrsend中写入数据Datasend
- //函数编写流程为 :start->发送设备地址->等待ACK->发送需要被写的内存地址->等待ACK->发送数据写入E2PROM->等待ACK->STOP
- void PCF8563_WriteOneByte(unsigned char Adddrsend, unsigned char Datasend)
- {
- IIC_Start();
- IIC_SendByte(0xA2);//通过I2C总线发送数据(芯片指令)写操作
- IIC_WaitAck();
- IIC_SendByte(Adddrsend);
- IIC_WaitAck();
- IIC_SendByte(Datasend);
- IIC_WaitAck();
- IIC_Stop();
- Delay1ms(10);
- }
-
- //使用封装好的I2C函数,进行函数PCF8563的读数据函数封装:从Adddrsend中读出数据,作为返回值
- //读函数编写流程:start->发送设备地址->等待ACK->发送需要被读的内存地址->等待ACK->发送读指令(设备地址)->等待ACK-->读内存数据->等待no ACK->STOP
- unsigned char PCF8563_ReadOneByte(unsigned char Adddrsend)
- {
- unsigned char Rec;
- IIC_Start();
- IIC_SendByte(0xA2);//通过I2C总线发送数据(芯片指令)写操作
- IIC_WaitAck();
- IIC_SendByte(Adddrsend);
- IIC_WaitAck();
- IIC_Start();
- IIC_SendByte(0xA3);
- IIC_WaitAck();
- Rec=IIC_RecByte();
- IIC_Stop();
- return Rec;
- }
-
- /******************BCD转十进制***************************/
- unsigned char bcd_dec(unsigned char bat)
- {
- unsigned char temp1,temp2,tol;
- temp1=bat&0x0f;
- temp2=(bat&0xf0)>>4;
- tol=temp2*10+temp1;
- return tol;
- }
- /******************十进制转BCD***************************/
- unsigned char dec_bcd(unsigned char bat)
- {
- return ((bat%10) & 0x0F) | (((bat/10) << 4) & 0xF0);;
- }
-
-
- //获取当前时间并转化
- void get_time(void)
- {
- time_buf[6]=0x7f&PCF8563_ReadOneByte(0x02); //读取秒
- time_buf[5]=0x7f&PCF8563_ReadOneByte(0x03); //读取分钟
- time_buf[4]=0x3f&PCF8563_ReadOneByte(0x04); //读取小时
- time_buf[3]=0x3f&PCF8563_ReadOneByte(0x05); //读取天数
- time_buf[2]=0x1f&PCF8563_ReadOneByte(0x07); //读取月
- time_buf[1]=0xff&PCF8563_ReadOneByte(0x08); //读取年
- time_buf[7]=0x07&PCF8563_ReadOneByte(0x06); //读取星期
-
-
- time_buf1[6]=bcd_dec(time_buf[6]); //将读取的BCD码转换成十进制以便运算,秒
- time_buf1[5]=bcd_dec(time_buf[5]); //将读取的BCD码转换成十进制以便运算,分
- time_buf1[4]=bcd_dec(time_buf[4]); //将读取的BCD码转换成十进制以便运算,小时
- time_buf1[3]=bcd_dec(time_buf[3]); //将读取的BCD码转换成十进制以便运算,日
- time_buf1[2]=bcd_dec(time_buf[2]); //将读取的BCD码转换成十进制以便运算,月
- time_buf1[1]=bcd_dec(time_buf[1]); //将读取的BCD码转换成十进制以便运算,年
- time_buf1[7]=bcd_dec(time_buf[7]); //将读取的BCD码转换成十进制以便运算,星期
- //printf("20%d年%d月%d日%d时%d分%d秒\r\n",date.year1,date.moom1,date.dat1,date.hour1,date.min1,date.sec1);
- }
-
-
- //初始化当前时间
- void time_init()
- {
- //将十进制数转化为BCD值,方便写入PCF8563
- time_buf[1] = dec_bcd(time_buf1[1]);
- time_buf[2] = dec_bcd(time_buf1[2]);
- time_buf[3] = dec_bcd(time_buf1[3]);
- time_buf[4] = dec_bcd(time_buf1[4]);
- time_buf[5] = dec_bcd(time_buf1[5]);
- time_buf[6] = dec_bcd(time_buf1[6]);
- time_buf[7] = dec_bcd(time_buf1[7]);
-
-
- PCF8563_WriteOneByte(0x02,time_buf[6]); //写入秒
- PCF8563_WriteOneByte(0x03,time_buf[5]); //写入分
- PCF8563_WriteOneByte(0x04,time_buf[4]); //写入小时
- PCF8563_WriteOneByte(0x05,time_buf[3]); //写入日
- PCF8563_WriteOneByte(0x07,time_buf[2]); //写入月
- PCF8563_WriteOneByte(0x08,time_buf[1]); //写入年
- PCF8563_WriteOneByte(0x06,time_buf[7]); //写入星期
-
- }
PCF8563.h
- #ifndef _PCF8563_H
- #define _PCF8563_H
-
- #include "iic.h"
- #define uchar unsigned char
- #define uint unsigned int
-
- //typedef struct {
- // uint16_t year;
- // uint8_t mon;
- // uint8_t day;
- // uint8_t hour;
- // uint8_t min;
- // uint8_t sec;
- // uint8_t week;
- //}sTime;
-
- void PCF8563_WriteOneByte(unsigned char Adddrsend, unsigned char Datasend);
- unsigned char PCF8563_ReadOneByte(unsigned char Adddrsend);
- unsigned char bcd_dec(unsigned char bat);
- unsigned char dec_bcd(unsigned char bat);
- void time_init();//初始化当前时间
- void get_time(void);//读取当前时间
-
-
-
- #endif
Key16.c
- #include "Key16.h"
-
- uchar KeyScan_4x4(void)
- {
- uchar X_temp,Y_temp,temp;
- X_temp=0XF0;//列值赋初值
- Y_temp=0X0F;//行值赋初值
- P2M1&=0X3F;P2M0|=0XC0;//设置P2.6-P2.7为强推挽输出 0011 1111;1100 0000
- P4M1&=0X0F;P4M0|=0XF0;//设置P4.4-P4.7为强推挽输出 0000 1111;1111 0000
- P5M1&=0XF3;P5M0|=0X0C;//设置P5.2-P5.3为强推挽输出 1111 0011;0000 1100
-
- ROW1=1;ROW2=1;ROW3=1;ROW4=1;//行置高
- COL1=0;COL2=0;COL3=0;COL4=0;//列置低
- //所用到行IO口配置为输入,进行检测
- Delay1ms(10);
- P4M1&=0X0F;P4M0&=0X0F;//设置P4.4-P4.7为准双向口
- Delay1ms(10);
- if(ROW1==0)//检测行1电平是否为低电平
- {
- Delay1ms(10);
- if(ROW1==0)
- Y_temp&=0X0E;
- }
- if(ROW2==0)//检测行2电平是否为低电平
- {
- Delay1ms(10);
- if(ROW2==0)
- Y_temp&=0X0D;
- }
- if(ROW3==0)//检测行3电平是否为低电平
- {
- Delay1ms(10);
- if(ROW3==0)
- Y_temp&=0X0B;
- }
- if(ROW4==0)//检测行4电平是否为低电平
- {
- Delay1ms(10);
- if(ROW4==0)
- Y_temp&=0X07;
- }
- P2M1&=0X3F;P2M0|=0XC0;//设置P2.6-P2.7为强推挽输出 0011 1111;1100 0000
- P4M1&=0X0F;P4M0|=0XF0;//设置P4.4-P4.7为强推挽输出 0000 1111;1111 0000
- P5M1&=0XF3;P5M0|=0X0C;//设置P5.2-P5.3为强推挽输出 1111 0011;0000 1100
- ROW1=0;ROW2=0;ROW3=0;ROW4=0;//行置低
- COL1=1;COL2=1;COL3=1;COL4=1;//列置高
- Delay1ms(10);
- P2M1&=0X3F;P2M0&=0X3F;//设置P2.6-P2.7为准双向口
- P5M1&=0XF3;P5M0&=0XF3;//设置P5.2-P5.3为准双向口
- Delay1ms(10);
- if(COL1==0)//检测列1电平是否为低电平
- {
- Delay1ms(10);
- if(COL1==0)
- X_temp&=0XE0;
- }
- if(COL2==0)//检测列2电平是否为低电平
- {
- Delay1ms(10);
- if(COL2==0)
- X_temp&=0XD0;
- }
- if(COL3==0)//检测列3电平是否为低电平
- {
- Delay1ms(10);
- if(COL3==0)
- X_temp&=0XB0;
- }
- if(COL4==0)//检测列4电平是否为低电平
- {
- Delay1ms(10);
- if(COL4==0)
- X_temp&=0X70;
- }
- //将行值和列值合并,得到按键对应的编码值,该值与16个按键一一对应
- temp=X_temp|Y_temp;
- temp=~temp;
- //将按键检测的原始编码值解析对应按键值信息
- switch(temp)//颠倒键值
- {
- case 0X11:return '/';//1
- case 0X21:return 'x';//2
- case 0X41:return '-';//3
- case 0X81:return '+';//4
- case 0X12:return '=';//5
- case 0X22:return '9';//6
- case 0X42:return '8';//7
- case 0X82:return '7';//8
- case 0X14:return 'C';//9
- case 0X24:return '6';//0
- case 0X44:return '5';//a
- case 0X84:return '4';//b
- case 0X18:return '<';//c
- case 0X28:return '3';//d
- case 0X48:return '2';//e
- case 0X88:return '1';//f
- default:return 0;
- }
- }
Key16.h
- #ifndef _KEY_4X4_H
- #define _KEY_4X4_H
-
- #include <stc15.h>
- #include "delay.h"
-
- #define uchar unsigned char
- #define uint unsigned int
-
- /*
- 矩阵按键引脚定义*/
- sbit COL4=P5^2; //4*4矩阵检测列检测端口
- sbit COL3=P5^3; //4*4矩阵检测列检测端口
- sbit COL2=P2^6; //4*4矩阵检测列检测端口
- sbit COL1=P2^7; //4*4矩阵检测列检测端口
- sbit ROW4=P4^4; //4*4矩阵检测行检测端口
- sbit ROW3=P4^5; //4*4矩阵检测行检测端口
- sbit ROW2=P4^6; //4*4矩阵检测行检测端口
- sbit ROW1=P4^7; //4*4矩阵检测行检测端口
-
-
- uchar KeyScan_4x4(void);
-
- #endif
zimo.h
- #ifndef _ZIMO_H
- #define _ZIMO_H
- #define uchar unsigned char
- #define uint unsigned int
-
- uchar code close_Clock[]={0x0E,0x0A,0x0A,0x0A,0x1F,0x11,0x11,0x1F};//??
- uchar code guan[] = {0x11,0x0A,0x1F,0x0A,0x1F,0x0A,0x1B,0x00};
- uchar code kai[] = {0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x0A,0x00};
- uchar code open_Clock[]={0x0E,0x02,0x02,0x02,0x1F,0x11,0x11,0x1F};//???
- uchar code myZi[] = {0x00,0x00,0x0A,0x15,0x11,0x0A,0x04,0x00};
- uchar code myZi2[] = {0x00,0x0A,0x15,0x15,0x11,0x0A,0x04,0x00};
- uchar code xin1_2[] = {0x00,0x0A,0x1F,0x1F,0x1F,0x0E,0x04,0x00};
- uchar code xin1_1[] = {0x00,0x00,0x0A,0x1F,0x1F,0x0E,0x04,0x00};
-
-
- #endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。