当前位置:   article > 正文

基于STC15系列单片机的智能门锁(含IIC、步进电机、矩阵按键、PCF8263、LCD1602等配置文件)_单片机stc15系统设计

单片机stc15系统设计

一、项目背景及功能需求

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文件

  1. #include <stc15.h>
  2. #include <string.h>
  3. #include "LCD1602.h"
  4. #include "delay.h"
  5. #include "zimo.h"
  6. #include "Key16.h"
  7. #include "stepmotor.h"
  8. #include "PCF8563.h"
  9. #include "JiSuanQi.h"
  10. #define uchar unsigned char
  11. #define uint unsigned int
  12. sbit beep=P3^7;
  13. uint X=999;
  14. uchar clear[]=" ";
  15. uchar clearPwd[]=" ";
  16. uchar show1[]="WelcomeSmartLock";
  17. uchar show2[]="InputPassword";
  18. uchar success_show[]="Success!";
  19. uchar fail_show[]="Fail!";
  20. uchar number[]="211071085";
  21. extern unsigned char time_buf1[8];
  22. extern unsigned char time_buf[8];
  23. uchar PWD[]="888888";
  24. uchar input_Pwd[8];
  25. uchar oneInput[8];
  26. uchar twoInput[8];
  27. uchar JiSuan[10];
  28. uint ans;
  29. uchar clockFlag=0;
  30. uint Motor_Num;
  31. uchar my_input=0;
  32. uchar index=0;
  33. uchar pageFlag=0;
  34. uchar Flag=0;//行
  35. uchar FailNum=0;
  36. void LCD_Show_closeClock();
  37. void LCD_Show_openClock();
  38. void LCD_Clear();
  39. void openClock();
  40. void close();
  41. void LCD_Show_Time();
  42. void Show_Xin();
  43. void main()
  44. {
  45. P3M0=0x00;
  46. P3M1=0x00;
  47. LCD_Init();
  48. // time_init();
  49. LCD_Show_String(0,0,show1);
  50. LCD_Show_String(3,1,number);
  51. Delay1000ms();
  52. LCD_Clear();
  53. while(1)
  54. {
  55. my_input = KeyScan_4x4();
  56. if(my_input=='/')
  57. {
  58. pageFlag=(pageFlag+1)%5;
  59. LCD_Clear();
  60. Delay200ms();
  61. }
  62. if(pageFlag==0)//页面1显示时间
  63. {
  64. LCD_Show_Time();
  65. }
  66. else if(pageFlag==1)//页面2显示门锁
  67. {
  68. if(clockFlag==0)
  69. {
  70. LCD_Show_closeClock();
  71. LCD_Show_String(0,0,show2);
  72. }
  73. else if(clockFlag==1)
  74. {
  75. LCD_Show_openClock();
  76. }
  77. if('0'<=my_input && my_input<='9' && index<=7)
  78. {
  79. input_Pwd[index]=my_input;
  80. LCD_Show_OneChar(index, 1, input_Pwd[index]);
  81. Delay200ms();
  82. LCD_Show_OneChar(index, 1, '*');
  83. index++;
  84. LCD_Show_OneChar(14, 1, index+'0');
  85. }
  86. if(my_input=='<' && index!=0)
  87. {
  88. index--;
  89. input_Pwd[index]='0';
  90. LCD_Show_OneChar(index, 1, ' ');
  91. Delay200ms();
  92. LCD_Show_OneChar(14, 1, index+'0');
  93. }
  94. if(my_input=='=')
  95. {
  96. LCD_Clear();
  97. input_Pwd[index]='\0';
  98. index=0;
  99. if(strcmp(input_Pwd,PWD)==0 && clockFlag==0)
  100. {
  101. LCD_Show_String(0,0,success_show);
  102. openClock();
  103. Delay1000ms();
  104. LCD_Clear();
  105. clockFlag=1;
  106. LCD_Show_openClock();
  107. input_Pwd[0]='\0';
  108. }
  109. else
  110. {
  111. LCD_Show_String(0,0,fail_show);
  112. FailNum++;
  113. if(FailNum==3)
  114. {X=999;
  115. while(X--)
  116. {
  117. beep=0;
  118. Delay500us();
  119. beep=1;
  120. Delay500us();
  121. }
  122. FailNum=0;
  123. }
  124. Delay1000ms();
  125. LCD_Clear();
  126. LCD_Show_closeClock();
  127. LCD_Show_String(0,0,show2);
  128. }
  129. LCD_Show_OneChar(14, 1, index+'0');
  130. }
  131. if(my_input=='+' && clockFlag==1)
  132. {
  133. clockFlag=0;
  134. LCD_Clear();
  135. Delay200ms();
  136. index=0;
  137. close();
  138. LCD_Show_String(0,0,show2);
  139. input_Pwd[0]='\0';
  140. LCD_Show_OneChar(14, 1, index+'0');
  141. }
  142. if(my_input=='C')
  143. {
  144. LCD_Show_String(0,1,clearPwd);
  145. Delay200ms();
  146. index=0;
  147. LCD_Show_OneChar(14, 1, index+'0');
  148. }
  149. }
  150. else if(pageFlag==2)//页面3显示修改密码
  151. {
  152. if(clockFlag==1)
  153. {
  154. // LCD_Show_String(0,0,"ChangePassword!");
  155. // Delay1000ms();
  156. LCD_Show_String(0,0,"ChangeP");
  157. LCD_Show_String(0,1,"RepeatP");
  158. LCD_Show_OneChar(7, Flag, ':');
  159. if('0'<=my_input && my_input<='9' && index<=7)
  160. {
  161. oneInput[index]=my_input;
  162. LCD_Show_OneChar(index+8, Flag, oneInput[index]);
  163. Delay200ms();
  164. LCD_Show_OneChar(index+8, Flag, '*');
  165. index++;
  166. }
  167. if(my_input=='<' && index!=0)
  168. {
  169. index--;
  170. oneInput[index]='0';
  171. LCD_Show_OneChar(index+8, Flag, ' ');
  172. Delay200ms();
  173. }
  174. if(my_input=='=')
  175. {
  176. Delay200ms();
  177. Flag++;
  178. oneInput[index]='\0';
  179. if(Flag==2)
  180. {
  181. if(strcmp(oneInput,twoInput)==0)
  182. {
  183. strcpy(PWD,oneInput);
  184. LCD_Clear();
  185. LCD_Show_String(0,0,"ChangeSuccess!");
  186. Delay1000ms();
  187. LCD_Clear();
  188. }
  189. else
  190. {
  191. LCD_Clear();
  192. LCD_Show_String(0,0,"DifferentResults!");
  193. Delay1000ms();
  194. LCD_Clear();
  195. }
  196. }
  197. strcpy(twoInput, oneInput);
  198. index=0;
  199. }
  200. }
  201. else
  202. {
  203. LCD_Show_String(0,0," NoAuthority!");
  204. }
  205. }
  206. else if(pageFlag==3)//页面4计算器
  207. {
  208. if(('0'<=my_input && my_input<='9')||(my_input=='+' || my_input=='-' || my_input=='x' || my_input=='='))
  209. {
  210. JiSuan[index]=my_input;
  211. LCD_Show_OneChar(index, 0, JiSuan[index]);
  212. index++;
  213. JiSuan[index]='\0';
  214. Delay200ms();
  215. if(my_input=='=')
  216. {
  217. ans=Jfuntion(JiSuan);
  218. LCD_Show_OneChar(0, 1, ans+'0');
  219. }
  220. }
  221. if(my_input=='C')
  222. {
  223. LCD_Clear();
  224. Delay200ms();
  225. index=0;
  226. }
  227. if(my_input=='<' && index!=0)
  228. {
  229. index--;
  230. JiSuan[index]='0';
  231. LCD_Show_OneChar(index, 0, ' ');
  232. Delay200ms();
  233. }
  234. }
  235. else if(pageFlag==4)//页面5显示动画
  236. {
  237. Show_Xin();
  238. }
  239. }
  240. }
  241. void LCD_Clear()
  242. {
  243. LCD_Show_String(0,0,clear);
  244. LCD_Show_String(0,1,clear);
  245. }
  246. void LCD_Show_closeClock()
  247. {
  248. LCD_Show_Customer(15,0,0,close_Clock);
  249. LCD_Show_Customer(15,1,1,guan);
  250. }
  251. void LCD_Show_openClock()
  252. {
  253. LCD_Show_Customer(15,0,0,open_Clock);
  254. LCD_Show_Customer(15,1,1,kai);
  255. }
  256. void close()
  257. {
  258. LCD_Show_closeClock();
  259. Motor_Num=256;
  260. while(Motor_Num--)
  261. {
  262. Motor_Drive41(0,5);
  263. }
  264. MotorStop();
  265. }
  266. void openClock()
  267. {
  268. Motor_Num=256;
  269. LCD_Show_openClock();
  270. while(Motor_Num--)
  271. {
  272. Motor_Drive41(1,5);
  273. }
  274. MotorStop();
  275. }
  276. void LCD_Show_Time()
  277. {
  278. //显示年份
  279. uchar time_ge,time_shi;
  280. get_time();
  281. time_ge=time_buf1[1]%10;
  282. time_shi=time_buf1[1]/10;
  283. LCD_Show_OneChar(3,0,'2');
  284. LCD_Show_OneChar(4,0,'0');
  285. LCD_Show_OneChar(5,0,time_shi+'0');
  286. LCD_Show_OneChar(6,0,time_ge+'0');
  287. //显示月份
  288. time_ge=time_buf1[2]%10;
  289. time_shi=time_buf1[2]/10;
  290. LCD_Show_OneChar(8,0,time_shi+'0');
  291. LCD_Show_OneChar(9,0,time_ge+'0');
  292. //显示日
  293. time_ge=time_buf1[3]%10;
  294. time_shi=time_buf1[3]/10;
  295. LCD_Show_OneChar(11,0,time_shi+'0');
  296. LCD_Show_OneChar(12,0,time_ge+'0');
  297. //显示时
  298. time_ge=time_buf1[4]%10;
  299. time_shi=time_buf1[4]/10;
  300. LCD_Show_OneChar(4,1,time_shi+'0');
  301. LCD_Show_OneChar(5,1,time_ge+'0');
  302. //显示分
  303. time_ge=time_buf1[5]%10;
  304. time_shi=time_buf1[5]/10;
  305. LCD_Show_OneChar(7,1,time_shi+'0');
  306. LCD_Show_OneChar(8,1,time_ge+'0');
  307. //显示秒
  308. time_ge=time_buf1[6]%10;
  309. time_shi=time_buf1[6]/10;
  310. LCD_Show_OneChar(10,1,time_shi+'0');
  311. LCD_Show_OneChar(11,1,time_ge+'0');
  312. //显示 : 和锁
  313. LCD_Show_Customer(15,0,0,close_Clock);
  314. LCD_Show_OneChar(6,1,':');
  315. LCD_Show_OneChar(9,1,':');
  316. //显示星期
  317. time_ge=time_buf1[7];
  318. time_ge+=(time_ge==0)?1:0;
  319. LCD_Show_OneChar(14,0,time_ge+'0');
  320. }
  321. void Show_Xin()
  322. {
  323. uchar i;
  324. for(i=0;i<15;i+=2)
  325. {
  326. LCD_Show_Customer(i,0,0,myZi);
  327. LCD_Show_Customer(i+1,0,1,xin1_1);
  328. LCD_Show_Customer(i,1,1,xin1_1);
  329. LCD_Show_Customer(i+1,1,0,myZi);
  330. }
  331. Delay500ms();
  332. for(i=0;i<15;i+=2)
  333. {
  334. LCD_Show_Customer(i,0,0,myZi2);
  335. LCD_Show_Customer(i+1,0,1,xin1_2);
  336. LCD_Show_Customer(i,1,1,xin1_2);
  337. LCD_Show_Customer(i+1,1,0,myZi2);
  338. }
  339. Delay500ms();
  340. }

LCD1602.c

  1. #include "LCD1602.h"
  2. void LCD_Write_Com(uchar LCD_Com)
  3. {
  4. LCD_RS=0;//写命令
  5. LCD_RW=0;//写操作
  6. LCD_DATA=LCD_Com;//把数据放到数据线上
  7. Delay1ms(1);//延时,LCD1602准备接收数据
  8. LCD_EN=1;//EN拉高
  9. LCD_EN=0;//EN拉低
  10. }
  11. void LCD_Write_Data(uchar LCD_Data)
  12. {
  13. LCD_RS=1;//写数据
  14. LCD_RW=0;//写操作
  15. LCD_DATA=LCD_Data;//把数据放到数据线上
  16. Delay1ms(1);//延时,LCD1602准备接收数据
  17. LCD_EN=1;//EN拉高
  18. LCD_EN=0;//EN拉低
  19. }
  20. void LCD_Init()
  21. {
  22. //GPIO初始化
  23. P2M1&=0Xe5;P2M0&=0Xe5;//1110 0101设置为准双向口
  24. P0M1=0X00;P0M0=0X00;//设置为准双向口
  25. LCD_EN=0;
  26. LCD_RS=0;
  27. Delay5ms();
  28. LCD_Write_Com(0X38);//显示模式设置
  29. LCD_Write_Com(0X0C);//开关显示,光标设置0000 1100 D=1:开显示 C=0:不显示光标 B=0:光标不闪烁
  30. LCD_Write_Com(0X06);//光标设置 0000 0110 N=1 光标自动加1 S=0 整屏不移动
  31. LCD_Write_Com(0X01);//清屏
  32. Delay1ms(5);
  33. }
  34. void LCD_Show_OneChar(uchar X,uchar Y,uchar LCD_char)
  35. {
  36. X&=0X0F;
  37. Y&=0X01;//限制X不能大于15,Y不能大于1
  38. if(Y)
  39. {
  40. X=X+0X40;//当要显示的位置在第二行时,算出地址
  41. }
  42. X=X+0X80;//计算地址指令码
  43. LCD_Write_Com(X);//发送命令
  44. LCD_Write_Data(LCD_char);//发送显示的数据
  45. }
  46. void LCD_Show_String(uchar X,uchar Y,uchar *LCD_String)
  47. {
  48. uchar i;
  49. for(i=0;LCD_String[i]!='\0';i++)
  50. {
  51. LCD_Show_OneChar(X,Y,LCD_String[i]);
  52. X++;
  53. }
  54. }
  55. /*显示自定义字符:本函数实现在CGRAM的0X00的地址中写入自定义字符,然后显示在XY坐标位置
  56. LCD1602可定义的字符可存在CGROM的0X00-0X07共8个位置
  57. X:列地址(0-15)
  58. Y:行地址(0-1)
  59. Num:自定义字符在CGROM中存储的位置(0-7)
  60. LCD_String:自定义字符的取模;若用取模软件(阴码/行列式/顺向)
  61. */
  62. void LCD_Show_Customer(uchar X,uchar Y,uchar Num,uchar *LCD_Cust)//显示自定义字符
  63. {
  64. uchar i;
  65. uchar Com=Num;//用于计算CGRAM地址指令
  66. X&=0X0F;
  67. Y&=0X01;//限制X不能大于15,Y不能大于1
  68. if(Y)
  69. {
  70. X=X+0X40;//当要显示的位置在第二行时,算出地址
  71. }
  72. X=X+0X80;//计算地址指令码
  73. Com=Com<<3;
  74. Com=Com+0X40;//计算指令码
  75. for(i=0;i<8;i++)
  76. {
  77. LCD_Write_Com(Com);//设置存入数据的地址
  78. Com++;
  79. LCD_Write_Data(LCD_Cust[i]);//逐行填充每行的内容
  80. }
  81. LCD_Write_Com(X);//发送命令
  82. LCD_Write_Data(Num);//发送显示的数据
  83. }

LCD1602.h

  1. #ifndef _LCD1602_H
  2. #define _LCD1602_H
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #include <stc15.h>
  6. #include "delay.h"
  7. sbit LCD_EN=P2^1;
  8. sbit LCD_RS=P2^4;
  9. sbit LCD_RW=P2^3;
  10. #define LCD_DATA P0
  11. void LCD_Init();
  12. void LCD_Show_OneChar(uchar X,uchar Y,uchar LCD_char);
  13. void LCD_Show_String(uchar X,uchar Y,uchar *LCD_String);
  14. void LCD_Show_Customer(uchar X,uchar Y,uchar Num,uchar *LCD_Cust);
  15. #endif

iic.c

  1. #include "iic.h"
  2. //起始信号
  3. void IIC_Start (void)
  4. {
  5. SDA =1;
  6. SCL = 1;
  7. Delay1us();
  8. SDA = 0;
  9. }
  10. //终止信号
  11. void IIC_Stop(void)
  12. {
  13. SDA = 0;
  14. SCL = 1;
  15. Delay1us();
  16. SDA = 1;
  17. Delay1us();
  18. }
  19. //等待应答
  20. bit IIC_WaitAck(void)
  21. {
  22. bit i;
  23. SCL = 1;
  24. Delay1us();
  25. i = SDA;
  26. SCL = 0;
  27. return i;
  28. }
  29. //应答位控制
  30. void IIC_SendAck(bit j)
  31. {
  32. SCL = 0;
  33. Delay1us();
  34. SCL = 1;
  35. Delay1us();
  36. SDA = j;
  37. Delay1us();
  38. SCL = 0;
  39. SDA = 1;
  40. Delay1us();
  41. }
  42. //I2C发送1个字节数据
  43. void IIC_SendByte(unsigned char dite)
  44. {
  45. unsigned char i;
  46. SDA = 0;
  47. SCL =0;
  48. Delay1us();
  49. for(i=0;i<8;i++)
  50. {
  51. if(dite &0x80) SDA = 1;
  52. else SDA =0;
  53. Delay1us();
  54. dite <<=1;
  55. SCL = 1;
  56. Delay1us();
  57. SCL = 0;
  58. Delay1us();
  59. }
  60. }
  61. //I2C接收1个字节数据
  62. unsigned char IIC_RecByte(void)
  63. {
  64. unsigned char i,tmpe;
  65. SCL = 0;
  66. Delay1us();
  67. for(i=0;i<8;i++)
  68. {
  69. SCL = 1;
  70. Delay1us();
  71. tmpe = tmpe<<1;
  72. if(SDA) tmpe |=1;
  73. SCL =0;
  74. Delay1us();
  75. }
  76. return tmpe;
  77. }

 iic.h

  1. #ifndef _IIC_H
  2. #define _IIC_H
  3. #include <stc15.h>
  4. #include "delay.h"
  5. //总线引脚定义
  6. sbit SDA = P5^3; /* 数据线 */
  7. sbit SCL = P5^2; /* 时钟线 */
  8. void IIC_Start (void);//起始信号
  9. void IIC_Stop(void);//终止信号
  10. bit IIC_WaitAck(void);//等待应答
  11. void IIC_SendAck(bit j);//应答位控制
  12. void IIC_SendByte(unsigned char dite);//I2C发送1个字节数据
  13. unsigned char IIC_RecByte(void);//I2C接收1个字节数据
  14. #endif

