|
108_623247_5a21717862c094a.jpg (18.51 KB, 下載次數(shù): 78)
下載附件
2016-2-2 04:20 上傳
108_623247_c9769c93bfd1353.jpg (29.56 KB, 下載次數(shù): 85)
下載附件
2016-2-2 04:20 上傳
108_623247_588760cef8bdc75.jpg (24.55 KB, 下載次數(shù): 96)
下載附件
2016-2-2 04:20 上傳
108_623247_79eafbb7dab5f89.jpg (33.71 KB, 下載次數(shù): 71)
下載附件
2016-2-2 04:20 上傳
用STC系列單片機(jī)制作四位可預(yù)置計(jì)時(shí)器_用UM5140X計(jì)時(shí)器電路改裝
#:當(dāng)使用的EEPROM起始地址不是C2~C7的IC時(shí)請(qǐng)到STC_EEPROM.h文件中注釋#define EEPROM_C2_C7這行宏定義
功能: 具有二個(gè)按鍵,四位紅色共陽(yáng)極數(shù)碼顯示
P3.6長(zhǎng)按 = 模式鍵、短按 = 移位、保存
P3.7長(zhǎng)按 = 開(kāi)始鍵、短按 = 加數(shù)、停止計(jì)時(shí)
具有正、倒;計(jì)分或計(jì)秒預(yù)設(shè)選擇
具有預(yù)約、倒計(jì)時(shí);開(kāi)機(jī)功能分別輸出一個(gè)1S低電平信號(hào)和一個(gè)長(zhǎng)通低電平信號(hào)
使用說(shuō)明:
A: 上電前若P1.0對(duì)地則為倒計(jì)秒//P1.1對(duì)地則為倒計(jì)分//其它狀態(tài)組合未定義,建議不使用。
1: 長(zhǎng)按P3.6口開(kāi)關(guān)則先重新調(diào)出存在eeprom在的計(jì)時(shí)停止計(jì)時(shí)顯示P***且第一個(gè)*以125ms閃爍
此時(shí)若依次短按P3.6口開(kāi)關(guān)則移向下一位閃爍,在該位閃爍若短按P3.7口的開(kāi)關(guān)則此位加1。
當(dāng)?shù)谌齻(gè)*閃爍時(shí)如果再短按一次P3.6口開(kāi)關(guān)則保存此次設(shè)定值并退出設(shè)置狀態(tài),顯示***。若
在閃爍10s內(nèi)沒(méi)有新鍵按下則自動(dòng)退出設(shè)置狀態(tài)并不保存此次設(shè)定值,顯示***。
2: 長(zhǎng)按P3.7口開(kāi)關(guān)則開(kāi)始計(jì)時(shí)顯示***且最后一個(gè)dp點(diǎn)閃爍,在計(jì)時(shí)器運(yùn)行中若短按P3.7口開(kāi)關(guān)則
停止計(jì)時(shí),10s內(nèi)沒(méi)有新鍵按下則自動(dòng)重載預(yù)設(shè)值,顯示***。
3: 當(dāng)時(shí)間從預(yù)設(shè)值倒計(jì)到 000 時(shí)停止倒計(jì)時(shí)且P1^2口輸出1S低電平信號(hào)(后自動(dòng)變高)、P1.3口長(zhǎng)通
低電平信號(hào)(短按P3.7口開(kāi)關(guān)可關(guān)閉),10s后自動(dòng)重載預(yù)設(shè)值。
程序設(shè)計(jì):LBQ691477940 2018-03-10
升級(jí)記錄:
增加上電自動(dòng)選擇設(shè)置正計(jì)時(shí)與倒計(jì)時(shí)的初步程序編寫(xiě)。 2018-3-11 23:08
P1.0 & P1.1 對(duì)地時(shí)為倒計(jì)秒
P1.0 對(duì)地時(shí)為倒計(jì)分
P1.1 對(duì)地時(shí)為正計(jì)秒
P1.0 & P1.1 不接時(shí)為正計(jì)分 2018-3-11 09:33- /*********************************************************************/
- #include
- #include
- #include
- #define nop _nop_()
- #define uint unsigned int
- #define uchar unsigned char
- #define ulong unsigned long
- #define SBI(Y,X) Y |= (1 << X) //讓Y的X位置1
- #define CBI(Y,X) Y &= ~(1 << X) //讓Y的X位清0
- #define set_key P1 //定義鍵盤(pán)口
- #define KEY P3 //定義鍵盤(pán)口
- #define set_djm 0x00 //P1.0 & P1.1 對(duì)地時(shí)為倒計(jì)秒
- #define set_zjm 0x01 //P1.0 對(duì)地時(shí)為倒計(jì)分
- #define set_djf 0x02 //P1.1 對(duì)地時(shí)為正計(jì)秒
- //#define set_zjf 0x03 //P1.0 & P1.1 不接時(shí)為正計(jì)分
- sbit P1_4 = P1^4; //位驅(qū)動(dòng)
- sbit P1_5 = P1^5; //位驅(qū)動(dòng)
- sbit P1_6 = P1^6; //位驅(qū)動(dòng)
- sbit P1_7 = P1^7; //位驅(qū)動(dòng)
- sbit OUT1S = P1^2; //到時(shí)間后輸出約1S低電平
- sbit OUTL = P1^3; //到時(shí)間后輸出低電平,直到短按P3^7口開(kāi)關(guān)鍵后才變高
- sbit DP = P2^2;
- sbit sw_mode = P3^6; //長(zhǎng)按為模式鍵、短按移位
- sbit sw_strat = P3^7; //長(zhǎng)按為開(kāi)始鍵、短按加數(shù)
- bit DPP = 0, g_shi = 0,up_dn; //閃爍標(biāo)志位、千位是否顯示標(biāo)志位、正計(jì)時(shí)與倒計(jì)時(shí)標(biāo)志位為1時(shí)倒計(jì)。
- static uchar yiwei = 4; //用于設(shè)置時(shí)間值時(shí)移位
- static uint count = 0; //定時(shí)器0內(nèi)的計(jì)數(shù)器
- uint set_count,set_time,time1 = 0; //倒計(jì)數(shù)次數(shù)、設(shè)置的時(shí)間值(倒計(jì)時(shí)計(jì)數(shù)器)、正計(jì)時(shí)計(jì)數(shù)器
- uchar shi,ge,sf,bf,xflash,flash1; //千位、百位、十位、個(gè)位、10s后自動(dòng)退出設(shè)置、到時(shí)間后輸出1s
- uchar Ttotal[4]; //前面三個(gè)字節(jié)為設(shè)置好的時(shí)間,最后一個(gè)字節(jié)用來(lái)判斷eeprom是否寫(xiě)過(guò)
- /********************* 函數(shù)聲明 *****************************************/
- uchar key_function(void); //獨(dú)立按鍵檢測(cè)函數(shù)聲明
- void delay_ms(uint n); //12MHZ晶振時(shí)毫秒級(jí)CPU延時(shí)函數(shù)
- void write_time(void); //轉(zhuǎn)換時(shí)間值并寫(xiě)入
- void abc_cba(unsigned int time); //轉(zhuǎn)換時(shí)間值供顯示
- void Read_time(void); //讀出存在eeprom內(nèi)的時(shí)間值
- /*********************** 共陽(yáng)極數(shù)字編碼 ********************************/
- uchar code table[]={
- //P2.0=E / P2.1=D / P2.2=DP / P2.3=C / P2.4=G / P2.5=B / P2.6=F / P2.7=A
- // 0 1 2 3 4 5 6 7 8 9
- 0x14,0xd7,0x4c,0x45,0x87,0x25,0x24,0x17,0x04,0x05,0x0e,0xff};//0~9 P共陽(yáng)極數(shù)字編碼
- /***************************************************************************/
- /*********************************************************************
- 功能:12MHZ晶振時(shí)毫秒級(jí)CPU延時(shí)函數(shù)
- 參數(shù): 1~65535(不可以為0)
- 結(jié)果:占用CPU方式延時(shí)與參數(shù)值相同的毫秒時(shí)間
- 備注:應(yīng)用于1T單片機(jī)時(shí)i<600 ;12T單片機(jī)時(shí)i<125
- XX: LBQ691477940 2011-02-19
- /**************************************************************************/
- void delay_ms(uint n)
- {
- uint i;
- while(--n !=0)
- {
- #ifdef EEPROM_C2_C7
- for(i = 0;i < 600;i++);
- #else
- for(i = 0;i < 125;i++);
- #endif
- }
- }
- /****************************************************************************
- /*********************************************************************
- 函數(shù)名:獨(dú)立按鍵檢測(cè)函數(shù)(帶參數(shù)返回)
- 全局變量:無(wú)
- 參數(shù)說(shuō)明:無(wú)
- 返回說(shuō)明:返回按鍵值
- 說(shuō)明:延時(shí)消抖,返回值為0xff表示無(wú)按鍵按下或按鍵不正常
- /**********************************************************************************/
- uchar key_function(void)
- {
- uchar data keytemp = 0; //按鍵值局部變量
- if ((set_key & 0x03) != 0x03) //如果有按鍵按下 0000 0011 03h
- // 0000 0001 01h
- { // 0000 0010 02h
- keytemp = set_key & 0x03; //取鍵值
- delay_ms(50); //延時(shí)消抖
- if ((set_key & 0x03) == keytemp)
- {
- return (keytemp); //返回按鍵值
- }
- else
- {
- return (0xff); //無(wú)正常按鍵
- }
- }
- return (0xff); //無(wú)按鍵按下
- }
- /************************************************************************/
- /********************* 轉(zhuǎn)換時(shí)間值并寫(xiě)入 ***************************/
- void write_time(void)
- {
- Ttotal[0] = time1 / 100;
- Ttotal[1] = time1 % 100 / 10;
- Ttotal[2] = time1 % 10;
- Ttotal[3] = 0x00;
- Sector_Erase(EEPROM_ADD); //擦除扇區(qū)
- String_write(EEPROM_ADD,4,Ttotal); //重新寫(xiě)入數(shù)據(jù)
- String_Read(EEPROM_ADD,4); //重新設(shè)置后讀出來(lái)備用,目的是更新Read_buf[]數(shù)組方便定時(shí)器0
- } //中斷后time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];的取值
- /*************************************************************************************/
- /***************************** 轉(zhuǎn)換時(shí)間值供顯示 *************************************/
- void abc_cba(unsigned int time)
- {
- ge = time / 100;
- sf = time % 100 / 10;
- bf = time % 10;
- }
- /**********************************************************************************/
- /************************** 讀出存在eeprom內(nèi)的時(shí)間值 *********************/
- void Read_time(void)
- {
- String_Read(EEPROM_ADD,4); //讀出來(lái)備用
- //EEPROM_ADD 要寫(xiě)讀內(nèi)部EEPROM的始起地扯
- // 4 共要讀出4個(gè)數(shù)據(jù)
- if(Read_buf[3] != 0)//不為0表示eeprom內(nèi)容未寫(xiě)過(guò)
- {
- time1 = 138;//給一個(gè)為138的初值
- write_time();//寫(xiě)入eeprom
- }
- set_time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];
- if(up_dn)time1 = set_time; //如果為倒計(jì)送設(shè)置的值
- else time1 = 0; //如果為正計(jì)送0
- }
- /******************************************************************************/
- //*******************************主程序******************************************
- void main()
- {
- uint keynum; //長(zhǎng)按計(jì)數(shù)緩存區(qū)
- bit key = 0 ; //sw_mode鍵長(zhǎng)按標(biāo)志位/正計(jì)、倒計(jì)
- SP = 0x60; //堆棧指針
- /******** 注意STC89系列沒(méi)有此時(shí)鐘頻率分頻功能故只能有 12M晶振 ******************/
- //CLK_DIV = 0x00; //系統(tǒng)時(shí)鐘
- CLK_DIV = 0x01; //系統(tǒng)時(shí)鐘/2
- //CLK_DIV = 0x02; //系統(tǒng)時(shí)鐘/4
- //CLK_DIV = 0x03; //系統(tǒng)時(shí)鐘/8
- //CLK_DIV = 0x04; //系統(tǒng)時(shí)鐘/16
- //CLK_DIV = 0x06; //系統(tǒng)時(shí)鐘/32
- //CLK_DIV = 0x06; //系統(tǒng)時(shí)鐘/64
- //CLK_DIV = 0x07; //系統(tǒng)時(shí)鐘/128
- /*********************************************************************************/
- set_key = 0xff;
- switch (key_function())
- {
- case set_djm:
- {
- up_dn = 1; //正計(jì)時(shí)與倒計(jì)時(shí)標(biāo)志位、為1時(shí)倒計(jì)。
- set_count = 20; //P1.6對(duì)地倒計(jì)秒
- break;
- }
- case set_djf:
- {
- up_dn = 1; //正計(jì)時(shí)與倒計(jì)時(shí)標(biāo)志位、為1時(shí)倒計(jì)。
- set_count = 1200; //P1.7對(duì)地倒計(jì)分
- break;
- }
- case set_zjm:
- {
- up_dn = 0; //正計(jì)時(shí)與倒計(jì)時(shí)標(biāo)志位、為1時(shí)倒計(jì)。
- set_count = 20; //P1.6對(duì)地倒計(jì)秒
- break;
- }
- /* case set_zjf:
- {
- break;
- } */
- default:
- {
- up_dn = 0; //正計(jì)時(shí)與倒計(jì)時(shí)標(biāo)志位、為1時(shí)倒計(jì)。
- set_count = 1200; //P1.7對(duì)地倒計(jì)分
- break;
- }
- }
- /***************************************************************************/
- TMOD = 0x11; //設(shè)置定時(shí)器0/1為工作方式1(0001 0001)
- //write_time();//寫(xiě)入eeprom
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;
- TH1 = (65536 - 2500) / 256;
- TL1 = (65536 - 2500) % 256;
- ET1 = 1;
- TR1 = 1;
- ET0 = 1;
- EA = 1; //開(kāi)定時(shí)器0中斷、啟動(dòng)定時(shí)器0、開(kāi)總中斷
- OUT1S = 1; //到時(shí)間后輸出約1S低電平,上電后置1
- OUTL = 1; //到時(shí)間后輸出約低電平,上電后置1
- Read_time(); //讀出存在eeprom內(nèi)的時(shí)間值
- if(up_dn) time1 = set_time;
- abc_cba(time1); //轉(zhuǎn)換時(shí)間值供顯示
- /********************* 長(zhǎng)按為模式鍵、短按移位 **************************************/
- while(1)
- {
- if ((KEY & 0xc0) == 0x80) //如果有按鍵按下 1100 0000 C0h
- // 1011 1111 80h
- {
- delay_ms(20); //延時(shí)消抖
- while ((KEY & 0xc0) == 0x80) //長(zhǎng)按為模式鍵、短按移位
- {
- keynum++;
- delay_ms(10); //防止干擾
- if (keynum > 200) //如果是長(zhǎng)按sw_mode模式鍵則
- {
- TR0 = 0; //停止計(jì)時(shí)器0
- DPP = 0; //關(guān)閉小數(shù)點(diǎn)閃爍標(biāo)志位
- key = 1; //置sw_mode鍵有長(zhǎng)按標(biāo)志位
- g_shi = 1; //千位是否顯示標(biāo)志位置位
- yiwei = 0;
- xflash = 0; //每按一次清0一次讓其永遠(yuǎn)達(dá)不到10s的退出值
- time1 = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];//重調(diào)回之前值
- if(up_dn) abc_cba(set_time);//如果為倒計(jì)時(shí)轉(zhuǎn)換set_time時(shí)間值供顯示
- else abc_cba(time1); //如果為正計(jì)時(shí)轉(zhuǎn)換time1時(shí)間值供顯示
- }
- }
- if (keynum > 200)
- {
- keynum = 0;
- }
- else if(keynum >= 10) //防止干擾
- {
- keynum = 0;
- if(key) //如果sw_mode鍵有長(zhǎng)按標(biāo)志位
- {
- TR0 = 0;
- DPP = 0; //關(guān)閉小數(shù)點(diǎn)閃爍標(biāo)志位
- xflash = 0; //每按一次清0一次讓其永遠(yuǎn)達(dá)不到10s的退出值
- yiwei++;
- if(yiwei >= 3)
- {
- yiwei = 4; //讓移位功能失效
- key = 0; //關(guān)閃sw_mode鍵有長(zhǎng)按標(biāo)志位
- g_shi = 0; //關(guān)閉千位是否顯示標(biāo)志位
- write_time(); //轉(zhuǎn)換時(shí)間值并寫(xiě)入
- if(!up_dn)time1 = 0; //如果為正計(jì)時(shí)則保存完后恢復(fù)time1為 000
- }
- }
- }
- }
- /**************** 長(zhǎng)按為開(kāi)始鍵、短按加數(shù)、停止計(jì)時(shí) ************************************/
- if ((KEY & 0xc0) == 0x40) //如果有按鍵按下 1100 0000 C0h
- { // 0111 1111 40h
- delay_ms(20); //延時(shí)消抖
- while ((KEY & 0xc0) == 0x40) //長(zhǎng)按為開(kāi)始鍵、短按加數(shù)、停止計(jì)時(shí)
- {
- keynum++;
- delay_ms(10); //防止干擾
- if (keynum > 200) //如果長(zhǎng)按sw_strat開(kāi)始鍵則
- {
- if((set_time !=0)||(up_dn == 0))//set_time=0未重置數(shù)時(shí)不能啟動(dòng)倒計(jì)時(shí)或?yàn)檎?jì)時(shí)模式時(shí)啟動(dòng)計(jì)時(shí)器
- {
- Read_time(); //啟動(dòng)前先更新set_time的值供定時(shí)器0中斷程序參考
- count = 0; //定時(shí)器0內(nèi)的計(jì)數(shù)器清0保持每次時(shí)間一樣
- TR0 = 1; //開(kāi)啟計(jì)時(shí)器0
- }
- }
- }
- if (keynum > 200)
- {
- keynum = 0;
- }
- else if(keynum >= 10) //防止干擾
- {
- keynum = 0;
- TR0 = 0; //關(guān)閃計(jì)時(shí)器0
- DPP = 0; //關(guān)閉小數(shù)點(diǎn)閃爍標(biāo)志位
- xflash = 0; //每按一次清0一次讓其永遠(yuǎn)達(dá)不到10s的退出值
- OUTL = 1; //短按P3^7口開(kāi)關(guān)鍵后才變高
- switch(yiwei)
- {
- case 0:
- {
- ge++;
- if(ge >= 10) //如果大于10清0
- ge = 0;
- break;
- }
- case 1:
- {
- sf++;
- if(sf >= 10) //如果大于10清0
- sf = 0;
- break;
- }
- case 2:
- {
- bf++;
- if(bf >= 10) //如果大于10清0
- bf = 0;
- break;
- }
- default:
- {
- break;
- }
- }
- set_time = time1 = ge * 100 + sf * 10 + bf; //將調(diào)節(jié)后的值轉(zhuǎn)換為time值
- }
- }
- if(up_dn) abc_cba(set_time);//如果為倒計(jì)時(shí)轉(zhuǎn)換set_time時(shí)間值供顯示
- else abc_cba(time1); //如果為正計(jì)時(shí)轉(zhuǎn)換time1時(shí)間值供顯示
- }
- }
- /**************************************************************************/
- /*****************************************************************************
- 函數(shù)功能:定時(shí)器中斷
- 入口參數(shù):
- 出口參數(shù):
- /****************************************************************************/
- void timer0(void) interrupt 1
- {
- CY = 0;
- TL0 +=(65536 - 50007) % 256;//中斷響應(yīng)時(shí)間同步修正/重裝初值(低8位修正值)
- TH0 = (65536 - 50000) / 256 +(unsigned char)CY;//高8位初值修正/重裝初值(高8位修正值)
- count++;
- if (count == set_count) //50ms x 20 = 1秒鐘
- { //50ms x 1200 = 1分鐘
- count = 0x00;
- time1++;
- set_time--;
- if(!set_time) //如果已倒計(jì)為0則重讀eeprom內(nèi)的值
- {
- TR0 = 0;
- flash1 = 0; //到時(shí)間后先將其清0保證1s輸出的時(shí)間
- DPP = 1; //這里置1經(jīng)下面取反后則為0關(guān)閉小數(shù)點(diǎn)閃爍標(biāo)志位
- OUT1S = OUTL = 0; //輸出低電平直到短按P3^7口開(kāi)關(guān)鍵后才變高
- } //到時(shí)間后輸出約1S低電平
- }
- DPP = ~DPP; //爍標(biāo)志位取反一次
- xflash = 0; //讓其永遠(yuǎn)達(dá)不到10s的退出值
- }
- /******************************************************************/
- /******************************************************************/
- void timer1(void) interrupt 3
- {
- static uchar led;
- uchar flash;
- bit flas;
- TH1 = (65536 - 2500) / 256;
- TL1 = (65536 - 2500) % 256;
- flash++;
- if(flash == 50) //2.5ms x 50 = 125ms
- {
- flash = 0;
- flas = !flas; //跟據(jù)移位值來(lái)使某位閃煥
- xflash++;
- if(!OUT1S) //從OUT1S輸出為低時(shí)才++
- flash1++;
- }
- if(flash1 == 8) //125ms x 8 = 1s 后自動(dòng)變?yōu)楦唠娖?br />
- {
- OUT1S = 1; //到時(shí)間后輸出約1S低電平
- }
- if(xflash == 80) //125ms x 80 = 10s 后自動(dòng)退出設(shè)置狀態(tài)
- {
- xflash = 0; //清0
- yiwei = 4; //讓跟據(jù)移位值來(lái)使某位閃煥功能失效
- if(up_dn)
- set_time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];//如果為倒計(jì)時(shí)重調(diào)回之前值
- else
- time1 = 0; //如果為倒計(jì)時(shí)則清0
- DPP = 0; //關(guān)閉小數(shù)點(diǎn)閃爍標(biāo)志位
- g_shi = 0; //關(guān)閉千位是否顯示標(biāo)志位
- }
- switch(led)
- {
- case 0:
- {
- P1_7 = 0;
- if(g_shi)
- P2 = table[10]; //不顯示千位
- else
- P2 = table[11]; //顯示千位
- P1_4 = 1;
- led = 1;
- break;
- }
- case 1:
- {
- if((flas)&&(yiwei == 0))//跟據(jù)移位值來(lái)使某位閃煥
- P2 = table[11]; //不顯示
- else
- P2 = table[ge]; //顯示個(gè)位
- P1_4 = 0;
- P1_5 = 1;
- led = 2;
- break;
- }
- case 2:
- {
- if((flas)&&(yiwei == 1))//跟據(jù)移位值來(lái)使某位閃煥
- P2 = table[11]; //不顯示
- else
- P2 = table[sf]; //顯示十分位
- P1_5 = 0;
- P1_6 = 1;
- led = 3;
- break;
- }
- case 3:
- {
- if((flas)&&(yiwei == 2))//跟據(jù)移位值來(lái)使某位閃煥
- P2 = table[11]; //不顯示
- else
- P2 = table[bf]; //顯示百分位
- if(DPP)
- DP = 0; //直接打開(kāi)小數(shù)點(diǎn)
- else
- DP = 1; //直接關(guān)閉小數(shù)點(diǎn)
- P1_6 = 0;
- P1_7 = 1;
- led = 0;
- break;
- }
- default:break;
- }
- }
- /******************************************** END ********************************/
復(fù)制代碼
|
|