|
設(shè)計(jì)要求:
1、實(shí)現(xiàn)0―9999范圍計(jì)數(shù)。
2、要求使用紅外發(fā)光二極管、光電管檢測(cè);
3、12864顯示:進(jìn)門人數(shù),出門人數(shù),房間里人數(shù);
4、要求光電發(fā)射管與接收管有1米以上的間距
程序已通過清翔電子開發(fā)板完美測(cè)試 (可采用光敏、紅外、熱釋電紅外計(jì)數(shù))
液晶端口
DATA:P0.0~P0.7
RS:P3.5
RW:P3.6
EN:P3.4
PSB:P3.7
1302端口
DAT:P1.1
CLK:P1.0
RST:P1.2
獨(dú)立按鍵端口:P3.0~P3.3
計(jì)數(shù).jpg (6.44 MB, 下載次數(shù): 87)
下載附件
2019-7-27 09:51 上傳
單片機(jī)源程序如下:
- /******************************************************************
- /
- / 名稱:人員計(jì)數(shù)器+時(shí)鐘(12864顯示)
- /
- ******************************************************************/
- #include <reg52.h> //調(diào)用單片機(jī)頭文件
- #include <intrins.h>
- #include "12864.c"
- #define uchar unsigned char //無符號(hào)字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號(hào)整型 宏定義 變量范圍0~65535
- sbit hw_jin=P1^0; //紅外傳感器IO口定義
- sbit hw_chu=P1^1; //紅外傳感器IO口定義
- sbit sda=P1^3; //數(shù)據(jù)線
- sbit clk=P1^4; //時(shí)鐘線
- sbit rst=P1^2; //使能
- sbit mode=P3^0; //設(shè)置鍵
- sbit s1 =P3^1; //加鍵
- sbit s2 =P3^2; //減鍵
- sbit yes =P3^3; //調(diào)整確認(rèn)鍵
- sbit speak=P2^3;
- sbit ACC0=ACC^0; //累加器A低位
- sbit ACC7=ACC^7; //累加器A高位
- uchar dis,temp,a,h,m,n; //設(shè)置參數(shù)用
- uchar set_num=80; //設(shè)置倒計(jì)時(shí)數(shù)的啟始值
- uint num; //總數(shù)
- uint jin,chu; //進(jìn) 出
- uchar sec,min,hour,day,mouth,year,week;
- bit flag;
- /***************寫數(shù)據(jù)********************/
- void write_byte(uchar dat)
- {
- ACC=dat;
- rst=1;
- for(a=8;a>0;a--)
- {
- sda=ACC0;
- clk=0;
- clk=1;
- ACC=ACC>>1;
- }
- }
- /******************讀數(shù)據(jù)********************/
- uchar read_byte()
- {
- rst=1;
- for(a=8;a>0;a--)
- {
- ACC7=sda;
- clk=1;
- clk=0;
- ACC=ACC>>1;
- }
- return (ACC);
- }
- /*********向1302芯片寫函數(shù),指定寫入地址,數(shù)據(jù)*********/
- void write_1302(uchar add,uchar dat)
- {
- rst=0;
- clk=0;
- rst=1;
- write_byte(add);
- write_byte(dat);
- clk=1;
- rst=0;
- }
- /*********從1302讀數(shù)據(jù)函數(shù),指定讀取數(shù)據(jù)來源地址*******/
- uchar read_1302(uchar add)
- {
- uchar temp;
- rst=0;
- clk=0;
- rst=1;
- write_byte(add);
- temp=read_byte();
- clk=1;
- rst=0;
- return(temp);
- }
- /****************BCD碼轉(zhuǎn)十進(jìn)制函數(shù),輸入BCD,返回十進(jìn)制*******/
- uchar BCD(uchar m)
- {
- uchar x;
- x=m>>4;
- return(x=x*10+(m&=0x0f));
- }
- /********1302芯片初始化子函數(shù)********/
- void ds1302_init()
- {
- rst=0;
- clk=0;
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- delay(30);
- write_1302(0x8e,0x80); //打開寫保護(hù)
- }
- /***********************1ms延時(shí)函數(shù)*****************************/
- void delayms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
- /*************定時(shí)器0初始化程序***************/
- void time_init()
- {
- EA =1; //開總中斷
- TMOD=0X01; //定時(shí)器0、工作方式1
- ET0 =1; //開定時(shí)器0中斷
- TR0 =1; //允許定時(shí)器0定時(shí)
- }
- /******************紅外計(jì)數(shù)**********************/
- void hw_jin_dis() //紅外計(jì)數(shù)
- {
- if(hw_jin==0) //計(jì)數(shù)
- {
- delayms(1); //消抖動(dòng)
- if(hw_jin==1) //仿真時(shí)修改hw_jin==0 可以直觀看到計(jì)數(shù)
- { //確認(rèn)
- jin++;
- if(jin>=9999) jin=9999; //最大計(jì)9999
- num=jin-chu; //計(jì)算總?cè)藬?shù)
- if(dis==0)
- {
- lcd_pos(0,2);
- lcd_wdat(table[jin%10000/1000]);
- lcd_wdat(table[jin%1000/100]);
- lcd_wdat(table[jin%100/10]);
- lcd_wdat(table[jin%10]);
- lcd_pos(2,2);
- lcd_wdat(table[num%10000/1000]);
- lcd_wdat(table[num%1000/100]);
- lcd_wdat(table[num%100/10]);
- lcd_wdat(table[num%10]);
- }
- }
- }
- }
- /******************紅外計(jì)數(shù)**********************/
- void hw_chu_dis() //紅外計(jì)數(shù)
- {
- if(hw_chu==0) //計(jì)數(shù)
- {
- delayms(1); //消抖動(dòng)
- if(hw_chu==1) //仿真時(shí)修改hw_chu==0 可以直觀看到計(jì)數(shù)
- { //確認(rèn)
- if(jin>chu) chu++;
- if(chu>=9999) chu=9999;
- num=jin-chu; //計(jì)算總?cè)藬?shù)
- if(dis==0)
- {
- lcd_pos(1,2);
- lcd_wdat(table[chu%10000/1000]);
- lcd_wdat(table[chu%1000/100]);
- lcd_wdat(table[chu%100/10]);
- lcd_wdat(table[chu%10]);
- lcd_pos(2,2);
- lcd_wdat(table[num%10000/1000]);
- lcd_wdat(table[num%1000/100]);
- lcd_wdat(table[num%100/10]);
- lcd_wdat(table[num%10]);
- }
- }
- }
- }
- void time_display()
- {
- lcd_pos(2,6);
- lcd_wdat(table[sec/10]);
- lcd_wdat(table[sec%10]);
- lcd_pos(1,6);
- lcd_wdat(table[min/10]);
- lcd_wdat(table[min%10]);
- lcd_pos(0,6);
- lcd_wdat(table[hour/10]);
- lcd_wdat(table[hour%10]);
- lcd_pos(3,1);
- lcd_wdat(table[year/10]);
- lcd_wdat(table[year%10]);
- lcd_pos(3,3);
- lcd_wdat(table[mouth/10]);
- lcd_wdat(table[mouth%10]);
- lcd_pos(3,5);
- lcd_wdat(table[day/10]);
- lcd_wdat(table[day%10]);
- }
- void key()
- {
- if(mode==0) //第一次判斷"模式"按鍵按下
- {
- delay(5); //延時(shí)消抖
- if(mode==0){TR0=0;n++;}while(!mode);}
- if(n>6) {TR0=1;n=0;}
- if(n!=0)
- {
- if(s1==0) //調(diào)整+鍵
- {
- delay(30);
- if(s1==0)
- {
- TR0=0;
- switch(n)
- {
- case 1:sec++; //設(shè)置鍵按動(dòng)1次,調(diào)秒
- if(sec==60) sec=0; //秒超過59,再加1,就歸零
- lcd_pos(2,6);
- lcd_wdat(table[sec/10]);
- lcd_wdat(table[sec%10]);
- temp=(sec)/10*16+(sec)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x80,temp); //向DS1302內(nèi)寫秒寄存器80H寫入調(diào)整后的秒數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 2:min++; //設(shè)置鍵按動(dòng)2次,調(diào)分
- if(min==60) min=0; //分?jǐn)?shù)據(jù)加到60時(shí)自動(dòng)變成0
- lcd_pos(1,6);
- lcd_wdat(table[min/10]);
- lcd_wdat(table[min%10]);
- temp=(min)/10*16+(min)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x82,temp); //向DS1302內(nèi)寫分寄存器82H寫入調(diào)整后的分?jǐn)?shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 3:hour++;
- if(hour==24) hour=0; //時(shí)數(shù)據(jù)加到24時(shí)自動(dòng)變成0
- lcd_pos(0,6);
- lcd_wdat(table[hour/10]);
- lcd_wdat(table[hour%10]);
- temp=(hour)/10*16+(hour)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x84,temp); //向DS1302內(nèi)寫小時(shí)寄存器84H寫入調(diào)整后的小時(shí)數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 4:day++; //設(shè)置鍵按動(dòng)5次,調(diào)天
- if(day==32) day=1; //天數(shù)據(jù)加到32時(shí)自動(dòng)變成1
- if(mouth==2){if(day==30) day=1;}
- if(mouth==4){if(day==31) day=1;}
- if(mouth==6){if(day==31) day=1;}
- if(mouth==9){if(day==31) day=1;}
- if(mouth==11){if(day==31)day=1;}
- lcd_pos(3,5);
- lcd_wdat(table[day/10]);
- lcd_wdat(table[day%10]);
- temp=(day)/10*16+(day)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x86,temp); //向DS1302內(nèi)寫日期寄存器86H寫入調(diào)整后的日期數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù) write_1602com(yh+10);
- break;
- case 5:mouth++; //設(shè)置鍵按動(dòng)6次,調(diào)月
- if(mouth>=13) mouth=1; //月數(shù)據(jù)加到12時(shí)自動(dòng)變成1
- lcd_pos(3,3);
- lcd_wdat(table[mouth/10]);
- lcd_wdat(table[mouth%10]);
- temp=(mouth)/10*16+(mouth)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x88,temp); //向DS1302內(nèi)寫月份寄存器88H寫入調(diào)整后的月份數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 6:year++; //設(shè)置鍵按動(dòng)7次,調(diào)年
- if(year==100) year=0; //年數(shù)據(jù)加到100時(shí)自動(dòng)變成0
- lcd_pos(3,1);
- lcd_wdat(table[year/10]);
- lcd_wdat(table[year%10]);
- temp=(year)/10*16+(year)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x8c,temp); //向DS1302內(nèi)寫年份寄存器8cH寫入調(diào)整后的年份數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- }
- }
- while(!s1);
- }
- }
- if(n!=0)
- {
- if(s2==0) //調(diào)整+鍵
- {
- delay(30);
- if(s2==0)
- {
- TR0=0;
- switch(n)
- {
- case 1:sec--; //設(shè)置鍵按動(dòng)1次,調(diào)秒
- if(sec==-1) sec=59; //秒減到0時(shí)就歸59
- lcd_pos(2,6);
- lcd_wdat(table[sec/10]);
- lcd_wdat(table[sec%10]);
- temp=(sec)/10*16+(sec)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x80,temp); //向DS1302內(nèi)寫秒寄存器80H寫入調(diào)整后的秒數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 2:min--; //設(shè)置鍵按動(dòng)2次,調(diào)分
- if(min==-1) min=59; //分?jǐn)?shù)據(jù)減到0時(shí)自動(dòng)變成59
- lcd_pos(1,6);
- lcd_wdat(table[min/10]);
- lcd_wdat(table[min%10]);
- temp=(min)/10*16+(min)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x82,temp); //向DS1302內(nèi)寫分寄存器82H寫入調(diào)整后的分?jǐn)?shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 3:hour--;
- if(hour==-1) hour=23; //時(shí)數(shù)據(jù)減到0時(shí)自動(dòng)變成23
- lcd_pos(0,6);
- lcd_wdat(table[hour/10]);
- lcd_wdat(table[hour%10]);
- temp=(hour)/10*16+(hour)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x84,temp); //向DS1302內(nèi)寫小時(shí)寄存器84H寫入調(diào)整后的小時(shí)數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 4:day--; //設(shè)置鍵按動(dòng)5次,調(diào)天
- if(day==0) day=31; //天數(shù)據(jù)減到0時(shí)自動(dòng)變成31
- if(mouth==2){if(day==-1) day=29;}
- if(mouth==4){if(day==-1) day=30;}
- if(mouth==6){if(day==-1) day=30;}
- if(mouth==9){if(day==-1) day=30;}
- if(mouth==11){if(day==-1)day=30;}
- lcd_pos(3,5);
- lcd_wdat(table[day/10]);
- lcd_wdat(table[day%10]);
- temp=(day)/10*16+(day)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x86,temp); //向DS1302內(nèi)寫日期寄存器86H寫入調(diào)整后的日期數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù) write_1602com(yh+10);
- break;
- case 5:mouth--; //設(shè)置鍵按動(dòng)6次,調(diào)月
- if(mouth==0) mouth=12; //月數(shù)據(jù)減到0時(shí)自動(dòng)變成12
- lcd_pos(3,3);
- lcd_wdat(table[mouth/10]);
- lcd_wdat(table[mouth%10]);
- temp=(mouth)/10*16+(mouth)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x88,temp); //向DS1302內(nèi)寫月份寄存器88H寫入調(diào)整后的月份數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- case 6:year--; //設(shè)置鍵按動(dòng)7次,調(diào)年
- if(year==-1) year=99; //年數(shù)據(jù)減到0時(shí)自動(dòng)變成99
- lcd_pos(3,1);
- lcd_wdat(table[year/10]);
- lcd_wdat(table[year%10]);
- temp=(year)/10*16+(year)%10; //十進(jìn)制轉(zhuǎn)換成DS1302要求的DCB碼
- write_1302(0x8e,0x00); //允許寫,禁止寫保護(hù)
- write_1302(0x8c,temp); //向DS1302內(nèi)寫年份寄存器8cH寫入調(diào)整后的年份數(shù)據(jù)BCD碼
- write_1302(0x8e,0x80); //打開寫保護(hù)
- break;
- }
- }
- while(!s2);
- }
- }
- if(n!=0)
- {
- if(yes==0) //調(diào)整值確認(rèn)鍵按下,保存設(shè)置的參數(shù),直接退出調(diào)整狀態(tài),進(jìn)入走時(shí)。
- {
- delay(30);
- if(yes==0)
- {
- n=0;
- TR0=1; //打開定時(shí)器
- temp=(sec)/10*16+(sec)%10;
- write_1302(0x8e,0x00);
- write_1302(0x80,0x00|temp); //秒數(shù)據(jù)寫入DS1302
- write_1302(0x8e,0x80);
- delay(100);
- time_display();
- }
- while(!yes); //松開按鍵檢測(cè)
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
計(jì)數(shù)器 時(shí)鐘.rar
(26.66 KB, 下載次數(shù): 32)
2019-7-27 09:57 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|