stempmotor.c

  1. #include "stepmotor.h"
  2. //步进电机初始化
  3. void StepMotor_Init()
  4. {
  5. P1M1 &= 0xF0; P1M0 |= 0x0F; //设置P1.0~P1.3为推挽输出
  6. // P1M1 &= 0xF0; P1M0 &= 0xF0; //设置P1.0~P1.3为准双向
  7. }
  8. //电机停止
  9. void MotorStop(void)
  10. {
  11. DD=0;CC=0;BB=0;AA=0;
  12. }
  13. //步进电机转动:单四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  14. void Motor_Drive41(uchar X,uint Speed)
  15. {
  16. if(X==1) //顺时针转动
  17. {
  18. DD=0;CC=0;BB=0;AA=1;
  19. Delay1ms(Speed); //转速调节
  20. DD=0;CC=0;BB=1;AA=0;
  21. Delay1ms(Speed); //转速调节
  22. DD=0;CC=1;BB=0;AA=0;
  23. Delay1ms(Speed); //转速调节
  24. DD=1;CC=0;BB=0;AA=0;
  25. Delay1ms(Speed); //转速调节
  26. }
  27. else //逆时针转动
  28. {
  29. DD=1;CC=0;BB=0;AA=0;
  30. Delay1ms(Speed); //转速调节
  31. DD=0;CC=1;BB=0;AA=0;
  32. Delay1ms(Speed); //转速调节
  33. DD=0;CC=0;BB=1;AA=0;
  34. Delay1ms(Speed); //转速调节
  35. DD=0;CC=0;BB=0;AA=1;
  36. Delay1ms(Speed); //转速调节
  37. }
  38. }
  39. //步进电机转动:双四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  40. void Motor_Drive42(uchar X,uint Speed)
  41. {
  42. if(X==1) //顺时针转动
  43. {
  44. DD=0;CC=0;BB=1;AA=1;
  45. Delay1ms(Speed); //转速调节
  46. DD=0;CC=1;BB=1;AA=0;
  47. Delay1ms(Speed); //转速调节
  48. DD=1;CC=1;BB=0;AA=0;
  49. Delay1ms(Speed); //转速调节
  50. DD=1;CC=0;BB=0;AA=1;
  51. Delay1ms(Speed); //转速调节
  52. }
  53. else //逆时针转动
  54. {
  55. DD=1;CC=0;BB=0;AA=1;
  56. Delay1ms(Speed); //转速调节
  57. DD=1;CC=1;BB=0;AA=0;
  58. Delay1ms(Speed); //转速调节
  59. DD=0;CC=1;BB=1;AA=0;
  60. Delay1ms(Speed); //转速调节
  61. DD=0;CC=0;BB=1;AA=1;
  62. Delay1ms(Speed); //转速调节
  63. }
  64. }
  65. //步进电机转动:八拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  66. void Motor_Drive8(uchar X,uint Speed)
  67. {
  68. if(X==1) //顺时针转动
  69. {
  70. DD=0;CC=0;BB=0;AA=1;
  71. Delay1ms(Speed); //转速调节
  72. DD=0;CC=0;BB=1;AA=1;
  73. Delay1ms(Speed); //转速调节
  74. DD=0;CC=0;BB=1;AA=0;
  75. Delay1ms(Speed); //转速调节
  76. DD=0;CC=1;BB=1;AA=0;
  77. Delay1ms(Speed); //转速调节
  78. DD=0;CC=1;BB=0;AA=0;
  79. Delay1ms(Speed); //转速调节
  80. DD=1;CC=1;BB=0;AA=0;
  81. Delay1ms(Speed); //转速调节
  82. DD=1;CC=0;BB=0;AA=0;
  83. Delay1ms(Speed); //转速调节
  84. DD=1;CC=0;BB=0;AA=1;
  85. Delay1ms(Speed); //转速调节
  86. }
  87. else //逆时针转动
  88. {
  89. DD=1;CC=0;BB=0;AA=1;
  90. Delay1ms(Speed); //转速调节
  91. DD=1;CC=0;BB=0;AA=0;
  92. Delay1ms(Speed); //转速调节
  93. DD=1;CC=1;BB=0;AA=0;
  94. Delay1ms(Speed); //转速调节
  95. DD=0;CC=1;BB=0;AA=0;
  96. Delay1ms(Speed); //转速调节
  97. DD=0;CC=1;BB=1;AA=0;
  98. Delay1ms(Speed); //转速调节
  99. DD=0;CC=0;BB=1;AA=0;
  100. Delay1ms(Speed); //转速调节
  101. DD=0;CC=0;BB=1;AA=1;
  102. Delay1ms(Speed); //转速调节
  103. DD=0;CC=0;BB=0;AA=1;
  104. Delay1ms(Speed); //转速调节
  105. }
  106. }

stempmotor.h

  1. #ifndef _STEPMOTOR_H
  2. #define _STEPMOTOR_H
  3. #include <stc15.h>
  4. #include "delay.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. sbit AA=P1^0; //电机控制口,连接电机驱动板IN1
  8. sbit BB=P1^1; //电机控制口,连接电机驱动板IN2
  9. sbit CC=P1^2; //电机控制口,连接电机驱动板IN3
  10. sbit DD=P1^3; //电机控制口,连接电机驱动板IN4
  11. void StepMotor_Init();//步进电机初始化
  12. void MotorStop(void);//电机停止
  13. void Motor_Drive41(uchar X,uint Speed);//步进电机转动:单四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  14. void Motor_Drive42(uchar X,uint Speed);//步进电机转动:双四拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  15. void Motor_Drive8(uchar X,uint Speed);//步进电机转动:八拍 其中X=1表示正转,X=0表示反转;Speed表示转速设置
  16. #endif

 PCF8563.c

  1. #include "PCF8563.h"
  2. unsigned char time_buf1[8]={20,23,5,31,21,11,0,3};//空年月日时分秒星期(10进制)
  3. unsigned char time_buf[8]; //空年月日时分秒星期 (16进制)
  4. //使用封装好的I2C函数,进行函数PCF8563的写函数封装:向地址Adddrsend中写入数据Datasend
  5. //函数编写流程为 :start->发送设备地址->等待ACK->发送需要被写的内存地址->等待ACK->发送数据写入E2PROM->等待ACK->STOP
  6. void PCF8563_WriteOneByte(unsigned char Adddrsend, unsigned char Datasend)
  7. {
  8. IIC_Start();
  9. IIC_SendByte(0xA2);//通过I2C总线发送数据(芯片指令)写操作
  10. IIC_WaitAck();
  11. IIC_SendByte(Adddrsend);
  12. IIC_WaitAck();
  13. IIC_SendByte(Datasend);
  14. IIC_WaitAck();
  15. IIC_Stop();
  16. Delay1ms(10);
  17. }
  18. //使用封装好的I2C函数,进行函数PCF8563的读数据函数封装:从Adddrsend中读出数据,作为返回值
  19. //读函数编写流程:start->发送设备地址->等待ACK->发送需要被读的内存地址->等待ACK->发送读指令(设备地址)->等待ACK-->读内存数据->等待no ACK->STOP
  20. unsigned char PCF8563_ReadOneByte(unsigned char Adddrsend)
  21. {
  22. unsigned char Rec;
  23. IIC_Start();
  24. IIC_SendByte(0xA2);//通过I2C总线发送数据(芯片指令)写操作
  25. IIC_WaitAck();
  26. IIC_SendByte(Adddrsend);
  27. IIC_WaitAck();
  28. IIC_Start();
  29. IIC_SendByte(0xA3);
  30. IIC_WaitAck();
  31. Rec=IIC_RecByte();
  32. IIC_Stop();
  33. return Rec;
  34. }
  35. /******************BCD转十进制***************************/
  36. unsigned char bcd_dec(unsigned char bat)
  37. {
  38. unsigned char temp1,temp2,tol;
  39. temp1=bat&0x0f;
  40. temp2=(bat&0xf0)>>4;
  41. tol=temp2*10+temp1;
  42. return tol;
  43. }
  44. /******************十进制转BCD***************************/
  45. unsigned char dec_bcd(unsigned char bat)
  46. {
  47. return ((bat%10) & 0x0F) | (((bat/10) << 4) & 0xF0);;
  48. }
  49. //获取当前时间并转化
  50. void get_time(void)
  51. {
  52. time_buf[6]=0x7f&PCF8563_ReadOneByte(0x02); //读取秒
  53. time_buf[5]=0x7f&PCF8563_ReadOneByte(0x03); //读取分钟
  54. time_buf[4]=0x3f&PCF8563_ReadOneByte(0x04); //读取小时
  55. time_buf[3]=0x3f&PCF8563_ReadOneByte(0x05); //读取天数
  56. time_buf[2]=0x1f&PCF8563_ReadOneByte(0x07); //读取月
  57. time_buf[1]=0xff&PCF8563_ReadOneByte(0x08); //读取年
  58. time_buf[7]=0x07&PCF8563_ReadOneByte(0x06); //读取星期
  59. time_buf1[6]=bcd_dec(time_buf[6]); //将读取的BCD码转换成十进制以便运算,秒
  60. time_buf1[5]=bcd_dec(time_buf[5]); //将读取的BCD码转换成十进制以便运算,分
  61. time_buf1[4]=bcd_dec(time_buf[4]); //将读取的BCD码转换成十进制以便运算,小时
  62. time_buf1[3]=bcd_dec(time_buf[3]); //将读取的BCD码转换成十进制以便运算,日
  63. time_buf1[2]=bcd_dec(time_buf[2]); //将读取的BCD码转换成十进制以便运算,月
  64. time_buf1[1]=bcd_dec(time_buf[1]); //将读取的BCD码转换成十进制以便运算,年
  65. time_buf1[7]=bcd_dec(time_buf[7]); //将读取的BCD码转换成十进制以便运算,星期
  66. //printf("20%d年%d月%d日%d时%d分%d秒\r\n",date.year1,date.moom1,date.dat1,date.hour1,date.min1,date.sec1);
  67. }
  68. //初始化当前时间
  69. void time_init()
  70. {
  71. //将十进制数转化为BCD值,方便写入PCF8563
  72. time_buf[1] = dec_bcd(time_buf1[1]);
  73. time_buf[2] = dec_bcd(time_buf1[2]);
  74. time_buf[3] = dec_bcd(time_buf1[3]);
  75. time_buf[4] = dec_bcd(time_buf1[4]);
  76. time_buf[5] = dec_bcd(time_buf1[5]);
  77. time_buf[6] = dec_bcd(time_buf1[6]);
  78. time_buf[7] = dec_bcd(time_buf1[7]);
  79. PCF8563_WriteOneByte(0x02,time_buf[6]); //写入秒
  80. PCF8563_WriteOneByte(0x03,time_buf[5]); //写入分
  81. PCF8563_WriteOneByte(0x04,time_buf[4]); //写入小时
  82. PCF8563_WriteOneByte(0x05,time_buf[3]); //写入日
  83. PCF8563_WriteOneByte(0x07,time_buf[2]); //写入月
  84. PCF8563_WriteOneByte(0x08,time_buf[1]); //写入年
  85. PCF8563_WriteOneByte(0x06,time_buf[7]); //写入星期
  86. }

