性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復(fù)
  • 收藏
  • 點(diǎn)贊
  • 分享
  • 發(fā)新帖

STC15F104E制作的15小時(shí)(或150分鐘)定時(shí)器

STC15F104E制作的15小時(shí)定時(shí)器-原理圖

//*****使用STC15F104E制作的計(jì)時(shí)器*****
//1. 上電為關(guān)閉狀態(tài)。
//2. 長(zhǎng)按按鍵上電可轉(zhuǎn)換模式,默認(rèn)模式1:10分-150分 步進(jìn)10分鐘設(shè)置,共15檔設(shè)置。模式2:1小時(shí)-15小時(shí) 步進(jìn)1小時(shí)設(shè)置,共15檔設(shè)置。
//3. 按一下按鍵可以遞增計(jì)時(shí)時(shí)間,1、2、3...一直可以累加到15檔,再按則關(guān)閉(計(jì)時(shí)時(shí)間為0)。
//4. 使用4個(gè)LED分別按8421碼指示總計(jì)時(shí)時(shí)間,最多15檔。
//5. 計(jì)時(shí)期間,繼電器吸合,計(jì)時(shí)結(jié)束后繼電器釋放,蜂鳴器響起。
//6. 計(jì)時(shí)期間相應(yīng)的LED每秒閃一次。
//7. 可以斷電記憶未完成的時(shí)間,來電接著繼續(xù)計(jì)時(shí)??紤]到STC單片機(jī)EEPROM壽命問題,故10分鐘保存一次計(jì)時(shí)狀態(tài)。
//8. 因STC15F104E上電后P3.3是低電平,故P3.3接按鍵,以避免副作用。
//9. 使用內(nèi)部振蕩11.0592M

#include 
#include 

typedef unsigned char  UINT8;
typedef unsigned int   UINT16;

//***************************************************************************
//定義Flash操作等待時(shí)間及允許IAP/ISP/EEPROM 操作的常數(shù)
#define ENABLE_ISP 0x83 //系統(tǒng)工作時(shí)鐘<12MHz 時(shí),對(duì)IAP_CONTR 寄存器設(shè)置此值

sbit relay= P3^5; 	
sbit key1 = P3^3;	//因STC15F104E加電P3.3為低電平,為避免副作用,作為按鍵輸入。
sbit led1 = P3^4;
sbit led2 = P3^2;
sbit led3 = P3^1;
sbit led4 = P3^0;

UINT8 sec, min,count;	 //時(shí)間計(jì)數(shù)
UINT8 buzz_time = 0;	 //蜂鳴器響鈴時(shí)間設(shè)置
UINT8 Delay_counting = 0;//按鍵消抖

bit light, save;
bit min_hour = 0 ;		 //分和時(shí)計(jì)數(shù)選擇  模式選擇:0=時(shí)鐘計(jì)數(shù)  1=分鐘計(jì)數(shù)
bit system_time = 0;	 //系統(tǒng)時(shí)間標(biāo)記	
bit run_stop = 0; 		 //時(shí)間計(jì)數(shù)與停止  0=停止計(jì)數(shù)  1=允許計(jì)數(shù)
bit buzz_run = 0 ;		 //1 = 啟動(dòng)蜂鳴器  0= 關(guān)閉蜂鳴器

#define MAX_HOURS   15	 //時(shí)設(shè)置最大值




//***************************************************************************
void IAP_Disable()
{
    //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
    //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
    IAP_CONTR = 0;  //關(guān)閉IAP 功能
    IAP_CMD   = 0;  //清命令寄存器,使命令寄存器無命令,此句可不用
    IAP_TRIG  = 0;  //清命令觸發(fā)寄存器,使命令觸發(fā)寄存器無觸發(fā),此句可不用
    IAP_ADDRH = 0;
    IAP_ADDRL = 0;
}

//***************************************************************************
//eeprom讀一字節(jié)
//入口: addr = 要讀取字節(jié)的地址
//返回: 讀出的字節(jié)
//***************************************************************************
UINT8 Byte_Read(UINT16 addr)
{
    IAP_DATA = 0x00;
    IAP_CONTR = ENABLE_ISP; //打開IAP 功能, 設(shè)置Flash 操作等待時(shí)間
    IAP_CMD = 0x01;         //IAP/ISP/EEPROM 字節(jié)讀命令

    IAP_ADDRH = addr >> 8;  //設(shè)置目標(biāo)單元地址的高8 位地址
    IAP_ADDRL = addr;       //設(shè)置目標(biāo)單元地址的低8 位地址
    
    IAP_TRIG = 0x5A;   //先送5Ah,再送A5h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h后,ISP/IAP 命令立即被觸發(fā)起動(dòng)
    _nop_();    _nop_();    _nop_();
    //IAP_Disable();  //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
                      //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
    return (IAP_DATA);  //返回讀到的數(shù)據(jù)
}

