4-10 STM Timer/Counter 與比較吻合輸出 HT66F70A
STM (Standard type TM)提供5種模式 比對吻合輸出(Compare match) 計時/計數(Timer/Counter) 脈波寬度調變(PWM) 輸入捕捉(Input Capture) 單脈衝輸出模式(Single pulse output) 同時可搭配一支外部輸入腳位,以及TPn、TPnB兩支的輸出腳位進行運作。
STM 內部結構
STM 內部結構 16位元上數計數器TMnD 兩個內部暫存器TMnA(16 bit) TMnRP (8bit) TMnC0、TMnC1 特殊功暫存器 兩個內部暫存器CCRP(8bit)與CCRA(16bit)所組成。 由TnCK[2:0]位元的設定控制選擇七種不同的時脈信號作為16BIT上數計數器計數時脈源 操作模式 輸出特性
當啟動計數時(設定TnON=「1」),上數計數器會先清除為零,接著根據所選擇的時脈開始往上遞增。 計數過程中,比較器A與P會將其數值分別與TMnA(16bit)、TMnRP(8bit)的設定值進行比較,不同的工作模式在比對吻合時會產生不同的動作。 HT66F70A有兩組CTM計時模-TM2、TM4、TM5。
CTM 輸出入腳位 TH66F70A 計時模組: TM2,TM4,TM5 TM輸入腳位: TCK2,TCK4,TCK5 TM輸出腳位: TP2,TP2B TP4,TP4B TP5,TP5B
TMnC0 控制暫存器 Bit [7] : TnPAU : TMn計時/計數暫停控制位元 TnPAU TnCK2 TnCK1 TnCK0 TnON TnRP2 TnRP1 TnRP0 Bit 7 6 5 4 3 2 1 0 Bit [7] : TnPAU : TMn計時/計數暫停控制位元 = 1 : 暫停計數 = 0 : 繼續計數(當此為位元1時,TMnD由原暫停時的數值繼續往上計數) Bit [6 5 4] : TnCK[2:0] : TMn計數時脈選擇位元 = 000 : fINT= fsys/4 =100 : fINT= fINT = 001 : fINT= fsys =101 : 保留 = 010 : fINT= fsys/16 =110 : fINT=TCKn = 011 : fINT= fsys/64 =111 : fINT= TCKn’ Bit [3] : TnON : TM計時/計數控制位元 = 1 : 開始計數(當此為位元1時,TMnD先歸零後再開始往上計數) = 0 : 停止計數 Bit 2:0 保留 [0 0 0]
TMnC1 控制暫存器 TnM1 TnM0 TnIO1 TnIO0 TnOC TnPOL TnDPX TnCCLR Bit 7 6 5 4 3 2 1 0 Bit [7 6] : TnM[1:0] : STM模式控制位元 = 00 : STM為「比對吻合輸出」模式 = 01 : STM為「輸入補捉」模式 = 10 : STM為「PWM / single pulse」模式 = 11 : STM為「計時/計數」模式
TMnC1 控制暫存器 TnM1 TnM0 TnIO1 TnIO0 TnOC TnPOL TnDPX TnCCLR Bit 7 6 5 4 3 2 1 0 Bit [5 4] : TnIO[1:0] : TPn、 TPnB 為功能選擇位元 若STM為「比對吻合輸出」模式時(TnM[1:0]=00) : 00 : 比對吻合時,輸出不變 10 : 比對吻合時,輸出高態 01 : 比對吻合時,輸出低態 11 : 比對吻合時,輸出轉態 若STM為「輸入補捉」模式時 (TnM[1:0]=01) : 00: 在TP2_0, TP2_1輸入為正緣時,記錄TMnD 01: 在TP2_0, TP2_1輸入為負緣時,記錄TMnD 10: 在TP2_0, TP2_1輸入為負緣及正緣時,記錄TMnD 11: 停止輸入補捉功能 若STM為「PWM/Single Puls」模式 (TnM[1:0]=10) 00: 強制輸出為非啟動 10: PWM輸出 01: 強制輸出為啟動 11: Single Pulse Mode 若STM為計時/計數, (TnM[1:0]=11) 這兩位元無作用
TMnC1 控制暫存器 TnM1 TnM0 TnIO1 TnIO0 TnOC TnPOL TnDPX TnCCLR Bit 7 6 5 4 3 2 1 0 Bit [3] : TnOC 輸出準位控制位元 若STM為「比對吻合輸出」模式時(TP2M[1:0]=00) : 1 : 首次比對吻合前,輸出維持在「1」 0 : 首次比對吻合前,輸出維持在「0」 若STM為「PWM/Single Pulse」 (TP2M[1:0]=10) : 1 : 輸出啟動準位為「1」 0 : 輸出啟動準位為「0」 Bit [2] : TnPOL 輸出極性控制位元 1 : 輸出反向 0 : 輸出不反向 Bit [1] : TnDPX PWM模式之Duty與Period切換控制位元 = 1 : TMnRP控制Duty,TMnA控制Period = 0 : TMnRP控制Period ,TMnA控制Duty Bit [0] : TnCCLR = 1 : 當比較器 A 比對吻合時清除計數器 = 0 : 當比較器 P 比對吻合時或計數器溢位清除計數器
當CPU執行DELAY副程式時 STM仍繼續計數 待其計數值與TM2A暫存器所設定之參數產生比對吻合時 以中斷方式讓CPU跳至014h執行
4-10 STM(Compare match) - buzzer #include <HT66F70A.h> #define SPK_Port _pc4 //設定SPK_Port為PC4腳位 #define SPK_PortC _pcc4 //設定SPK_PortC為PCC4 #define _2M 2000000 typedef unsigned short u16; typedef unsigned char u8; u8 p=0,L=0 ; u16 COUNT=0; const u16 TAB_Pitch[] = { //音調參數 _2M/(523*2),_2M/(587*2), _2M/(659*2),_2M/(698*2), _2M/(785*2),_2M/(880*2), _2M/(988*2),_2M/(523*2*2)}; const u16 TAB_Duration[] ={ //音長參數 523/2,587/2,659/2,698/2, 785/2,880/2,988/2,(523*2)/2}; void Delay100us(u16 del); //函式原型宣告
主程式 void main() { _wdtc=0b10101111; //關閉看門狗計時器 _tm2c0=0; //fINT=fSYS/4 _tm2c1=0b00110101; //設定比較輸出模式與輸出方式 _pcs2=0x01; SPK_PortC=0; //規劃SPK_Port為輸出 _tm2al=TAB_Pitch[p]%256; // _tm2ah=TAB_Pitch[p]/256; //更改延遲時間 _emi=_t2ae=_mf0e=1; //啟用STM中斷 _t2on=1; //開啟計數 while(1) Delay100us(2000); }
副程式 void Delay100us(u16 del) //延遲del*200指令週期 { u16 i,j; //@fSYS=8MH,延遲del*100us for(i=0;i<del;i++) for(j=0;j<=25;j++) GCC_NOP(); } DEFINE_ISR(ISR_TM2A,0x14) { if(++COUNT==(2*TAB_Duration[L])) //計算方波個數 { _tm2al=TAB_Pitch[p]%256; // _tm2ah=TAB_Pitch[p]/256; //更改延遲時間 COUNT=0; if(++L>7)L=0; if(++p>7)p=0; _t2af=0;