PCF8563.h

  1. #ifndef _PCF8563_H
  2. #define _PCF8563_H
  3. #include "iic.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. //typedef struct {
  7. // uint16_t year;
  8. // uint8_t mon;
  9. // uint8_t day;
  10. // uint8_t hour;
  11. // uint8_t min;
  12. // uint8_t sec;
  13. // uint8_t week;
  14. //}sTime;
  15. void PCF8563_WriteOneByte(unsigned char Adddrsend, unsigned char Datasend);
  16. unsigned char PCF8563_ReadOneByte(unsigned char Adddrsend);
  17. unsigned char bcd_dec(unsigned char bat);
  18. unsigned char dec_bcd(unsigned char bat);
  19. void time_init();//初始化当前时间
  20. void get_time(void);//读取当前时间
  21. #endif

Key16.c

  1. #include "Key16.h"
  2. uchar KeyScan_4x4(void)
  3. {
  4. uchar X_temp,Y_temp,temp;
  5. X_temp=0XF0;//列值赋初值
  6. Y_temp=0X0F;//行值赋初值
  7. P2M1&=0X3F;P2M0|=0XC0;//设置P2.6-P2.7为强推挽输出 0011 1111;1100 0000
  8. P4M1&=0X0F;P4M0|=0XF0;//设置P4.4-P4.7为强推挽输出 0000 1111;1111 0000
  9. P5M1&=0XF3;P5M0|=0X0C;//设置P5.2-P5.3为强推挽输出 1111 0011;0000 1100
  10. ROW1=1;ROW2=1;ROW3=1;ROW4=1;//行置高
  11. COL1=0;COL2=0;COL3=0;COL4=0;//列置低
  12. //所用到行IO口配置为输入,进行检测
  13. Delay1ms(10);
  14. P4M1&=0X0F;P4M0&=0X0F;//设置P4.4-P4.7为准双向口
  15. Delay1ms(10);
  16. if(ROW1==0)//检测行1电平是否为低电平
  17. {
  18. Delay1ms(10);
  19. if(ROW1==0)
  20. Y_temp&=0X0E;
  21. }
  22. if(ROW2==0)//检测行2电平是否为低电平
  23. {
  24. Delay1ms(10);
  25. if(ROW2==0)
  26. Y_temp&=0X0D;
  27. }
  28. if(ROW3==0)//检测行3电平是否为低电平
  29. {
  30. Delay1ms(10);
  31. if(ROW3==0)
  32. Y_temp&=0X0B;
  33. }
  34. if(ROW4==0)//检测行4电平是否为低电平
  35. {
  36. Delay1ms(10);
  37. if(ROW4==0)
  38. Y_temp&=0X07;
  39. }
  40. P2M1&=0X3F;P2M0|=0XC0;//设置P2.6-P2.7为强推挽输出 0011 1111;1100 0000
  41. P4M1&=0X0F;P4M0|=0XF0;//设置P4.4-P4.7为强推挽输出 0000 1111;1111 0000
  42. P5M1&=0XF3;P5M0|=0X0C;//设置P5.2-P5.3为强推挽输出 1111 0011;0000 1100
  43. ROW1=0;ROW2=0;ROW3=0;ROW4=0;//行置低
  44. COL1=1;COL2=1;COL3=1;COL4=1;//列置高
  45. Delay1ms(10);
  46. P2M1&=0X3F;P2M0&=0X3F;//设置P2.6-P2.7为准双向口
  47. P5M1&=0XF3;P5M0&=0XF3;//设置P5.2-P5.3为准双向口
  48. Delay1ms(10);
  49. if(COL1==0)//检测列1电平是否为低电平
  50. {
  51. Delay1ms(10);
  52. if(COL1==0)
  53. X_temp&=0XE0;
  54. }
  55. if(COL2==0)//检测列2电平是否为低电平
  56. {
  57. Delay1ms(10);
  58. if(COL2==0)
  59. X_temp&=0XD0;
  60. }
  61. if(COL3==0)//检测列3电平是否为低电平
  62. {
  63. Delay1ms(10);
  64. if(COL3==0)
  65. X_temp&=0XB0;
  66. }
  67. if(COL4==0)//检测列4电平是否为低电平
  68. {
  69. Delay1ms(10);
  70. if(COL4==0)
  71. X_temp&=0X70;
  72. }
  73. //将行值和列值合并,得到按键对应的编码值,该值与16个按键一一对应
  74. temp=X_temp|Y_temp;
  75. temp=~temp;
  76. //将按键检测的原始编码值解析对应按键值信息
  77. switch(temp)//颠倒键值
  78. {
  79. case 0X11:return '/';//1
  80. case 0X21:return 'x';//2
  81. case 0X41:return '-';//3
  82. case 0X81:return '+';//4
  83. case 0X12:return '=';//5
  84. case 0X22:return '9';//6
  85. case 0X42:return '8';//7
  86. case 0X82:return '7';//8
  87. case 0X14:return 'C';//9
  88. case 0X24:return '6';//0
  89. case 0X44:return '5';//a
  90. case 0X84:return '4';//b
  91. case 0X18:return '<';//c
  92. case 0X28:return '3';//d
  93. case 0X48:return '2';//e
  94. case 0X88:return '1';//f
  95. default:return 0;
  96. }
  97. }

