


PS—串行口中斷優先級控制位
PT1—TC1中斷優先級控制位
PX1—外部中斷1優先級控制位
PT0—TC0中斷優先級控制位
PX0—外部中斷0優先級控制位
同優先級的中斷請求,按默認順序響應。
【說明】
1. 本文里類似的x均可取值為0或1。
3. 機器周期是單片機的基本操作周期,一個機器周期內單片機完成一項基本操作,如取指等。一個機器周期包含12個時鐘周期。時鐘周期是時鐘頻率的倒數。
4. T0對應引腳P3.4,T1對應P3.5。
5. INT0對應P3.2引腳,INT1對應P3.3引腳。
二、定時器的使用
由于定時器都是由初值計數直至溢出,因此最重要的就是設置計數器的初值。 假設需要定時器產生一次中斷的事件為t,計算初值的步驟如下:
四、例程
可將以下代碼直接復制到.c文件中。



STC89C52單片機定時器1實現計數器
///////////////////////////////////////////////////////////////////////////
實現功能: 配置定時器1的相關寄存器,使其實現定時器中斷功能,然后通過在數碼管顯示
實驗板型號:BS-XYD-C52
實驗名稱: 定時器1實現計數器
///////////////////////////////////////////////////////////////////////////
#include《reg52.h》
#define uchar unsigned char //定義unsigned char 為 uchar
#define uint unsigned int //定義unsigned int 為 uint
uchar cTime_10ms_counter; //中斷次數計數單元
uchar cTime_1s_ok; //判斷是否為1s的變量
uchar uDis_buff[2]; //顯示緩沖區,存放要顯示的2個字符的段碼值
uchar cTime; //秒計數單元
#define Time_1s_Sign 100 //根據中斷周期,判斷是否到一秒的標志
sbit Duan=P2^6; //定義數碼管的段選使能端
sbit Wei =P2^7; //定義數碼管的位選使能端
#define Digital_tube_Wei_Enable Wei=1; //開啟控制數碼管的位選使能端
#define Digital_tube_Wei_Disable Wei=0; //關閉控制數碼管的位選使能端
#define Digital_tube_Duan_Enable Duan=1; //開啟控制數碼管的段選使能端
#define Digital_tube_Duan_Disable Duan=0; //關閉控制數碼管的段選使能端
#define Digital_tube_Duan P0 //定義數碼管數據端口
uchar code Dis_table[]= //將BCD碼轉換成數碼管掃描碼的數組
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code Dis_Position[]= //定義數碼管位選的數組
{0x3e,0x3d,0x3b,0x37,0x1f,0x2f};
///////////////////////////////////////////////////////////////////////////
函數名稱:毫秒延時函數
函數功能:實現毫秒級的延時
參數介紹:Delay_MS: 定義需要延時的毫秒的數值
iNumber: 記錄Delay_MS的數值,以for語句實現所要求的延時
iValue: 要延時毫秒所要進行的循環數值,本數值為實際測得
返回值: 無
注意事項:本實驗是在所用晶振為12M的前提下實現的毫秒延時,本函數是通過循環的形
式完成,所以如果改變了晶振的頻率,請做相應的改變
///////////////////////////////////////////////////////////////////////////
void DelayMs(uint Delay_MS)
{
uint iNumber,iValue;
for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for語句實現單片機的延時
{
iValue=107; //107這個數值是通過測定而得
while(iValue--);
}
}
///////////////////////////////////////////////////////////////////////////
函數名稱:One_DigitalTube_display
函數功能:完成在實驗板上數碼管指定顯示,即在特定的數碼管上顯示特定的數字,比
在第一個數碼管上顯示0
參數介紹:uData:要顯示的數字的BCD碼數組
uNumber:選擇哪個數碼管顯示,即讓某個特定數碼管顯示
返回值: 無
注意事項:實驗板上的數碼管是共陰極的數碼管,如果使用共陽極的數碼管,請注意不
要弄反了
///////////////////////////////////////////////////////////////////////////
void One_DigitalTube_display(uchar uData,uchar uNumber)
{
Digital_tube_Duan_Enable; //使能數碼管的段選
Digital_tube_Duan=Dis_table[uData];//輸入所要顯示的數值
Digital_tube_Duan_Disable; //關閉數碼管的段選
Digital_tube_Duan=Dis_Position[uNumber]; //點亮特定的數碼管
Digital_tube_Wei_Enable; //使能數碼管的位選
Digital_tube_Wei_Disable; //關閉數碼管的位選
DelayMs(5); //調整時序,以實現穩定顯示
}
///////////////////////////////////////////////////////////////////////////
函數名稱:Time_to_disbuffer
函數功能:把要在數碼管上顯示的數值,進行取余、取整,即對數值進行分割,這樣以
便顯示在分離的數碼管
參數介紹:無
返回值: 無
注意事項:無
///////////////////////////////////////////////////////////////////////////
void Time_to_disbuffer()
{
uDis_buff[1]=cTime; //對cTime的數值取余,即就是取cTime的個位
uDis_buff[0]=cTime/10; //對cTime的數值取整,即就是取cTime的十位
}
///////////////////////////////////////////////////////////////////////////
函數名稱:Init_time1
函數功能:配置定時器1,配置的模式是定時器1采用16位定時器模式,在定時器1的輸入
數值寄存器輸入特定的數值,使其每次中斷的周期為10ms,同時允許定時器1
中斷,并打開總中斷
參數介紹:無
返回值: 無
注意事項:無
///////////////////////////////////////////////////////////////////////////
void Init_time1(void)
{
TMOD |= 0x10;
TH1=(65535-10000)/256;
TL1=(65535-10000)%6; //定時器0的,寫入數值寄存器的低8位
EA=1; //總中斷打開
ET1=1; //定時器T0允許中斷
TR1=1; //定時器T0開始工作
}
///////////////////////////////////////////////////////////////////////////
函數名稱:Timer_Display
函數功能:把顯示緩沖區的數值顯示在數碼管上
參數介紹:cNumber:記錄for語句的循環次數
返回值: 無
注意事項:無
///////////////////////////////////////////////////////////////////////////
void Timer_Display()
{
uchar cNumber;
for(cNumber=0;cNumber《2;cNumber++)
{
One_DigitalTube_display(uDis_buff[cNumber],cNumber);
DelayMs(2);
}
}
///////////////////////////////////////////////////////////////////////////
函數名稱:main
函數功能:利用定時器1中斷,在數碼管上實現以一分鐘為周期的計數器
參數介紹:無
返回值: 無
注意事項:無
///////////////////////////////////////////////////////////////////////////
void main()
{
Init_time1(); //初始化定時器1
cTime=0;
while(1)
{
if(cTime_1s_ok)
{
cTime_1s_ok=0;
if(++cTime》=60) //每次自加一,同時判斷是否到1分鐘
{
cTime=0;
}
Time_to_disbuffer(); //新調整好的時間送入顯示緩沖區
}
Timer_Display(); //更新顯示內容
}
}
///////////////////////////////////////////////////////////////////////////
函數名稱:Interrupt_handler_time1
函數功能:重新給寄存器TH1和TL1賦值,判斷是否到達一秒,如果到一秒了,把相應的
變量賦予正值,以方便其他的程序編寫
參數介紹:無
返回值: 無
注意事項:無
///////////////////////////////////////////////////////////////////////////
void Interrupt_handler_time1(void) interrupt 3
{
uchar i;
TH1=(65535-10000)/256;//定時10毫秒
TL1=(65535-10000)%6;
cTime_10ms_counter++;
if(cTime_10ms_counter==Time_1s_Sign) //判斷是否到達一秒
{
cTime_10ms_counter=0;
cTime_1s_ok=1;
}
}
STC89C52單片機定時器2詳解
自認為單片機所有的資源中最不好搞清楚的就是定時器2,尤其是對于那些以前從來沒有玩過單片機的新手。定時器2是新增資源,也是51單片機定時器里面功能最強大的一個定時器。所以掌握好定時器2還是非常有必要的。以下是在我完全搞明白它的原理和用法的基礎上整理的一篇小文章。讀起來,好像Datasheet一樣!請原諒,希望沒有辜負你的點擊!
定時器2是一個16位定時器/計數器,通過設置特殊功能寄存器T2CON中的C/T2位可將其設置為定時器或是計數器;通過設置T2CON中的工作模式選擇位可將定時器2設置為三種工作模式,分別為捕獲、自動重新裝載(遞增或是遞減計數)和波特率發生器。
知識點一、定時器2的控制寄存器T2CON(可按位尋址)*
D7位--TF2:定時器2溢出標志位。用于請求中斷(必須由軟件清0)
D6位--EXF2:定時器外部標志位。當外部信號使能時,發生外部負跳變時置位請求中斷(必須由軟件清0)
D5位--RCLK:接受時鐘標志位。默認情況下串行口中模式1和模式3的時鐘是由定時器1的溢出率提供,若該位置位,則由定時器2提供。
D4位--TCLK:發送時鐘標志位。原理同上
D3位--EXEN2:定時器2的外部使能標志位。定時器2沒有作為串行口時鐘時,若將該位置位時,將允許T2EX的負跳變產生捕獲或重裝
D2位--TR2:定時器2啟動/停止控制位。
D1位--C/T2:定時器2的定時器/計數器選擇位(在reg52頭文件中定義為了C_T2,請注意,下面相同)
D0位--CP/RL2:捕獲/重裝標志位。
知識點二 ?、 ?定時器2的模式控制寄存器T2MOD(不可按位尋址)
該寄存器在單片機的頭文件reg2.h中可能沒有被定義,自己定義吧!
D1位—T2OE:定時器2輸出使能位
D0位—DCEN:向下計數使能位
知識點三:定時器2的三種模式*
*1、捕獲模式*
在“CP/RL2=1”&&“TR2=1”時進入捕獲模式。通過對控制寄存器T2CON的外部使能標志位EXEN2的置位和清0,又可以有分為如下兩種工作模式:
《1》EXEN2=0:
此時定時器2作為一個16位的定時器/計數器(由定時器/計數器選擇位C/T2位選擇)使用,實驗已通過。
《2》EXEN2=1:
此時定時器在前者的基礎上,增加一個特性,即允許接受外部輸入T2CON的負跳變,此負跳變使定時器2中的TH2和TL2中的值存入陷阱寄存器RCAP2H和RCAP2L中,并將外部標志位EXF2置位,引起中斷。該中斷與前者中的中斷同時存在并共用同一中斷程序(在中斷中可檢測TF2和T2EX位確定是哪一個引起的中斷)。除此之外該模式下,當中斷是T2EX位引發的時,雖然引發了中斷,但是由于不是溢出,并且計數器沒有停止計數,因此,此時TH2和TL2不用重新裝載值。
實驗證明在此模式下可以實現:用溢出中斷輸出方波,用線接入T2EX(P1^1),在T2EX的中斷中使蜂鳴器響起來,理論和實踐一樣,蜂鳴器響的頻率是方波的兩倍(因為它只捕捉負跳變)
2、自動重裝模式(遞增/遞減計數器)*
16位自動重裝模式中,定時器2可通過C/T2位配置為定時器/計數器,根據外部使能標志位EXEN2的置位和清0,可分為兩種情況:
《1》EXEN2=0時
定時器2為16位自動重裝的普通定時器,由陷阱寄存器提供重裝的值,只需要預設一下即可,可用于定時精度要求高,定時時間長(16位)的情況。
《2》EXEN2=1時,根據遞減計數使能位DCEN的置位和清0可分為兩種情況:
A1、T2MOD=0x00(DCEN=0;默認情況);
與上一種情況相比,此時16位自動重新裝載可由外部T2EX的負跳變,和溢出任意一種觸發,并都能產生中斷。
A2、T2MOD=0x01(DCEN=1);
此時允許T2EX控制計數的方向;T2EX=0時,重裝的值為0FF和0FF,遞減計數與陷阱寄存器預存值相等時,置位TF2產生中斷。T2EX=1時;自動重裝值為陷阱寄存器中的值,溢出時置位TF2產生中斷。
3、波特率發生器模式
T2CON的TCLK和RCLK位為0(默認)時,串行口發送和接受的波特率由定時器1提供;置位為1時,由定時器2提供。可以一個通過定時器1,一個通過定時器2,這樣可以獲得發送和接受時不同的波特率。
注意的地方: 定時器2作為定時器時,遞增頻率為晶振頻率的12分頻,而定時器2作為波特率發生器時,它的遞增頻率為晶振頻率的2分頻。
模式1和模式3的波特率=(振蕩器頻率/32) * (65535-N)
定時器2為計數模式時,外部時鐘信號由T2(P1^0)引腳進入。
定時器2作為波特率發生器的時候,TH2溢出并不會置位TF2,所以此時可以不用禁止定時器2中斷,若是EXEN2位被置位時,可以將T2EX作為附加的外部中斷。
定時器2作為波特率發生器的時候,不要對TH2和TL2讀寫,可以讀陷阱寄存器,但是也不要寫。當對定時器2的陷阱寄存器進行訪問時,應關閉定時器(TR2清0)。
4、可編程時鐘輸出
52系列單片機,可設定定時器/計數器2通過T2(p1^0)引腳輸出時鐘。
P1^0除了可以作為普通I/O口外,還可以作為定時器2的外部計數輸入和時鐘信號輸出。
C/T2=0并且T2MOD的T2OE位為1時,可將定時器2選為時鐘信號發生器,自動裝初值。設置公式:
時鐘信號輸出頻率=(振蕩器頻率/4)* (65535-N)
在時鐘輸出模式下,計數器溢出不會產生中斷請求。這種功能相當于定時器2可同時作為波特率發生器和時鐘發生器。
**因為此時外部中斷并沒有被暫用,若是在設置上不沖突的話可能同時還可以響應T2EX引入的外部信號,這個只是猜想,還沒有用實驗證明過,哈哈***
? ? ?單片機對于外來脈沖信號具有計數功能,但是有要求:
計數脈沖的最高頻率=振蕩器的頻率/24
并且為了確保給定電平在電平變化之前能被采樣一次,則這個電平至少要維持一個機器周期。
STC89C52單片機的定時器2的實現時鐘的程序
////////////////////////////////////////////////////////////////////////
實現功能: 配置定時器2的相關寄存器,使其實現定時器中斷功能,然后根據中斷
的周期頻率實現準確的時鐘系統,在數碼管上顯示實現
實驗板型號:BS-XYD-C52
實驗名稱: 定時器2實現時鐘系統
/////////////////////////////////////////////////////////////////////////
#include《reg52.h》
#define uchar unsigned char //定義unsigned char 為 uchar
#define uint unsigned int //定義unsigned int 為 uint
uchar cTime_10ms_counter; //中斷次數計數單元
uchar cTime_1s_ok; //判斷是否為1s的變量
uchar uDis_buff[6]; //顯示緩沖區,存放要顯示的6個字符的段碼值
uchar cTime[3]; //時、分、秒計數單元
#define Time_1s_Sign 100 //根據中斷周期,判斷是否到一秒的標志
sbit led=P1^0;
sbit Duan=P2^6; //定義數碼管的段選使能端
sbit Wei =P2^7; //定義數碼管的位選使能端
#define Digital_tube_Wei_Enable Wei=1; //開啟控制數碼管的位選使能端
#define Digital_tube_Wei_Disable Wei=0; //關閉控制數碼管的位選使能端
#define Digital_tube_Duan_Enable Duan=1; //開啟控制數碼管的段選使能端
#define Digital_tube_Duan_Disable Duan=0; //關閉控制數碼管的段選使能端
#define Digital_tube_Duan P0 //定義數碼管數據端口
uchar code Dis_table[]= //將BCD碼轉換成數碼管掃描碼的數組
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code Dis_Position[]= //定義數碼管位選的數組
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
/////////////////////////////////////////////////////////////////////////
函數名稱:毫秒延時函數
函數功能:實現毫秒級的延時
參數介紹:Delay_MS: 定義需要延時的毫秒的數值
iNumber: 記錄Delay_MS的數值,以for語句實現所要求的延時
iValue: 要延時毫秒所要進行的循環數值,本數值為實際測得
返回值: 無
注意事項:本實驗是在所用晶振為12M的前提下實現的毫秒延時,本函數是通過循環的形
式完成,所以如果改變了晶振的頻率,請做相應的改變
/////////////////////////////////////////////////////////////////////////
void DelayMs(uint Delay_MS)
{
uint iNumber,iValue;
for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for語句實現單片機的延時
{
iValue=107; //107這個數值是通過測定而得
while(iValue--);
}
}
/////////////////////////////////////////////////////////////////////////
函數名稱:One_DigitalTube_display
函數功能:完成在實驗板上數碼管指定顯示,即在特定的數碼管上顯示特定的數字,比
在第一個數碼管上顯示0
參數介紹:cData:要顯示的數字的BCD碼數組
cNumber:選擇哪個數碼管顯示,即讓某個特定數碼管顯示
返回值: 無
注意事項:實驗板上的數碼管是共陰極的數碼管,如果使用共陽極的數碼管,請注意不
要弄反了
/////////////////////////////////////////////////////////////////////////
void One_DigitalTube_display(uchar cData,uchar cNumber)
{
Digital_tube_Duan_Enable; //使能數碼管的段選
Digital_tube_Duan=Dis_table[cData];//輸入所要顯示的數值
Digital_tube_Duan_Disable; //關閉數碼管的段選
Digital_tube_Wei_Enable; //使能數碼管的位選
Digital_tube_Duan=Dis_Position[cNumber]; //點亮特定的數碼管的公共端
Digital_tube_Wei_Disable; //關閉數碼管的位選
DelayMs(1); //調整時序,以實現穩定顯示
}
/////////////////////////////////////////////////////////////////////////
函數名稱:Time_to_disbuffer
函數功能:把要在數碼管上顯示的數值,進行取余、取整,即對數值進行分割,這樣以
便顯示在分離的數碼管
參數介紹:cNumber1: 記錄時、分、秒計數單元數組的變量
cNumber2:記錄顯示緩沖區數組的變量
返回值: 無
注意事項:無
/////////////////////////////////////////////////////////////////////////
void Time_to_disbuffer()
{
uchar cNumber1,cNumber2=0;
for(cNumber1=0;cNumber1《=2;cNumber1++)
{
uDis_buff[cNumber2++]=cTime[cNumber1]/10; //對cTime的數值取整,即
//就是取cTime的十位
uDis_buff[cNumber2++]=cTime[cNumber1]; //對cTime的數值取余,即
//就是取cTime的個位
}
}
/////////////////////////////////////////////////////////////////////////
函數名稱:Init_time2
函數功能:配置定時器2,配置的模式是定時器1采用16位定時器模式,在定時器1的輸入
數值寄存器輸入特定的數值,使其每次中斷的周期為10ms,同時允許定時器1
中斷,并打開總中斷
參數介紹:無
返回值: 無
注意事項:無
/////////////////////////////////////////////////////////////////////////
void Init_time1(void)
{
TH2=(65535-10000)/256;
TL2=(65535-10000)%6; //定時器0的,寫入數值寄存器的低8位
EA=1; //總中斷打開
ET2=1; //定時器T0允許中斷
TR2=1; //定時器T0開始工作
}
/////////////////////////////////////////////////////////////////////////
函數名稱:Timer_Display
函數功能:把顯示緩沖區的數值顯示在數碼管上
參數介紹:cNumber:記錄for語句的循環次數
返回值: 無
注意事項:無
/////////////////////////////////////////////////////////////////////////
void Timer_Display()
{
uchar cNumber;
for(cNumber=0;cNumber《6;cNumber++)
{
One_DigitalTube_display(uDis_buff[cNumber],cNumber);
if(cNumber==1|cNumber==3)
{
Digital_tube_Duan_Enable; //使能數碼管的段選
Digital_tube_Duan=0x80; //輸入所要顯示的數值
Digital_tube_Duan_Disable; //關閉數碼管的段選
Digital_tube_Wei_Enable; //使能數碼管的位選
Digital_tube_Duan=Dis_Position[cNumber]; //點亮特定的數碼管的公共端
Digital_tube_Wei_Disable; //關閉數碼管的位選
DelayMs(1);
}
}
}
/////////////////////////////////////////////////////////////////////////
函數名稱:main
函數功能:利用定時器2中斷,實現準確的時鐘系統,然后在數碼管上顯示實現
參數介紹:無
返回值: 無
注意事項:無
/////////////////////////////////////////////////////////////////////////
void main()
{
Init_time1(); //初始化定時器1
cTime[0]=23,cTime[1]=58,cTime[2]=58;
Time_to_disbuffer(); //把預設時間送入顯示緩沖區
while(1)
{
if(cTime_1s_ok) //判斷是否到1秒了
{
cTime_1s_ok=0;
if(++cTime[2]》=60) //每次自加一,同時判斷是否到1分鐘
{
cTime[2]=0;
if(++cTime[1]》=60) //每次自加一,同時判斷是否到1小時了
{
cTime[1]=0;
if(++cTime[0]》=24) //每次自加一,同時判斷是否到24點了
{
cTime[0]=0;
}
}
}
Time_to_disbuffer(); //新調整好的時間送入顯示緩沖區
}
Timer_Display(); //更新顯示內容
}
}
/////////////////////////////////////////////////////////////////////////
函數名稱:Interrupt_handler_time2
函數功能:重新給寄存器TH2和TL2賦值,判斷是否到達一秒,如果到一秒了,把相應的
變量賦予正值,以方便其他的程序編寫
參數介紹:無
返回值: 無
注意事項:無
/////////////////////////////////////////////////////////////////////////
void Interrupt_handler_time2(void) interrupt 5
{
TF2=0;
TH2=(65535-10000)/256;//定時10毫秒
TL2=(65535-10000)%6;
cTime_10ms_counter++;
if(cTime_10ms_counter==Time_1s_Sign) //判斷是否到達一秒
{
cTime_10ms_counter=0;
cTime_1s_ok=1;
}
}
STC單片機STC89C52RC定時器延時時間的計算
延時時間要根據晶振頻率計算,不同板子可能有所不同。
時鐘周期:
1/時鐘源,在我現在這塊板子上,晶振頻率是11.0592M,也就是時鐘周期是 1/11059200秒
機器周期:
一般51單片機是12個時鐘周期,我的板子也就是 12/11059200秒
單次定時最長時間:
如果是16位的計數器,16位最大值是65535,共可計數65536次。基本的常數一定要記住,還要記住8位最大值是255,共可計數256次,還要記住8位上每位代表的數值。
12 * 65536/11059200 = 0.0711 s,也就是,71 ms內的定時可以單次定時就完成。如果定時時間超過71 ms,就要循環了。
一次定時需要幾次機器周期:
計算公式:定時秒數/機器周期
比 如我要定時1秒, 1/(12/11059200)= 921600次,16位計數器最大可計數65536次,921600次早就益出了。我們可以每次定時10 ms,循環100次就可以定時1秒了,1 s縮小100百倍就是10 ms, 也就是每次需要計數9216次。
確實計數器初始值:
定時10 ms時,如果計數器從0開始計數,我們就不知道什么時候到了9216次。所以應該計數了9216次,16位計數器最多計數95536次,然后就溢出,一溢出TCON的TF位就會置1,我們只要經常檢測TF位就可以知道什么時候完成10ms的定時了。
計算公式:計數器初始值=最大計數次數 - 需要計數次數
如果定時10 ms,計數器的初始值就是 65536 - 9216
計算計數器的高位和低位:
16位的計數器,也就是兩個8位組成,8位的最大計數次數是256。所以:
計數器高位 = 初始值/256
計數器低位 = 初始值%256
STC89C52RC單片機定時器示例代碼:
#include 《reg52.h》
//如果你的單片機沒用74hc138擴展IO口,下面代碼可略
sbit enableG1 = P1^3;
sbit enableG2 = P1^4;
sbit selectC = P1^2;
sbit selectB = P1^1;
sbit selectA = P1^0;
void hc138()
{
enableG1 = 1;
enableG2 = 0;
selectC = 1;
selectB = 1;
selectA = 0;
}
typedef unsigned char uint8;
typedef unsigned int uint16;
/**
1ms需要的機器周期 = 0.001/(12/11059200) = 921.6
要讓led燈以7.83hz閃動, 周期是 1000 / 7.83 = 127.713 ms, 也就是每64 ms改變亮滅狀態
**/
void main(void)
{
uint16 counter;
hc138();
TMOD = 0X01;
TH0 = (65536 - 922) / 256;
TL0 = (65536 - 922) % 256;
TR0 =1;
while(1)
{
if(TF0 == 1)
{
TF0 = 0;
TH0 = (65536 - 922) / 256;
TL0 = (65536 - 922) % 256;
counter++;
}
if(counter == 64)
{
counter = 0;
P0 = ~P0;
}
}
}
評論