您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
關(guān)于定時(shí)器 相信很多人都不會陌生,無論是51還是32,任何微控制器,都會有定時(shí)器
定時(shí)器控制器包含 4 組 32-位定時(shí)器,TIMER0~TIMER3,提供用戶便捷的計(jì)數(shù)定時(shí)功能。定時(shí)器可執(zhí)行很多功能,如頻率測量,時(shí)間延遲,時(shí)鐘發(fā)生,外部輸入管腳事件計(jì)數(shù)和外部捕捉管腳脈寬測量等。
特性
4 組 32-位定時(shí)器,帶24位向上計(jì)數(shù)器和一個(gè)8位的預(yù)分頻計(jì)數(shù)器
每個(gè)定時(shí)器都可以設(shè)置獨(dú)立的時(shí)鐘源
提供 one-shot, periodic, toggle 和 continuous 四種計(jì)數(shù)操作模式
通過CNT (TIMERx_CNT[23:0])可讀取內(nèi)部 24 位向上計(jì)數(shù)器的值
支持事件計(jì)數(shù)功能
通過CAPDAT (TIMERx_CAP[23:0])可讀取24-bit 捕捉值
支持外部管腳捕捉功能,可用于脈寬測量
支持外部引腳事件計(jì)數(shù),可用于復(fù)位24位向上定時(shí)器
如果定時(shí)器中斷信號產(chǎn)生,支持芯片從空閑/掉電模式喚醒
支持Timer0 超時(shí)溢出中斷來觸發(fā)Touch-Key 掃描
支持Timer0 ~ Timer3 超時(shí)溢出中斷或捕捉中斷來觸發(fā)PWM, EADC 和 DAC 功能
/****************************************************************************** * @file main.c * @version V1.00 * $Revision: 4 $ * $Date: 15/09/02 10:03a $ * @brief NuEdu Basic01 Timer Sample Code * @note * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include <stdio.h> #include "M451Series.h" #include "NuEdu-Basic01.h" /*---------------------------------------------------------------------------------------------------------*/ /* TMR0 IRQ handler */ /*---------------------------------------------------------------------------------------------------------*/ uint32_t volatile TimerCounter = 0; void TMR0_IRQHandler(void) { TimerCounter == 99 ? (TimerCounter = 0) : (TimerCounter++); // clear Timer0 interrupt flag TIMER_ClearIntFlag(TIMER0);//清空中斷標(biāo)志 } /*---------------------------------------------------------------------------------------------------------*/ /* MAIN function */ /*---------------------------------------------------------------------------------------------------------*/ int main(void) { //Initial System SYS_Init(); //Enable Timer0 clock and select Timer0 clock source CLK_EnableModuleClock(TMR0_MODULE);//使能模塊 CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);//選取時(shí)鐘源,和進(jìn)行分頻 //Initial Timer0 to periodic mode with 2Hz TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 2); //Enable Timer0 interrupt TIMER_EnableInt(TIMER0); NVIC_EnableIRQ(TMR0_IRQn); //Initial 7-Segment Open_Seven_Segment(); //Start Timer0 TIMER_Start(TIMER0); while(1) { Show_Seven_Segment(TimerCounter / 10, 1); CLK_SysTickDelay(200); Show_Seven_Segment(TimerCounter % 10, 2); CLK_SysTickDelay(200); } } /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/
TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 2);
定時(shí)器的模式有以下幾種:
#define TIMER_ONESHOT_MODE (0UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in one-shot mode */ #define TIMER_PERIODIC_MODE (1UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in periodic mode */ #define TIMER_TOGGLE_MODE (2UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in toggle-output mode */ #define TIMER_CONTINUOUS_MODE (3UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in continuous counting mode */ #define TIMER_TOUT_PIN_FROM_TX (0UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx pin */ #define TIMER_TOUT_PIN_FROM_TX_EXT (1UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx_EXT pin */ #define TIMER_CAPTURE_FREE_COUNTING_MODE (0UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to get timer counter value */ #define TIMER_CAPTURE_COUNTER_RESET_MODE (1UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to reset timer counter */ #define TIMER_CAPTURE_FALLING_EDGE (0UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Falling edge detection to trigger timer capture */ #define TIMER_CAPTURE_RISING_EDGE (1UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Rising edge detection to trigger timer capture */ #define TIMER_CAPTURE_FALLING_AND_RISING_EDGE (2UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Both falling and rising edge detection to trigger timer capture */ #define TIMER_COUNTER_FALLING_EDGE (0UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on falling edge detection */ #define TIMER_COUNTER_RISING_EDGE (1UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on rising edge detection */
定時(shí)器計(jì)數(shù)模式
定時(shí)器控制器提供四種定時(shí)器計(jì)數(shù)模式: one-shot, periodic, toggle-output 和 continuous counting 計(jì)數(shù)模式
One–shot模式
如果定時(shí)器工作在單周期 (one-shot) 模式(TIMERx_CTL[28:27]為00,且CNTEN (TIMERx_CTL[30])置1),則定時(shí)器的計(jì)數(shù)器開始計(jì)數(shù)。一旦CNT (TIMERx_CNT[23:0])計(jì)數(shù)器的值達(dá)到CMPDAT (TIMERx_CMP[23:0])的值時(shí),TIF (TIMERx_INTSTS[0])標(biāo)志將變?yōu)?,CNT的值和 CNTEN位將由定時(shí)器控制器自動(dòng)清零,然后定時(shí)器計(jì)數(shù)操作停止。與此同時(shí),如果INTEN (TIMERx_CTL[29])位使能,則定時(shí)器中斷信號產(chǎn)生并送到 NVIC通知CPU。
Periodic模式
如果定時(shí)器工作在周期 (periodic) 模式(TIMERx_CTL[28:27]為01)且CNTEN (TIMERx_CTL[30])置1,則定時(shí)器的計(jì)數(shù)器開始向上計(jì)數(shù)。一旦CNT (TIMERx_CNT[23:0])計(jì)數(shù)器的值達(dá)到CMPDAT (TIMERx_CMP[23:0])的值時(shí),TIF (TIMERx_INTSTS[0])標(biāo)志將變?yōu)?,CNT的值將由定時(shí)器控制器自動(dòng)清零,然后定時(shí)器重新計(jì)數(shù)。與此同時(shí),如果INTEN (TIMERx_CTL[29])使能,則定時(shí)器中斷信號產(chǎn)生并送到 NVIC 通知 CPU 。在該模式,定時(shí)器控制器周期性地操作計(jì)數(shù)和 與CMPDAT的值比較,直到CNTEN位由軟件清0
Toggle-Output模式
如果定時(shí)器工作在觸發(fā)輸出 (toggle-out) 模式(TIMERx_CTL[28:27]為10)且CNTEN (TIMERx_CTL[30])位置1,則定時(shí)器的計(jì)數(shù)器開始計(jì)數(shù)。toggle-out 模式的計(jì)數(shù)操做大部分與周期模式是一樣的,除了該模式當(dāng)TIF (TIMERx_INTSTS[0])位設(shè)置時(shí),有相關(guān)的T0 ~ T3管腳來輸出信號,因此,管腳T0 ~ T3上的觸發(fā)輸出信號以 50% 的占空周期反復(fù)改變。
Continuous Counting模式
如果定時(shí)器工作在連續(xù)計(jì)數(shù) (continuous counting) 模式(TIMERx_CTL[28:27]為11)且CNTEN (TIMERx_CTL[30])位置1,則定時(shí)器的計(jì)數(shù)器開始計(jì)數(shù)。一旦CNT (TIMERx_CNT[23:0])的值達(dá)到CMPDAT (TIMERx_CMP[23:0])的值時(shí),TIF (TIMERx_INTSTS[0])標(biāo)志將變?yōu)?,但CNT的值繼續(xù)保持向上計(jì)數(shù)。與此同時(shí),如果INTEN (TIMERx_CTL[29])使能,則定時(shí)器中斷信號產(chǎn)生并送到 NVIC 通知 CPU 。在該模式,用戶可以立刻改變不同的CMPDAT值,而不需要停止定時(shí)器計(jì)數(shù)和重新開始定時(shí)器計(jì)數(shù)。
例如,CMPDAT的值設(shè)置為 80。當(dāng)CNT 達(dá)到 80時(shí),TIF標(biāo)志將被置1,定時(shí)器計(jì)數(shù)器繼續(xù)計(jì)數(shù),而且CNT的值將不回到0,而是繼續(xù)計(jì)數(shù),81, 82, 83,˙˙˙ 到 (224 -1),然后再一次 0, 1, 2, 3, ˙˙˙ 到 224 -1,如此往復(fù)。接下來,如果軟件改變CMPDAT的值為200并且清除TIF標(biāo)志位,當(dāng)CNT的值達(dá)到200時(shí),TIF標(biāo)志將再次變?yōu)?,。最后,軟件改變CMPDAT的值為500并且清除TIF標(biāo)志,當(dāng)CNT的值達(dá)到500時(shí),TIF標(biāo)志將再次變?yōu)?。
在該模式,計(jì)數(shù)器計(jì)數(shù)是連續(xù)的。所以該操作模式叫做連續(xù)計(jì)數(shù)模式。
事件計(jì)數(shù)模式
定時(shí)器控制器也提供這樣的應(yīng)用,能對輸入事件(來自管腳Tx x=0~3)計(jì)數(shù)并將事件的次數(shù)反應(yīng)到
CNT (TIMERx_CNT[23:0]) 的值。也可以稱為事件計(jì)數(shù)功能。該功能下, EXTCNTEN
(TIMERx_CTL[24])位需置位并且定時(shí)器外設(shè)時(shí)鐘源必須設(shè)為HCLKPCLKx (x= 0~1)。
軟件可以通過CNTDBEN (TIMERx_EXTCTL[7])位來使能或關(guān)閉Tx管腳消抖電路。如果Tx管腳的消
抖電路關(guān)閉,輸入事件頻率必須少于1/3 PCLKxHCLK,如果消抖電路打開,輸入事件的頻率須小
于1/8 PCLKxHCLK , 以保證CNT 的值是正確的。軟件也可以通過設(shè)置CNTPHASE
(TIMERx_EXTCTL[0])來選擇邊沿檢測Tx管腳的相位。
事件計(jì)數(shù)模式下,定時(shí)器計(jì)數(shù)操作模式可以設(shè)置為單次,周期,和連續(xù)計(jì)數(shù)模式來計(jì)算來自Tx管腳
的輸入事件CNT (TIMERx_CNT[23:0])的值。
外部捕捉模式
事件捕捉功能是當(dāng)檢測到Tx_EXT管腳(x=0~3)邊沿電平有變化時(shí),CNT (TIMERx_CNT[23:0])會送
到CAPDAT (TIMERx_CAP[23:0])。在該模式下,需把CAPFUNCS (TIMERx_EXTCTL[4])位設(shè)置為
0,用來選擇Tx_EXT變化時(shí)用作事件捕捉功能,而且定時(shí)器外設(shè)時(shí)鐘源必須設(shè)為PCLKx (x=
0~1)HCLK。
軟件可以通過CAPDBEN (TIMERx_EXTCTL[6])位來使能或關(guān)閉Tx_EXT管腳消抖電路。在Tx_EXT
的消抖電路關(guān)閉時(shí),Tx_EXT管腳的轉(zhuǎn)變頻率必須少于1/3 PCLKxHCLK,在Tx_EXT的消抖電路打
開時(shí),Tx_EXT管腳的轉(zhuǎn)變頻率必須少于1/8 PCLKxHCLK,以保證捕捉功能能夠正常工作。軟件也
可以通過設(shè)置CAPEDGE (TIMERx_EXTCTL[2:1])位來選擇Tx_EXT管腳的邊沿轉(zhuǎn)變檢測方式。.
在事件捕捉模式,軟件不用考慮定時(shí)器計(jì)數(shù)器工作模式的選擇,只有當(dāng)檢測到Tx_EXT管腳有邊沿
變化時(shí)捕捉事件才會發(fā)生。
如果CPU不清除CAPIF狀態(tài)標(biāo)志,用戶應(yīng)知道此時(shí)的定時(shí)器會保持TIMERx_CAP寄存器的值不變,
且不會保存新的捕捉值。
外部復(fù)位計(jì)數(shù)模式
當(dāng)檢測到Tx_EXT管腳(x=0~3)有邊沿轉(zhuǎn)變時(shí),定時(shí)器同樣提供事件復(fù)位計(jì)數(shù)器功能來復(fù)位CNT
(TIMERx_CNT[23:0]) 的值。在該模式, 大部分設(shè)置與事件捕捉功能相同, 除了CAPFUNCS
(TIMERx_EXTCTL[4])位必須設(shè)置為1來選擇Tx_EXT轉(zhuǎn)變時(shí)用作為事件復(fù)位計(jì)數(shù)器。
定時(shí)器觸發(fā)功能
定時(shí)器控制器提供定時(shí)器超時(shí)溢出中斷或捕捉中斷來觸發(fā)PWM,DAC和EADC. 如果TRGSSEL (TIMERx_CTL[18])為0, 超時(shí)溢出中斷信號用于觸發(fā)PWM, EADC和DAC. 如果TRGSSEL (TIMERx_CTL[18]) 為 1, 捕捉中斷信號用于觸發(fā)PWM, EADC 和 DAC.
當(dāng)TRGPWM (TIMERx_CTL[19])被置1, 如果定時(shí)中斷信號產(chǎn)生, 定時(shí)器控制器將產(chǎn)生一個(gè)觸發(fā)脈沖作為PWM外部時(shí)鐘源。
當(dāng)TRGDAC (TIMERx_CTL[20]) 被置1, 如果定時(shí)中斷信號產(chǎn)生, 定時(shí)器控制器將觸發(fā)DAC開始轉(zhuǎn)換。
當(dāng)TRGEADC (TIMERx_CTL[21]) 被置1, 如果定時(shí)中斷信號產(chǎn)生, 定時(shí)器控制器將觸發(fā)EADC開始轉(zhuǎn)換。
Timer0定時(shí)器控制器也提供定時(shí)器超時(shí)中斷來觸發(fā)觸摸按鍵(Touch-Key)的掃描,當(dāng)WKTKEN (TIMER0_CTL[17])被置1且芯片在Power-down模式,如果Timer0超時(shí)中斷信號產(chǎn)生, Timer0 控制器也會觸發(fā)觸摸按鍵(Touch-Key)的掃描. 在此功能模式下, timer0模塊時(shí)鐘源應(yīng)設(shè)置為內(nèi)部低速 內(nèi)部低速 RC 振 蕩器 (LIRC)的 10 kHz 時(shí)鐘 或者外部低速晶體 外部低速晶體 外部低速晶體 (LXT) 的32.768 kHz時(shí)
這一段時(shí)間真的太安逸了,思維都懶惰了,想當(dāng)初在大學(xué)時(shí)利用定時(shí)器就可以做個(gè)時(shí)鐘出來,現(xiàn)在居然一心只為了完成任務(wù),沒有了原有的項(xiàng)目熱情,以后一定要努力,絕不放過任何提升自己的機(jī)會。
最上面的程序是利用數(shù)碼管來進(jìn)行0到99的計(jì)數(shù),我覺得著呢有必要講一講數(shù)碼管的知識
數(shù)碼管的一種是半導(dǎo)體發(fā)光器件,數(shù)碼管可分為七段數(shù)碼管和八段數(shù)碼管,區(qū)別在于八段數(shù)碼管比七段數(shù)碼管多一個(gè)用于顯示小數(shù)點(diǎn)的發(fā)光二極管單元DP(decimal point),其基本單元是發(fā)光二極管。
共陰極和共陽極的表示方法看下文:
void Show_Seven_Segment(unsigned char no, unsigned char number)
{
SEG_A_OFF;
SEG_B_OFF;
SEG_C_OFF;
SEG_D_OFF;
SEG_E_OFF;
SEG_F_OFF;
SEG_G_OFF;
SEG_H_OFF;
SEG_CONTROL1_OFF;
SEG_CONTROL2_OFF;
switch(no)
{
//show 0
case 0:
SEG_A_ON;
SEG_B_ON;
SEG_C_ON;
SEG_D_ON;
SEG_E_ON;
SEG_F_ON;
break;
//show 1
case 1:
SEG_B_ON;
SEG_C_ON;
break;
//show 2
case 2:
SEG_A_ON;
SEG_B_ON;
SEG_G_ON;
SEG_E_ON;
SEG_D_ON;
break;
//show 3
case 3:
SEG_A_ON;
SEG_B_ON;
SEG_G_ON;
SEG_C_ON;
SEG_D_ON;
break;
//show 4
case 4:
SEG_F_ON;
SEG_B_ON;
SEG_G_ON;
SEG_C_ON;
break;
//show 5
case 5:
SEG_A_ON;
SEG_F_ON;
SEG_G_ON;
SEG_C_ON;
SEG_D_ON;
break;
//show 6
case 6:
SEG_A_ON;
SEG_F_ON;
SEG_E_ON;
SEG_G_ON;
SEG_C_ON;
SEG_D_ON;
break;
//show 7
case 7:
SEG_A_ON;
SEG_B_ON;
SEG_C_ON;
SEG_F_ON;
break;
//show 8
case 8:
SEG_A_ON;
SEG_B_ON;
SEG_C_ON;
SEG_D_ON;
SEG_E_ON;
SEG_F_ON;
SEG_G_ON;
break;
//show 9
case 9:
SEG_A_ON;
SEG_B_ON;
SEG_C_ON;
SEG_F_ON;
SEG_G_ON;
break;
}
switch(number)
{
case 1:
SEG_CONTROL1_ON;
break;
//show 1
case 2:
SEG_CONTROL2_ON;
break;
}
}
M451則是這么表示的,其實(shí)是一樣的。
根據(jù)M451的定時(shí)器,我們可以計(jì)算出它的一些特點(diǎn),
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq) { uint32_t u32Clk = TIMER_GetModuleClock(timer); uint32_t u32Cmpr = 0, u32Prescale = 0; // Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, pre-scale = 0. //最快可能的定時(shí)器工作頻率是(u32Clk / 2)。 當(dāng)cmpr = 2時(shí),預(yù)標(biāo)度= 0。 if(u32Freq > (u32Clk / 2)) { u32Cmpr = 2; } else { if(u32Clk > 64000000) { u32Prescale = 7; // real prescaler value is 8 u32Clk >>= 3; } else if(u32Clk > 32000000) { u32Prescale = 3; // real prescaler value is 4 u32Clk >>= 2; } else if(u32Clk > 16000000) { u32Prescale = 1; // real prescaler value is 2 u32Clk >>= 1; } u32Cmpr = u32Clk / u32Freq; } timer->CTL = u32Mode | u32Prescale; timer->CMP = u32Cmpr; return(u32Clk / (u32Cmpr * (u32Prescale + 1))); }
uint32_t TIMER_GetModuleClock(TIMER_T *timer) { uint32_t u32Src; const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC}; if(timer == TIMER0) u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos; else if(timer == TIMER1) u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos; else if(timer == TIMER2) u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos; else // Timer 3 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos; if(u32Src == 2) { return (SystemCoreClock); } return (au32Clk[u32Src]); } 它是自動(dòng)選取時(shí)鐘源的。 不明白的話看一下寄存器是怎么寫的,對照一下。
printf("# Timer0 Settings:\n"); printf(" - Clock source is HXT \n"); printf(" - Time-out frequency is 1 Hz\n"); printf(" - Periodic mode \n"); printf(" - Interrupt enable \n"); printf("# Timer1 Settings:\n"); printf(" - Clock source is HCLK \n"); printf(" - Time-out frequency is 2 Hz\n"); printf(" - Periodic mode \n"); printf(" - Interrupt enable \n"); printf("# Timer2 Settings:\n"); printf(" - Clock source is HIRC \n"); printf(" - Time-out frequency is 4 Hz\n"); printf(" - Periodic mode \n"); printf(" - Interrupt enable \n"); printf("# Timer3 Settings:\n"); printf(" - Clock source is HXT \n"); printf(" - Time-out frequency is 8 Hz\n"); printf(" - Periodic mode \n"); printf(" - Interrupt enable \n"); printf("# Check Timer0 ~ Timer3 interrupt counts are reasonable or not.\n\n"); /* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */ TIMER0->CMP = __HXT; TIMER0->CTL = TIMER_CTL_INTEN_Msk | TIMER_PERIODIC_MODE; TIMER_SET_PRESCALE_VALUE(TIMER0, 0); /* Open Timer1 in periodic mode, enable interrupt and 2 interrupt ticks per second */ TIMER1->CMP = ((SystemCoreClock / 4) / 2); TIMER1->CTL = TIMER_CTL_INTEN_Msk | TIMER_PERIODIC_MODE; TIMER_SET_PRESCALE_VALUE(TIMER1, 3); /* Open Timer2 in periodic mode, enable interrupt and 4 interrupt ticks per second */ TIMER2->CMP = ((__HIRC / 1) / 4); TIMER2->CTL = TIMER_CTL_INTEN_Msk | TIMER_PERIODIC_MODE; TIMER_SET_PRESCALE_VALUE(TIMER2, 0); /* Open Timer3 in periodic mode, enable interrupt and 8 interrupt ticks per second */ TIMER3->CMP = ((__HXT / 1) / 8); TIMER3->CTL = TIMER_CTL_INTEN_Msk | TIMER_PERIODIC_MODE; TIMER_SET_PRESCALE_VALUE(TIMER3, 0); /* Enable Timer0 ~ Timer3 NVIC */ NVIC_EnableIRQ(TMR0_IRQn); NVIC_EnableIRQ(TMR1_IRQn); NVIC_EnableIRQ(TMR2_IRQn); NVIC_EnableIRQ(TMR3_IRQn); /* Clear Timer0 ~ Timer3 interrupt counts to 0 */ g_au32TMRINTCount[0] = g_au32TMRINTCount[1] = g_au32TMRINTCount[2] = g_au32TMRINTCount[3] = 0; u32InitCount = g_au32TMRINTCount[0]; /* Start Timer0 ~ Timer3 counting */ TIMER_Start(TIMER0); TIMER_Start(TIMER1); TIMER_Start(TIMER2); TIMER_Start(TIMER3); /* Check Timer0 ~ Timer3 interrupt counts */ printf("# Timer interrupt counts :\n");
附一張時(shí)鐘源的選擇
/****************************************************************************** * @file main.c * @version V1.00 * $Revision: 4 $ * $Date: 15/09/02 10:03a $ * @brief NuEdu Basic01 Timer Sample Code * @note * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include <stdio.h> #include "M451Series.h" #include "NuEdu-Basic01.h" /*---------------------------------------------------------------------------------------------------------*/ /* TMR0 IRQ handler */ /*---------------------------------------------------------------------------------------------------------*/ uint32_t volatile TimerCounter = 0; void GPD_IRQHandler(void) { /* To check if PC.5 interrupt occurred */ if(GPIO_GET_INT_FLAG(PD, BIT3)) { Write_Buzzer(0,0,0); } // else // { // /* Un-expected interrupt. Just clear all PC interrupts */ // PC->INTSRC = PC->INTSRC; // printf("Un-expected interrupts.\n"); // } } void TMR0_IRQHandler(void) { TimerCounter == 99 ? (TimerCounter = 0) : (TimerCounter++); // clear Timer0 interrupt flag if(Get_Key_Input()&0x01) { TimerCounter++; Show_Seven_Segment(TimerCounter / 10, 1); //CLK_SysTickDelay(200); Show_Seven_Segment(TimerCounter % 10, 2); //CLK_SysTickDelay(200); } if(Get_Key_Input()&0x02) { TimerCounter--; Show_Seven_Segment(TimerCounter / 10, 1); //CLK_SysTickDelay(200); Show_Seven_Segment(TimerCounter % 10, 2); //CLK_SysTickDelay(200); } TIMER_ClearIntFlag(TIMER0); } /*---------------------------------------------------------------------------------------------------------*/ /* MAIN function */ /*---------------------------------------------------------------------------------------------------------*/ int main(void) { int i=125; //Initial System SYS_Init(); /* Configure PD.3 as Quasi-bidirection mode and enable interrupt by falling edge trigger */ PD->MODE = (PD->MODE & (~GPIO_MODE_MODE3_Msk)) | (GPIO_MODE_QUASI << GPIO_MODE_MODE3_Pos); //Enable Timer0 clock and select Timer0 clock source CLK_EnableModuleClock(TMR0_MODULE); CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0); PD->INTTYPE |= (GPIO_INTTYPE_LEVEL << GPIO_INTTYPE_TYPE3_Pos); PD->INTEN |= GPIO_INTEN_FLIEN3_Msk; NVIC_EnableIRQ(GPD_IRQn); //Initial Timer0 to periodic mode with 2Hz TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 2); //Enable Timer0 interrupt TIMER_EnableInt(TIMER0); NVIC_EnableIRQ(TMR0_IRQn); Open_Buzzer(); //Initial 7-Segment Open_Seven_Segment(); Initial_Key_Input(); //Start Timer0 TIMER_Start(TIMER0); while(1) { /* Configure PC.5 as Quasi-bidirection mode and enable interrupt by falling edge trigger */ if(Get_Key_Input()&0x04) { Write_Buzzer(1, 250,i++); } if(Get_Key_Input()&0x08) { Write_Buzzer(1, 250,i--); } Show_Seven_Segment(TimerCounter / 10, 1); CLK_SysTickDelay(200); Show_Seven_Segment(TimerCounter % 10, 2); CLK_SysTickDelay(200); if(TimerCounter==50) { Write_Buzzer(1, 250,70); } } } /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/
這部分需要我認(rèn)真調(diào)試,觀察,有一些不對的地方
下一篇:C語言while語句
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08