Key16.h

  1. #ifndef _KEY_4X4_H
  2. #define _KEY_4X4_H
  3. #include <stc15.h>
  4. #include "delay.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. /*
  8. 矩阵按键引脚定义*/
  9. sbit COL4=P5^2; //4*4矩阵检测列检测端口
  10. sbit COL3=P5^3; //4*4矩阵检测列检测端口
  11. sbit COL2=P2^6; //4*4矩阵检测列检测端口
  12. sbit COL1=P2^7; //4*4矩阵检测列检测端口
  13. sbit ROW4=P4^4; //4*4矩阵检测行检测端口
  14. sbit ROW3=P4^5; //4*4矩阵检测行检测端口
  15. sbit ROW2=P4^6; //4*4矩阵检测行检测端口
  16. sbit ROW1=P4^7; //4*4矩阵检测行检测端口
  17. uchar KeyScan_4x4(void);
  18. #endif

zimo.h

  1. #ifndef _ZIMO_H
  2. #define _ZIMO_H
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar code close_Clock[]={0x0E,0x0A,0x0A,0x0A,0x1F,0x11,0x11,0x1F};//??
  6. uchar code guan[] = {0x11,0x0A,0x1F,0x0A,0x1F,0x0A,0x1B,0x00};
  7. uchar code kai[] = {0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x0A,0x00};
  8. uchar code open_Clock[]={0x0E,0x02,0x02,0x02,0x1F,0x11,0x11,0x1F};//???
  9. uchar code myZi[] = {0x00,0x00,0x0A,0x15,0x11,0x0A,0x04,0x00};
  10. uchar code myZi2[] = {0x00,0x0A,0x15,0x15,0x11,0x0A,0x04,0x00};
  11. uchar code xin1_2[] = {0x00,0x0A,0x1F,0x1F,0x1F,0x0E,0x04,0x00};
  12. uchar code xin1_1[] = {0x00,0x00,0x0A,0x1F,0x1F,0x0E,0x04,0x00};
  13. #endif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/658853
推荐阅读
相关标签
  

闽ICP备14008679号