//***************************************************************************
//eeprom寫一字節(jié)
//入口: addr = 要寫字節(jié)的地址
//      ch = 要寫入的字節(jié)數(shù)據(jù)
//***************************************************************************
void Byte_Write(UINT16 addr, UINT8 ch)
{
    IAP_CONTR = ENABLE_ISP; //打開 IAP 功能, 設(shè)置Flash 操作等待時(shí)間
    IAP_CMD = 0x02;         //IAP/ISP/EEPROM 字節(jié)編程命令
    
    IAP_ADDRH = addr >> 8;  //設(shè)置目標(biāo)單元地址的高8 位地址
    IAP_ADDRL = addr;       //設(shè)置目標(biāo)單元地址的低8 位地址
    
    IAP_DATA = ch;        //要編程的數(shù)據(jù)先送進(jìn)IAP_DATA 寄存器
    IAP_TRIG = 0x5A;   //先送5Ah,再送A5h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h后,ISP/IAP 命令立即被觸發(fā)起動(dòng)
    _nop_();    _nop_();    _nop_();
    //IAP_Disable();  //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
                      //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
}

//***************************************************************************
//eeprom扇區(qū)擦除
//入口: sect_addr = 扇區(qū)地址
//***************************************************************************
void Sector_Erase(UINT16 sect_addr)
{
    IAP_CONTR = ENABLE_ISP; //打開IAP 功能, 設(shè)置Flash 操作等待時(shí)間
    IAP_CMD = 0x03;         //IAP/ISP/EEPROM 扇區(qū)擦除命令
    
    IAP_ADDRH = (sect_addr & 0xFE00) >> 8; //設(shè)置目標(biāo)單元地址的高8 位地址
    IAP_ADDRL = sect_addr;                 //設(shè)置目標(biāo)單元地址的低8 位地址

    IAP_TRIG = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 觸發(fā)寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被觸發(fā)起動(dòng)
    _nop_();    _nop_();    _nop_();
    //IAP_Disable();  //關(guān)閉IAP 功能, 清相關(guān)的特殊功能寄存器,使CPU 處于安全狀態(tài),
    //一次連續(xù)的IAP 操作完成之后建議關(guān)閉IAP 功能,不需要每次都關(guān)
}




//***************************************************************************
//**Run and stop**
//***************************************************************************
void BeginRun()
{
    relay = 0;
    led1 = led2 = led3 = led4 = 1;
    run_stop = 1;
    sec = min = 0;
}

//***************************************************************************
void StopRun()
{
    relay = 1;
    run_stop = 0;
    led1 = led2 = led3 = led4 = 1;
    sec = min = 0;
    count = 0;
}

//***************************************************************************
//**定時(shí)器**
//***************************************************************************
void Init()		//50毫秒@11.0592MHz
{
    AUXR &= 0x7F;	//定時(shí)器時(shí)鐘12T模式
    TMOD &= 0xF0;	//設(shè)置定時(shí)器模式
    TL0 = 0x00;		//設(shè)置定時(shí)初值
    TH0 = 0x4C;		//設(shè)置定時(shí)初值
    TF0 = 0;		//清除TF0標(biāo)志
    TR0 = 1;		//啟動(dòng)定時(shí)器0計(jì)時(shí)
    ET0 = 1;
    EA = 1;
    
}

//***************************************************************************
//定時(shí)器0中斷
//***************************************************************************
void Timer0() interrupt 1
{
	   system_time = 1 ; //系統(tǒng)時(shí)間標(biāo)記
}




