?? hello.c
字號:
//*******************************************************************
//***此程序為調試通過的源程序
//***由南京賽博電子有限公司提供
//***文件名:sy0606.C***//
//***是51系例單片機的最小系統
//***有AT89S51/52的在線下載功能
//***IIC總線芯片為24C02,記存密碼
//*******************************************************************
#include"at89x52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define nop _nop_() /* 定義空操作指令 */
//#define VAR P1
sbit rs=P2^2; /*LCD模塊用*/
sbit rw=P2^1; /*LCD模塊用*/
sbit enable=P2^0; /*LCD模塊用*/
sbit SCL=P3^4; /*24C01 CSL接腳=89C51 T0 P3.4*/
sbit SDA=P3^5; /*24C01 SDA接腳=89C51 T1 P3.5*/
sbit en =P2^7; /*DTLED-6顯示芯片使能端*/
sbit dout=P2^6; /*DTLED-6顯示芯片數據讀入端*/
sbit clk=P2^5; /*DTLED-6顯示芯片/時鐘芯片DS1302時鐘輸入端*/
sbit DINOUT=P2^4; /*DS1302時鐘芯片數據輸入輸出端*/
sbit RST=P2^3; /*DS1302芯片復位起始端*/
bit FLAG0=0; /*位標號FLAG0=1鍵盤掃描回應*/
bit FLAG1=1; /*位標號20H.1比較密碼回應旗號*/
bit FLAG2=1; /*位標號FLAG2=0時,進入鍵盤操作*/
bit FLAG3=1; /*位標號FLAG3=0時,鍵盤操作*/
bit FLAG4=0; /*位標號FLAG4=0時,鍵盤操作*/
bit FLAG5=0; /*位標號FLAG5=1時,存儲*鍵按下*/
bit TSendAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no); /* 向有子地址器件寫入6字節數據函數 */
bit TRcvAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no); /* 向有子地址器件讀取6字節數據函數 */
bit acknow; /* 應答標志位 acknow=1 表示正常響應 acknow=0 表示未響應 */
static const char tab[16]={0x01,0x02,0x03,0x0c, /*鍵盤碼00,01,02,03,*/
0x04,0x05,0x06,0x0d, /*鍵盤碼04,05,06,07,*/
0x07,0x08,0x09,0x0e, /*鍵盤碼08,09,0a,0b,*/
0x0a,0x00,0x0b,0x0f};/*鍵盤碼0c,0d,0e,0f*/
//static const char tab1[6]={0x01,0x01,0x01,0x01,0x01,0x01};/*內定密碼"888888"*/
uchar char1[]="Syber Nanjing.Co";
uchar char2[]="Password:";
uchar dispbuf[9]; /*顯示值存放陣列*/
uchar clocktmp[3]; /*顯示值存放陣列*/
uchar bufdata[9];
uchar buf_rec_com1;
uchar bufuart[6]; /*串口接收值存放陣列*/
//uchar buf_rec_com1; //huzm
//uchar rec_comm1_len=0; //huzm
uchar a1=0,clockbak,b1=100,stand=0,m=0,busy,count=10;
char ww=0,ptr=0,ptr1=0; /*PTR鍵盤掃描指標,ptr1顯示器掃描指標*/
void delay (unsigned int value) /*延時副程式*/
{
while (value!=0) value--; /*10US延時*/
}
void Enable(uchar c);
void Write1(char *c1);
void Write2(char c2);
void Write3(void); /* 顯示密碼字符串 */
void send_to_Led_a(void); /*串行發送到DTLED-6副程式*/
void BCD(void); /*BCD碼轉換副程式*/
void clear(void); /*清除按鍵存放/顯示器陣列dispbuf[]副副程式*/
void open(void); /*開門比較密碼副程式*/
void read24c02(); /*讀24c02的存儲值*/
void write24c02(); /*寫24c02的存儲值*/
void IICSAVE(void); /*設定密碼并存入buft[]陣列副程式*/
//void disp(void); /*顯示存放在dispbuf[]陣列的密碼副程式*/
void send_to_Comm1(void); /*串口serial發送副程式*/
void temp(void);
void Rd1302st(void); /*讀時鐘芯片DS1302*/
void Rd1302(void); /*讀時鐘芯片DS1302*/
void Wr1302(void); /*寫時鐘芯片DS1302*/
void Start(); /* 起動總線函數 */
void Stop(); /* 結束總線函數 */
void SendByte(uchar c); /* 8951發數據或地址給8583 字節數據發送函數 */
uchar RcvByte(); /* 8951從24C01讀數據字節數據接收函數 */
void Ack(bit a); /* 主機8951應答子函數 */
void xch(void); /*宣告按鍵存放/顯示器陣列dispbuf[]右鍵滾入副程式*/
void wxb1(void); /*0~9計數,秒*/
void wxb2(void); /*0~9計數,分*/
void wxb3(void); /*0~9計數,時*/
void save_clocks(void); /*按顯示時間更改時鐘*/
/*********************************************************************/
//串行發送DTLED-6顯示
//dispbuf0-dispbuf1-dispbuf2-dispbuf3-dispbuf4-dispbuf5-dispbuf6-dispbuf7-dispbuf8
// 小數點 - 數碼管1- 數碼管2- 數碼管3- 數碼管4- 數碼管5- 數碼管6-ID識別碼-BZ識別碼
//00000xxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx
//小數點=1~6,其它為不顯示
//數碼管1-6=0~15,
//ID識別碼=0~15
//BZ識別碼=BZ.3為蜂鳴輸出控制位,0=關閉,1=打開
// BZ0~2為蜂鳴頻率輸出設定為,000=不分頻, 最高頻率輸出=4800Hz;
// 001=一次分頻,頻率輸出=4800/ 2 =2400Hz;
// 010=二次分頻,頻率輸出=4800/ 4 =1200Hz;
// 011=三次分頻,頻率輸出=4800/ 8 =600Hz;
// 100=四次分頻,頻率輸出=4800/ 16=300Hz;
// 101=五次分頻,頻率輸出=4800/ 32=150Hz;
// 110=六次分頻,頻率輸出=4800/ 64=75Hz;
// 111=七次分頻,頻率輸出=4800/128=38Hz;
//======================================================================
void send_to_Led_a(void) /*串行發送DTLED-6顯示副程式*/
{
char ts0,i,j;
clk=0;
en=0;
delay(10);
for(j=0;j<9;j++)
{
ts0=dispbuf[j];
for(i=0;i<4;i++) /*發小數點碼8,4,2,1*/
{
clk=1;
ts0=ts0<<1;
if(AC==1)
dout=1;
else dout=0;
clk=0;
nop;
delay(3);
}
}
en=1;
} /*返回主程式*/
//======================================================================
void Write1(char *c1)
{while(*c1!=0)
{Write2(*c1);
c1++;
}
}
//======================================================================
void Write3(void)
{uchar i=6;
while(i>0)
{ P1=bufdata[i]|0x30;
rs=1;rw=0;
enable=1;
delay(2);
enable=0;
i--;
}
}
//======================================================================
void Write2(char c2)
{P1=c2;
rs=1;rw=0;enable=1;
delay(2);
enable=0;
}
//======================================================================
void Enable(uchar c)
{
P1=c;
rs=0;rw=0;enable=1;
delay(2);
enable=0;
}
/***********************************************************************/
void temp(void)
{ FLAG2=0;
if(tab[ptr]==0x0e)
{
//disp(); /*如果是按“C”則呼叫顯示密碼DISP*/
dispbuf[0]=0x03; /*小數點位*/
}
else /*否則往下執行*/
{
switch(tab[ptr]) /*是則測試ptr鍵盤掃描計數器指標至TAB[]取到的鍵盤碼*/
{
case 0x0a:
write24c02(); /*是否按“*”是則呼叫設定密碼SET*/
clear(); /*是否按“#”是則呼叫清除顯示器CLEAR*/
break; /*跳出此循環*/
case 0x0b:
clear(); /*是否按“#”是則呼叫清除顯示器CLEAR*/
break; /*跳出此循環*/
case 0x0c: /*是否按“A”,未規劃鍵待用戶自己定義*/
FLAG2=1; P3_6=1;
dispbuf[0]=0x03; /*小數點位*/
break; /*跳出此循環*/
case 0x0d: /*是否按“B”,未規劃鍵待用戶自己定義*/
break; /*跳出此循環*/
case 0x0e: /*是否按“C”,已偵測過*/
read24c02(); /*呼叫讀取密碼存放在DATE1[]副程式*/
break; /*跳出此循環*/
case 0x0f:
open(); /*是否按“D”,是則呼比較密碼開門副程式*/
dispbuf[0]=0x03; /*小數點位*/
goto openend;
break; /*跳出此循環*/
default:
xch(); /*以上均不是則為數字鍵呼叫XCH作右鍵滾入*/
break; /*跳出此循環*/
} /*跳出SWITCH*/
delay(100); /*按鈕抗機械反彈跳*/
while(m==P0); /*按鈕放開否?*/
send_to_Led_a(); /*串行發送到DTLED-6副程式*/
openend: nop;
}
} /*返回上一層程式*/
/****************************************************/
void temp_setclock(void) /*判斷有按鍵輸入否?*/
{
switch(dispbuf[0]) /*是則測試ptr鍵盤掃描計數器指標至TAB[]取到的鍵盤碼*/
{
case 0x01:
wxb1(); /*0~9計數*/
break; /*跳出此循環*/
case 0x03:
wxb1(); /*0~9計數*/
break; /*跳出此循環*/
case 0x05:
wxb2(); /*0~2,0~4計數*/
break; /*跳出此循環*/
default: /*以上均不是*/
break; /*跳出此循環*/
}
delay(100); /*按鈕抗機械反彈跳*/
while(m==P0); /*按鈕放開否?*/
send_to_Led_a(); /*串行發送到DTLED-6副程式*/
} /*返回上一層程式*/
/****************************************************/
void wxb1(void)
{
switch(tab[ptr]) /*是則測試ptr鍵盤掃描計數器指標至TAB[]取到的鍵盤碼*/
{
case 0x02:
dispbuf[dispbuf[0]]++; /*是按“上”,是則呼叫設定密碼SET*/
if(dispbuf[dispbuf[0]]>9)
{dispbuf[dispbuf[0]+1]++;
dispbuf[dispbuf[0]]=0;
}
if(dispbuf[dispbuf[0]+1]==6)
{dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;
}
break; /*跳出此循環*/
case 0x08:
if(dispbuf[dispbuf[0]]==0) /*是按“下”,是則呼叫清除顯示器CLEAR*/
{if(dispbuf[dispbuf[0]+1]==0)
dispbuf[dispbuf[0]+1]=6;
dispbuf[dispbuf[0]]=10;
dispbuf[dispbuf[0]+1]--;
}
dispbuf[dispbuf[0]]--;
break; /*跳出此循環*/
case 0x04: /*是按“左”,未規劃鍵待用戶自己定義*/
dispbuf[0]=dispbuf[0]+2; /*小數點左移一位*/
if(dispbuf[0]>6)
dispbuf[0]=1;
break; /*跳出此循環*/
case 0x06: /*是按“右”,未規劃鍵待用戶自己定義*/
if(dispbuf[0]<3)
dispbuf[0]=7;
dispbuf[0]=dispbuf[0]-2; /*小數點右移一位*/
break; /*跳出此循環*/
case 0x0a: /*是按“*”,已偵測過*/
FLAG5=1;
break; /*跳出此循環*/
case 0x0c: /*是否按“A”,未規劃鍵待用戶自己定義*/
FLAG4=FLAG5=P3_6=1;
dispbuf[0]=0x03; /*小數點位*/
break; /*跳出此循環*/
default: /*以上均不是*/
break; /*跳出此循環*/
}
} /*返回上一層程式*/
/****************************************************/
void wxb2(void)
{switch(tab[ptr]) /*是則測試ptr鍵盤掃描計數器指標至TAB[]取到的鍵盤碼*/
{case 0x02:
dispbuf[dispbuf[0]]++; /*是按“上”,是則呼叫設定密碼SET*/
if(dispbuf[dispbuf[0]+1]==2)
{if(dispbuf[dispbuf[0]]>4)
{dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;}
}
else
{if(dispbuf[dispbuf[0]]>9)
{dispbuf[dispbuf[0]+1]++; dispbuf[dispbuf[0]]=0;}
if(dispbuf[dispbuf[0]+1]>2)
{dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;}
}
break; /*跳出此循環*/
case 0x08:
if(dispbuf[dispbuf[0]]==0) /*是按“下”,是則呼叫清除顯示器CLEAR*/
{if(dispbuf[dispbuf[0]+1]==0)
{dispbuf[dispbuf[0]+1]=2;
dispbuf[dispbuf[0]]=5;
}
else
{dispbuf[dispbuf[0]]=10; dispbuf[dispbuf[0]+1]--;
}
}
dispbuf[dispbuf[0]]--;
break; /*跳出此循環*/
case 0x04: /*是按“左”,未規劃鍵待用戶自己定義*/
dispbuf[0]=dispbuf[0]+2; /*小數點左移一位*/
if(dispbuf[0]>6)
dispbuf[0]=1;
break; /*跳出此循環*/
case 0x06: /*是按“右”,未規劃鍵待用戶自己定義*/
if(dispbuf[0]<3)
dispbuf[0]=7;
dispbuf[0]=dispbuf[0]-2; /*小數點右移一位*/
break; /*跳出此循環*/
case 0x0a: /*是按“*”,已偵測過*/
FLAG5=1;
break; /*跳出此循環*/
case 0x0c: /*是否按“A”,未規劃鍵待用戶自己定義*/
FLAG4=FLAG5=P3_6=1;
dispbuf[0]=0x03; /*小數點位*/
break; /*跳出此循環*/
default: /*以上均不是*/
break; /*跳出此循環*/
}
} /*返回上一層程式*/
/****************************************************/
void save_clocks(void) /*按顯示時間更改時鐘*/
{clocktmp[0]=dispbuf[1]|(dispbuf[2]<<4);
clocktmp[1]=dispbuf[3]|(dispbuf[4]<<4);
clocktmp[2]=dispbuf[5]|(dispbuf[6]<<4);
Wr1302();
FLAG2=1;
nop;
}
/****************************************************/
void xch(void) /*顯示向右移動副程式*/
{char c; /*宣告變數*/
for(c=6;c>0;c--)
{dispbuf[c]=dispbuf[c-1];/*將顯示器dispbuf[]移位交換,dispbuf[3]->dispbuf[4]->dispbuf[5]...*/
}
dispbuf[0]=0; /*有安鍵時,小數點不亮*/
dispbuf[1]=tab[ptr]; /*新的按鍵值存入dispbuf[1],最低位*/
} /*返回上一層程式*/
/****************************************************/
void open(void) /*開門比較密碼副程式*/
{char c; /*宣告變數*/
FLAG1=1; /*設開門標號為1*/
for(c=1;c<6;c++) /*比較六個密碼*/
{if(dispbuf[c]!=bufdata[c]) /*顯示值(按鍵值disbuf[])與密碼TAB[]比較是否相等*/
FLAG1=0;
if(FLAG1==0) /*FLAG1=0 表示不相等*/
break; /*跳出此循環*/
}
if(FLAG1==1) /*如FLAG1=1 表示密碼相等,令電鎖P2.0置0動作*/
{ /*密碼正確*/
dispbuf[8]=0x09; /*蜂鳴器設定開/二次分頻*/
dispbuf[0]=0x01; /*小數點到最高位位*/
P3_6=0; /*P3.6置0,使綠色下載指示燈亮(喇叭響)*/
TMOD=0x11;
TR1=1; /**/
IE=0x8a; /*8是允許中斷,a是TIMER0,TIMER1中斷致能位*/
send_to_Led_a(); /*串行發送到DTLED-6副程式*/
while(FLAG5==0) /*等待設置死循環*/
{
//scan(); /*呼叫鍵盤掃描副程式有按FLAG0會為1*/
if(FLAG0==1)
{
temp_setclock(); /*判斷有按鍵輸入否?*/
}
}
if(FLAG4==0)
save_clocks(); /*按顯示時間更改時鐘*/
}
else P3_6=1; /*密碼錯,P3.6置1,關閉綠色下載指示燈滅(喇叭不響)*/
} /*返回上一層程式*/
/******************************************************/
void clear(void) /*清除顯示器dispbuf[]為00副程式*/
{char c; /*宣告變數*/
for(c=1;c<7;c++) /*將00存入顯示陣列dispbuf[]*/
{dispbuf[c]=0x00;
}
} /*返回上一層程式*/
/******************************************************/
void Wr1302(void) /*寫時鐘芯片DS1302*/
{char i,j,ts0,conb,conbyt;
conb=0x80;
ts0=conb;
//
for(j=0;j<3;j++) /*寫秒,分,時三次循環*/
{clk=RST=0; /*DS1302系統初始化*/
nop;nop;
RST=1;
for(i=0;i<8;i++) /*寫控制字到DS1302*/
{clk=0; /*清時鐘*/
if(conb&0x01)
DINOUT=1;
else DINOUT=0;
clk=1; /*時鐘上升沿,發送數據有效*/
conb=conb>>1;
nop;
}
clk=0; /*清時鐘*/
conb=ts0+2+j*2;
conbyt=clocktmp[j]&0x7f;
for(i=0;i<8;i++) /*寫設定值到DS1302*/
{clk=0; /*清時鐘*/
if(conbyt&0x01)
DINOUT=1;
else DINOUT=0;
clk=1; /*時鐘上升沿,發送數據有效*/
conbyt=conbyt>>1;
nop;
}
delay(5);
RST=0;
nop;
}
}
/*返回主程式*/
/******************************************************/
void Rd1302st() /*啟動時鐘芯片振蕩器*/
{
char i,ts0,conb,conbyt;
Rd1302();
conbyt=clocktmp[0]&0x7f;
conb=0x80;
ts0=conb;
clk=RST=0; /*DS1302系統初始化*/
nop;nop;
RST=1;
for(i=0;i<8;i++) /*寫控制字到DS1302*/
{ clk=0; /*清時鐘*/
if(conb&0x01)
DINOUT=1;
else DINOUT=0;
clk=1; /*時鐘上升沿,發送數據有效*/
conb=conb>>1;
nop;
}
clk=0; /*清時鐘*/
for(i=0;i<8;i++) /*寫控制字到DS1302*/
{ clk=0; /*清時鐘*/
if(conbyt&0x01)
DINOUT=1;
else DINOUT=0;
clk=1; /*時鐘上升沿,發送數據有效*/
conbyt=conbyt>>1;
nop;
}
delay(5);
RST=0;
nop;
} /*返回主程式*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -