分享一個自己上周做的課程設計:密碼鎖不僅有基本的功能,還有實現密碼正確電機正轉三圈,反轉三圈。
以下是電路仿真截圖及工程文件截圖以及視頻演示。有需要的可以自行下載。
0.jpg (23.73 KB, 下載次數: 63)
下載附件
2017-12-16 22:29 上傳
開機時實物照片
0.jpg (66.24 KB, 下載次數: 70)
下載附件
2017-12-16 22:29 上傳
密碼正確時實物照片
0.jpg (66.52 KB, 下載次數: 59)
下載附件
2017-12-16 22:29 上傳
仿真電路原理圖如下(proteus仿真工程文件可到本帖附件中下載)
proteus仿真截圖.png (23.83 KB, 下載次數: 44)
下載附件
2017-12-16 22:07 上傳
工程文件截圖.png (54.41 KB, 下載次數: 60)
下載附件
2017-12-16 22:07 上傳
單片機源程序(hex文件):
- #include<reg51.h>
- #include"lcd.h"
- #define GPIO_KEY P1
- #define uint unsigned int
- #define INT8U unsigned char
- unsigned char KeyValue,flag,key;
- //用來存放讀取到的鍵值
- unsigned char KeyState;
- //用來存放按鍵狀態
- unsigned char PuZh[]="H082";
- unsigned char time[]=" TIME5 ";
- unsigned char key_right[]="right";
- unsigned char key_error[]="error";
- unsigned char right_dat[]="9999";
- unsigned char dat[]="0123456789HBCDEF";
- unsigned char key_dat[4]={0};
- void Delay10ms(char time); //延時10ms
- void KeyDown(); //檢測按鍵函數
- void test(); //密碼檢測函數
- void STEP_MOTOR_FFW(INT8U n);
- void STEP_MOTOR_REV(INT8U n);
-
- void clock_write(uchar ad,uint s);
- sbit LED0= P2^3;
- sbit BEEP= P2^2;
- unsigned char FFW[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
- unsigned char REV[]={0X09,0X08,0X0C,0X04,0X06,0X02,0X03,0X01};
- INT8U second;
- INT8U second=5;
- INT8U int_time;
- /*******************************************************************************
- * 函 數 名 : main
- * 函數功能 : 主函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void main(void)
- {
- unsigned char i,j;
- LcdInit();
- KeyState=0;
- TMOD=0X01;
- EA=1;
- ET0=1;
- TH0=(65536-46083)/256;
- TL0=(65536-46083)%256;
- TR0=0;
- int_time=0;
- for(i=0;i<16;i++)
- {
- LcdWriteData(PuZh[i]);}
- Delay10ms(3000); //等待3秒
- LcdWriteCom(0x01);
- while(1)
- {
- KeyDown();
- if(KeyValue==11) // 密碼不顯示
- {
- LcdWriteCom(0x01);
- LcdWriteCom(0x80+0x40);
- key=0;
- }
- if(KeyState)
- {
- KeyState=0;
- LcdWriteCom(0x80+0x40+key);
- if(KeyValue<11)
- {
- LcdWriteData(dat[KeyValue]);
- key_dat[key]=dat[KeyValue];
- key++;
- if(key==4)
- {
- test();key=0;
- }
- }
- }
- }
- }
- /*******************************************************************************
- * 函 數 名 : KeyDown
- * 函數功能 : 檢測有按鍵按下并讀取鍵值
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void KeyDown(void)
- {
- char a,j;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)
- {
- Delay10ms(1);
- if(GPIO_KEY!=0x0f)
- {
- KeyState=1;
- //測試列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //測試行
- GPIO_KEY=0XF0;
- Delay10ms(1);
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- if(KeyValue==12) //密碼顯示
- {
- LcdWriteCom(0x80);
- for(j=0;j<10;j++) LcdWriteData(PuZh[j]);
- for(j=0;j<4;j++)
- {
- LcdWriteCom(0x80+0x40+j);
- LcdWriteData(key_dat[j]);
- }
- }
- if(KeyValue==13) // 重新輸入密碼
- {
- LcdWriteCom(0x01);
- LcdWriteCom(0x80); key=0;flag=0;
- for(j=0;j<10;j++) LcdWriteData(PuZh[j]);
- for(j=0;j<4;j++) key_dat[j]=0;
- }
- while((a<50)&&(GPIO_KEY!=0xf0)) //檢測按鍵松手檢測
- {
- Delay10ms(1);
- a++;
- }
- a=0;
- }
- }
- }
- /*******************************************************************************
- * 函 數 名 : Delay10ms
- * 函數功能 : 延時函數,延時10ms
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Delay10ms(char time) //誤差 0us
- {
- unsigned char a,b,c;
- for(c=time;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- /*******************************************************************************
- * 函 數 名 : test
- * 函數功能 : 密碼檢測函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void test()
- { uint x;
- INT8U N=3;
- char i,j;
- for(i=0;i<4;i++)//密碼檢測
- {
- if(right_dat[i]==key_dat[i]) flag++;
- }
- if(flag==4) //密碼正確
- {
-
- for(j=0;j<5;j++) LcdWriteData(key_right[j]);
- for(x=0;x<100;x++) //光聲控制
- {Delay10ms(1);BEEP=~BEEP;}
- BEEP=1;
- LED0=0;
- STEP_MOTOR_FFW(N); //電機
- TR0=1;
- for(j=0;j<16;j++) //倒計時
- {
- LcdWriteData(time[j]);}
- clock_write(0x80,second);
- }
- else //密碼錯誤
- {
- flag=0;
- LcdWriteCom(0x80+0x46);
- Delay10ms(50);
- for(j=0;j<5;j++) LcdWriteData(key_error[j]);
- }
- }
- void STEP_MOTOR_FFW(INT8U n) //電機
- { INT8U i,j;
- for(i=0;i<5*n;i++)
- { for(j=0;j<8;j++)
- {P3=FFW[j];
- Delay10ms(25);}} }
- void STEP_MOTOR_REV(INT8U n)
- { INT8U i,j;
- for(i=0;i<5*n;i++)
- { for(j=0;j<8;j++)
- {P3=REV[j];
- Delay10ms(25);}} }
- void clock_write(uchar ad,uint second) //倒計時
- { LcdWriteCom(ad);
- LcdWriteData(second);
- Delay10ms(100);}
- void T0_interserve(void) interrupt 1
- { INT8U N=3;
- TH0=(65536-46083)/256;
- TL0=(65536-46083)%256;
- int_time++;
- if(int_time==20)
- { int_time=0;
- second--;}
- if(second==0)
- {STEP_MOTOR_REV(N);}
-
- }
- #include"lcd.h"
- /*******************************************************************************
- * 函 數 名 : Lcd1602_Delay1ms
- * 函數功能 : 延時函數,延時1ms
- * 輸 入 : c
- * 輸 出 : 無
- * 說 名 : 該函數是在12MHZ晶振下,12分頻單片機的延時。
- *******************************************************************************/
- void Lcd1602_Delay1ms(uint c) //誤差 0us
- {
- uchar a,b;
- for (; c>0; c--)
- {
- for (b=199;b>0;b--)
- {
- for(a=1;a>0;a--);
- }
- }
-
- }
- /*******************************************************************************
- * 函 數 名 : LcdWriteCom
- * 函數功能 : 向LCD寫入一個字節的命令
- * 輸 入 : com
- * 輸 出 : 無
- *******************************************************************************/
- #ifndef LCD1602_4PINS //當沒有定義這個LCD1602_4PINS時
- void LcdWriteCom(uchar com) //寫入命令
- {
- LCD1602_E = 0; //使能
- LCD1602_RS = 0; //選擇發送命令
- LCD1602_RW = 0; //選擇寫入
-
- LCD1602_DATAPINS = com; //放入命令
- Lcd1602_Delay1ms(1); //等待數據穩定
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5); //保持時間
- LCD1602_E = 0;
- }
- #else
- void LcdWriteCom(uchar com) //寫入命令
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 0; //選擇寫入命令
- LCD1602_RW = 0; //選擇寫入
- LCD1602_DATAPINS = com; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- // Lcd1602_Delay1ms(1);
- LCD1602_DATAPINS = com << 4; //發送低四位
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- }
- #endif
- /*******************************************************************************
- * 函 數 名 : LcdWriteData
- * 函數功能 : 向LCD寫入一個字節的數據
- * 輸 入 : dat
- * 輸 出 : 無
- *******************************************************************************/
- #ifndef LCD1602_4PINS
- void LcdWriteData(uchar dat) //寫入數據
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //選擇輸入數據
- LCD1602_RW = 0; //選擇寫入
- LCD1602_DATAPINS = dat; //寫入數據
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5); //保持時間
- LCD1602_E = 0;
- }
- #else
- void LcdWriteData(uchar dat) //寫入數據
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //選擇寫入數據
- LCD1602_RW = 0; //選擇寫入
- LCD1602_DATAPINS = dat; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- LCD1602_DATAPINS = dat << 4; //寫入低四位
- Lcd1602_Delay1ms(1);
- LCD1602_E = 1; //寫入時序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- }
- #endif
- /*******************************************************************************
- * 函 數 名 : LcdInit()
- * 函數功能 : 初始化LCD屏
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- #ifndef LCD1602_4PINS
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x38); //開顯示
- LcdWriteCom(0x0c); //開顯示不顯示光標
- LcdWriteCom(0x06); //寫一個指針加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //設置數據指針起點
- }
- #else
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x32); //將8位總線轉為4位總線
- LcdWriteCom(0x28); //在四位線下的初始化
- LcdWriteCom(0x0c); //開顯示不顯示光標
- LcdWriteCom(0x06); //寫一個指針加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //設置數據指針起點
- …………
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
全部資料51hei下載地址:
多功能密碼鎖.rar
(14.8 MB, 下載次數: 210)
2017-12-16 22:09 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|