//***************************************************************************
//**模式:按時(shí)鐘計(jì)數(shù)**
//***************************************************************************
void time_hour()
{
	static UINT8 tim0, tim1, tim2;
	if(1==system_time && 1==run_stop)
	{
		system_time = 0;
		if(++tim0 >= 10)    //500ms
	    {
	        tim0 = 0;
	        light = !light;
	        if(++tim1 >= 2) //1s
	        {
	            tim1 = 0;
	            if(++sec >= 60) //1m
	            {
	                if(++tim2 >= 10)    //10m
	                {
	                    tim2 = 0;
	                    save = 1;
	                }
	                sec = 0;


	                if(++min >= 60) //1h
	                {
	                    min = 0;
	                    if(count>=1){count--;if(0==count){buzz_run = 1;}}
						else
	                    {
	                        StopRun();
	                        Sector_Erase(0);	//計(jì)時(shí)結(jié)束后清除保存的信息,以防下次加電繼續(xù)計(jì)時(shí)。					
	                    }
	                }

	            }
	        }
	    }
	}

}	  


 
//***************************************************************************
//**模式:按分鐘計(jì)數(shù)**
//***************************************************************************
void time_min()
{
	static UINT8 tim0, tim1, tim2;
	if(1==system_time && 1==run_stop)
	{
		system_time = 0;
		if(++tim0 >= 5)    //500ms
	    {
	        tim0 = 0;
	        light = !light;
	        if(++tim1 >= 4) //1s
	        {	
	            tim1 = 0;
	            if(++sec >= 60) //1min
	            {
					sec = 0;
					
	                if(++tim2 >= 10)    //10min
	                {	
	                    tim2 = 0;
	                    save = 1;
						if(count>=1){count--;if(0==count){buzz_run = 1 ;}}
						else 
						{					
							StopRun();			//停止計(jì)數(shù)
							Sector_Erase(0);	//計(jì)時(shí)結(jié)束后清除保存的信息,以防下次加電繼續(xù)計(jì)時(shí)。							
						}
	                }		                
	            
	            }
	        }
		}
	}   
}


//***************************************************************************
//**蜂鳴器輸出**
//***************************************************************************
void buzz_out()
{
	static UINT8 number;
	if(1==buzz_run){buzz_time = 50;buzz_run = 0;}//如果時(shí)間到........
	
	if(1 == system_time && 0== run_stop && buzz_time>=1)
	{
		system_time = 0;  //系統(tǒng)時(shí)間時(shí)標(biāo)
		if(++number >= 5) //響鈴間隔
		{
			number = 0 ;
			if(--buzz_time>=1)
			{
				key1 = ~key1;
			}	
			else {key1 = 1 ;buzz_time = 0;}
		} 

	}

}





//***************************************************************************
//**10us延時(shí)**用于按鍵消抖
//***************************************************************************
void Delay(void)
{
  UINT8 i,j,k;
 
  	 for(i=6;i>0;i--)
     for(j=1;j>0;j--)
     for(k=1;k>0;k--);
}



//***************************************************************************
//**按鍵設(shè)置時(shí)間**
//***************************************************************************
void ReadKey()
{
	if(buzz_time<=0)   //按鍵引腳與蜂鳴器輸出共用,蜂鳴器響時(shí)按鍵不參與檢測(cè)
	{
		if(!key1)					
		{
	
			if(Delay_counting < 40)  //按鍵消抖
			{
				Delay();			 //延時(shí)10us
				Delay_counting++;	
			}
			
	
	
	
			if(!key1 && Delay_counting == 40)	
			{
				count++ ; 
				if(count > MAX_HOURS)  count=0;
			    if(count == 0)
			    {
			        StopRun();
			    }
			    else
			    {
			        BeginRun();
			    }
				Delay_counting = 210 ;					
			}
	
		}
				else if(key1)Delay_counting = 0;//松手清0,待下一次延時(shí)消抖

	}

}




//***************************************************************************
//**檢查時(shí)間**
//***************************************************************************
void check()	
{
	    
	
		if(count == 0 || count > MAX_HOURS)
	    {
	        count = 0;
	        run_stop = 0;
	    }
	    else
	    {
	        relay = 0;
	        run_stop = 1;
	    }

}




//***************************************************************************
//**8 4 2 1 LED顯示時(shí)間**
//***************************************************************************
void display()
{
        if(count == 0)  //運(yùn)行檢查
    {
        StopRun();
    }
    else
    {
        led4 = count & 8 ? light : 1;	//顯示時(shí)間
        led3 = count & 4 ? light : 1;
        led2 = count & 2 ? light : 1;
        led1 = count & 1 ? light : 1;
    }
}




//***************************************************************************
//**讀EPPROM**
//***************************************************************************
void read_data()
{
	sec = Byte_Read(0);	 //讀秒
    min = Byte_Read(1);	 //讀分
    min_hour = Byte_Read(2);//讀模式
    count = Byte_Read(3);	//讀時(shí)間設(shè)置
}




//***************************************************************************
//**寫EPPROM**
//***************************************************************************
void Write_epprom()
{
        if(save & TR0)  //保存到eeprom中
    {
        save = 0;
        Sector_Erase(0);//擦除EEPROM
        Byte_Write(0, sec);//寫秒
        Byte_Write(1, min);//寫分
        Byte_Write(2, min_hour);//寫模式
        Byte_Write(3, count);//寫設(shè)置時(shí)間
    }
}




//***************************************************************************
//**程序入口**
//***************************************************************************
void main()
{
    P3 = 0xFF;  //初始化端口狀態(tài)
    light = 0;	
    save = 0; 	//10分鐘保護(hù)一次時(shí)間數(shù)據(jù)

    Init();		//初始化定時(shí)器
  	read_data();//讀epprom
	check();	//檢查時(shí)間是否到
	buzz_time = 0;//蜂鳴器響鈴時(shí)間清0

	//模式選擇(按住按鍵上電)
	if(!key1){min_hour=~min_hour;buzz_time = 5;Sector_Erase(0);while(!key1){if(0==min_hour){led1 = 0;}else led4=0;};}	 
	//01 LED代表10 - 150 分鐘模式	 08 LED代表1 - 15 小時(shí)模式



    while(min_hour == 1)//**模式:時(shí)間按時(shí)鐘來計(jì)數(shù)**
    {

        ReadKey();  	//讀取按鍵
		time_hour();	//時(shí)計(jì)數(shù)
		buzz_out();		//蜂鳴器輸出
        Write_epprom(); //寫epprom
		display();	    //8 4 2 1 LED顯示時(shí)間
    }



	while(min_hour == 0)//**模式:時(shí)間按分鐘來計(jì)數(shù)**
	{
	    ReadKey();  	//讀取按鍵
		time_min();		//分鐘計(jì)數(shù)
		buzz_out();		//蜂鳴器輸出
		Write_epprom();	//寫epprom
		display();		//8 4 2 1 LED顯示時(shí)間
	}
}

1

2

 

 

全部回復(fù)(8)
正序查看
倒序查看
2014-04-28 08:39

不錯(cuò)挺好的帖子,也給其他想使用STC15F104的新人做了樣本程序!支持!

0
回復(fù)
2014-04-28 08:41
@yueyunno1
不錯(cuò)挺好的帖子,也給其他想使用STC15F104的新人做了樣本程序!支持!

個(gè)人建議你這個(gè)程序可以適當(dāng)優(yōu)化一下:

    1.按鍵釋放問題,防止按一次多次動(dòng)作;

    2.程序LED比較部分可以優(yōu)化;                                                    

0
回復(fù)
shenx123
LV.10
4
2014-04-28 15:27
有沒有詳細(xì)的程序解釋呢?
0
回復(fù)
178064035
LV.4
5
2014-04-28 18:37
@yueyunno1
個(gè)人建議你這個(gè)程序可以適當(dāng)優(yōu)化一下:    1.按鍵釋放問題,防止按一次多次動(dòng)作;    2.程序LED比較部分可以優(yōu)化;                                                    

按鍵釋放時(shí)是沒有問題的,不存在多次動(dòng)作。

 

 

 

0
回復(fù)
178064035
LV.4
6
2014-04-28 18:38
@shenx123
有沒有詳細(xì)的程序解釋呢?
基本上就這樣了 
0
回復(fù)
2014-04-28 23:30
@178064035
基本上就這樣了[圖片] 
其實(shí)可以把定時(shí)的時(shí)間再搞長(zhǎng)點(diǎn),或則設(shè)置幾個(gè)檔位,這樣可能更實(shí)用一些,150MIN有時(shí)候都顯得時(shí)間短了點(diǎn)!
0
回復(fù)
2014-04-29 00:20
@yueyunno1
其實(shí)可以把定時(shí)的時(shí)間再搞長(zhǎng)點(diǎn),或則設(shè)置幾個(gè)檔位,這樣可能更實(shí)用一些,150MIN有時(shí)候都顯得時(shí)間短了點(diǎn)!
說的是啊, 如果功能再多點(diǎn)就好了,反正程序可以隨便編寫的
0
回復(fù)
cltwolf
LV.5
9
2014-04-29 13:30

挺好的,振奮人心啊

0
回復(fù)
發(fā)