回首頁   上一頁   通用輸出入控制    異常向量與外部中斷控制   計時器控制

 串列埠UART控制    串列埠SPI控制    串列埠I2C控制    RTC控制控制    FLASH記憶體控制    uCOS-II系統程式

計時器延時實習                計時中斷實習                                 計時匹配輸出實習 

計時匹配中斷輸出實習  計時匹配輸出及捕捉器輸入實習  光學編碼器中斷實習 

PWM單邊緣輸出實習    PWM雙邊緣輸出實習                    PWM中斷輸出實習 

PWM類比三角波輸出實習 PWM直流馬達控制實習            看門狗計時器WDT實習

/***********************計時器延時範例******************************
*檔名︰TIMER1.C
*功能︰使用Timer0設定0.5秒計時,控制LED1閃爍。
*模擬:開啟Timer0視窗,單步執行觀察MR0暫存器的變化
* 開啟GPIO或Logic Analyzer視窗,快速執行觀察輸出及時間的變化
*********************************************************************/
#include "LPC2106.h"
void main(void)
{
IODIR =LED1; // 設定LED1為輸出
PCONP=PCTIM0; // PCTIM0=1,致能Timer0工作
T0PR = 0; // 設定預除倍數=PR+1=1,tclk=pclk
T0MCR = MR0Int+MR0Res; // MR0Int=1,致能當T0TC=T0MR0時,會產生中斷
// MR0Res=1,當T0TC=T0MR0時,會重置T0TC=0
T0MR0 = Fpclk * 0.5; // 匹配時間=0.5秒
T0TCR = CntRes; // CntRes=1,重置T0TC=0
T0TCR = CntEn; // CntEn=1,致能T0TC開始計數
while(1)
{
while((T0IR & MR0) == 0); // 等待T0TC=T0MR0,MR0計時中斷旗標=1
T0IR = MR0; // 清除MR0中斷旗標
if((IOSET & LED1) == 0) IOSET = LED1; // 反相令LED1=1
else IOCLR = LED1; // 反相令LED1=0
}
}

/*********************計時中斷範例 ************************
*檔名︰TIMER2.C
*功能︰使用Timer0設定延時中斷,控制LED1-4輪流閃爍及輸出步進馬達控制信號
*模擬:開啟Timer0視窗,單步執行觀察MR0-3暫存器的變化
* 開啟GPIO或Logic Analyzer視窗,快速執行觀察輸出及時間的變化
****************************************************************/
#include "LPC2106.h"
/*************************************************************
** 函數名稱: IRQ_Timer0
** 功能描述: 中斷異常處理程式,Timer0匹配時間中斷,令LED1-4輪流閃爍
**************************************************************/
void IRQ_Timer0(void) __irq
{
if(T0IR & MR0) // 若T0TC=T0MR0=0.25秒,計時中斷旗標=1
{
IOCLR=LED1+LED2+LED3+LED4;IOSET=LED2;// 僅LED2=1
T0IR = MR0; // 清除MR0中斷旗標
}
if(T0IR & MR1) // 若T0TC=T0MR1=0.5秒,MR1計時中斷旗標=1
{
IOCLR=LED1+LED2+LED3+LED4;IOSET=LED3;// 僅LED3=1
T0IR = MR1; // 清除MR1中斷旗標
}
if(T0IR & MR2) // 若T0TC=T0MR2=0.75秒,MR2計時中斷旗標=1
{ IOCLR=LED1+LED2+LED3+LED4;IOSET=LED4;// 僅LED4=1
T0IR = MR2; // 清除MR2中斷旗標
}
if(T0IR & MR3) // 若T0TC=T0MR3=1秒,MR3計時中斷旗標=1
{ IOCLR=LED1+LED2+LED3+LED4;IOSET=LED1;// 僅LED1=1
T0IR = MR3; // 清除MR3中斷旗標
}
VICVectAddr = 0x00; // 通知VIC中斷處理結束
}
//*********************************************************************************
void main(void)
{
IODIR=IOCLR=LED1+LED2+LED3+LED4; // 設定LED1-4為輸出0
IOSET=LED1; // LED1=1
PCONP=PCTIM0; //PCTIM0=1,致能Timer 0工作
T0PR = 0; // 設定預除倍數=PR+1=1
T0MCR =MR0Int+MR1Int+MR2Int+MR3Int+MR3Res;
// MR0Int=1,致能當T0TC=T0MR0時,會產生中斷
// MR1Int=1,致能當T0TC=T0MR1時,會產生中斷
// MR2Int=1,致能當T0TC=T0MR2時,會產生中斷
// MR3Int=1,致能當T0TC=T0MR3時,會產生中斷
// MR3Res=1,當T0TC=T0MR3時,重置T0TC=0
T0MR0 = Fpclk * 0.25; // MR0匹配時間=0.25秒
T0MR1 = Fpclk * 0.5; // MR1匹配時間=0.5秒
T0MR2 = Fpclk * 0.75; // MR2匹配時間=0.75秒
T0MR3 = Fpclk; // MR3匹配時間=1秒

T0TCR = CntRes; // CntRes=1,重置T0TC
T0TCR = CntEn; // CntEn=1,致能T0TC開始計數

/* 設定Timer0中斷IRQ */
VICIntSelect = 0x00; // 所有中斷通道設定為IRQ中斷
VICVectCntl0 = CntlTimer0; // Timer0中斷通道為最高優先
VICVectAddr0 = (uint32)IRQ_Timer0; // 設定Timer0中斷服務程式位址
VICIntEnable = IntTimer0; // 致能Timer0中斷
while(1); // 空轉,等待Timer0中斷
}

      圖. 計時器中斷延時範例輸出波形

 

/*********************計時匹配輸出範例 **************************
*檔名︰MATCH1.C
*功能︰使用Timer1設定0.5秒匹配輸出,令MAT1.0(P12)腳反相輸出1Hz方波
*模擬:開啟Timer1及Logic Analyzer視窗,快速執行觀察MAT1.0及暫存器變化
**************************************************************************/
#include "LPC2106.h"
int main(void)
{
PINSEL0 = MAT10; // 設定匹配輸出腳MAT1.0
PCONP=PCTIM1; // PCTIM1=1,致能Timer 1工作
T1PR = 0; // 設定Timer1預除倍數=T1PR+1=1
T1MR0 = Fpclk * 0.5;// MR0匹配時間=0.5秒,同時令T1TC=0
T1MCR = MR0Res; // MR0Res=1,當T1TC=T1MR0時,會令T1TC=0
T1EMR = 0x30; // 0011 0000 匹配接腳輸出設定
// bit5:4=11,T1TC=T1MR0時,MAT1.0腳反相輸出

T1TCR = CntRes; // CntRes=1,重置T1TC
T1TCR = CntEn; // CntEn=1, 致能T1TC開始計數
while(1); // 空轉,表示可作其它工作,此時Timer1匹配輸出
}

    圖 計時匹配輸出範例輸出波形

 

/*********************計時匹配中斷輸出範例 **************************
*檔名:MATCH3.C
*功能:Timer1匹配中斷輸出,控制MAT1.0(P12)閃爍5次後,暫停1秒,再重覆。
*模擬:開啟Timer1及Logic Analyzer視窗,快速執行觀察MAT1.0輸出及暫存器變化
**************************************************************************/
#include "LPC2106.h"
uint8 count=10; // 設定中斷10次,每閃爍一次,會產生兩次中斷,故為閃爍5次
/*********************************************************************
** 函數名稱: IRQ_Timer1
** 功能描述: 控制MAT1.0(P12)閃爍5次後,暫停2秒,再重覆
*********************************************************************/
void IRQ_Timer1(void) __irq
{
count--; // 中斷次數-1
if(count==0)
{
T1TCR = 0x00; // CntE=0禁能T1TC計數
Delay_ms(1000); // 暫停1秒
count=10; // 重新設定中斷次數=10,閃爍5次
T1TCR = CntEn; // CntEn=1,啟動T1TC
}
T1IR = MR0; // MR0=1,清除MATCH0中斷旗標
VICVectAddr = 0x00; // 通知VIC中斷處理結束
}
//***************************************************************
void main(void)
{
PCONP = PCTIM1; // PCTIM1=1,致能Timer 1工作
PINSEL0 = MAT10;// 設定匹配輸出腳MAT1.0(P12)
T1PR = 0; // 設定Timer1預除倍數=T1PR+1=1

T1MR0 = Fpclk* 0.1;// MR0匹配時間=0.1秒
T1MCR = MR0Int+MR0Res; // MR0Int=1,當T1TC=T1MR0時,產生中斷
// MR0Res=1,當T1TC=T1MR0時,重置T1TC=0
T1EMR = 0x30; // 0011 0000
// bit5:4=11,T1TC=T1MR0,MAT1.0腳反相輸出

T1TCR = CntRes; // CntRes=1,重置T1TC=0
T1TCR = CntEn; // CntEn=1,致能T1TC開始計數

/* 設定Timer1中斷IRQ */
VICIntSelect = 0x00; // 所有中斷通道設定為IRQ中斷
VICVectCntl0 = CntlTimer1; // Timer1中斷通道為最高優先
VICVectAddr0 = (uint32)IRQ_Timer1; // 設定Timer1中斷服務程式位址
VICIntEnable = IntTimer1; // 致能Timer1中斷
while(1); // 空轉,表示可作其它工作,此時MAT1.0(P12)匹配輸出

}

/*********************計時匹配輸出及捕捉器輸入範例 **************************
*檔名︰CAP1.C
*功能︰使用Timer1令MAT1.0腳(P12)每10mS反相輸出方波
* 送到CAP0.0(P02)捕捉Timer0時間,由LCD顯示顯示時間。
*模擬:開啟Timer0-1視窗,快速執行,觀察CAP0暫存器及時間的變化
*接線︰將MAT1.0腳(P12)連接到CAP0.0(P02)。
* P22=LCD_RS,P23=LCD_EN ,P24-31=LCD_DATA,DBGSEL=0
*附加:IO.C
**************************************************************************/
#include "LPC2106.h"
uint8 const Table[]={"CAPTURE="}; // 第一行列表字元
void main(void)
{
uint8 i;
uint32 cap_old,cap_time; // 無符號32位整數變數
PINSEL0 = CAP00+MAT10; // 設定捕捉腳CAP0.0及匹配輸出腳MAT1.0
LCD_init(); // 啟始LCD工作

for(i=0 ; i< 8 ; i++) // 讀取列表"CAPTURE="字元
Send_Data(Table[i]); // 到LCD顯示出來

PCONP=PCTIM1+PCTIM0; // 致能週邊設備Timer 1-0工作

T1PR = 0; // 設定Timer1預除倍數=T1PR+1=1
T1MCR = MR0Res; // MR0Res=1,當T1TC=T1MR0時,會重置T1TC=0
T1MR0 = Fpclk*0.01; // T1MR0匹配時間=10mS,數值限0.001~0.3之間
T1EMR = 0x30; // 0011 0000 匹配接腳輸出設定
// bit5:4=11,T1TC=T1MR0時,MAT1.0腳反相輸出
T1TCR = CntRes; // 重置T1TC=0;
T1TCR = CntEn; // 致能T1TC開始計數
//-------------------------------------------------------------------------
T0PR = 0; // 設定Timer0預除倍數=T0PR+1=1
T0CCR = CAP0_ris+CAP0_fal+CAP0_event;
// CAP0_ris=1,當CAP0.0輸入正緣觸發時,捕捉T0TC時間-->CR0
// CAP0_fal=1,當CAP0.0輸入負緣觸發時,捕捉T0TC時間-->CR0
// CAP0_event=1,捕捉T0TC時間-->CR0 ,會產生中斷
T0TCR = CntRes; // CntRes=1,重置T0TC=0
T0TCR = CntEn; // CntEn=1,致能T0TC開始計數

while(1)
{
while((T0IR & CR0) == 0); // 等待CAP0.0捕捉時間到T0CR0,計時中斷旗標=1
T0IR=CR0; // CR0=1,清除捕捉通道CAP0中斷旗標
if(T0CR0 > cap_old) // 避免計數溢位時,會計算錯誤的頻率
{
cap_time=T0CR0-cap_old;//取兩次捕捉器的時間差
LCD_Cmd(0x88); // 由第一行第8字開始顯示
LCD_Disp((cap_time+1)*1000/Fpclk); // 半週期的時間差,以mS為單位由LCD顯示
Send_Data('m'); Send_Data('S'); // LCD後面顯示mS
}
cap_old=T0CR0; // 將新捕捉器時間存入舊捕捉時間
}
}

    圖. 計時捕捉器實習電路

 

       圖. 轉軸編碼器實習電路

 

/*********ENCODE1.C*****光學編碼器一倍數解析中斷範例程式*****************
*動作:ENCODE正轉或反轉,一倍數解析計數,由LCD顯示計數遞加或遞減
*功能︰Timer0令匹配輸出腳MAT0.0(P03)及MAT0.2(P16)模擬輸出encode的A/B相信號
ENCODE的A-B相由捕捉腳CAP1.0(P10)及P11輸入,在LCD顯示計數值及週期時間。
*模擬:開啟Timer0-1及Watch視窗,快速執行,在CAP1.0輸入觸發信號,觀察CAP0暫存器
* 及變數count的變化
*接線:由P03及P16輸出A-B相模擬信號,接到P10及P11輸入。
* 正向相接則上數,反向相接則下數。
****************************************************************/
#include "LPC2106.h"
uint8 const Table1[]={"Count="}; // 第一行列表字元
uint8 const Table2[]={"Time="}; // 第二行列表字元

uint32 count=123456; // LCD 6位數顯示初值
uint32 cap_old; // 捕捉的前一次時間
/*************************************************************
** 函數名稱: IRQ_CAP
** 功能描述: ENCODE的A-B相輸入一倍數解析計數,由LCD顯示計數
************************************************************/
void IRQ_CAP(void) __irq
{
uint32 cap_time; //兩次捕捉器的時間差

if(IOPIN & 0x800) count++; // 若P11=0,為正轉令count遞加
else count--; // 若P11=1 ,為反轉令count遞減

LCD_Cmd(0x86); // 游標由第一行第6字開始顯示
LCD_Disp(count); // 計數顯示

if(T1CR0 > cap_old) // 避免計數溢位時,會計算錯誤的頻率
{
cap_time=T1CR0-cap_old; //取兩次捕捉器的時間差
LCD_Cmd(0xC5); // 游標由第二行第5字開始顯示
LCD_Disp(cap_time/(Fpclk/1000)); // 以mS為單位顯示時間差
Send_Data('m'); Send_Data('S'); // LCD後面顯示mS
}

cap_old=T1CR0; // 將新捕捉器時間存入舊捕捉時間
T1IR=CR0; // CR0=1,清除捕捉通道CAP0中斷旗標
VICVectAddr = 0x00; // 通知VIC中斷處理結束
}
/*********************************************************************************
** 函數名稱: Init_MATCH
** 功能描述: 設定Timer0令匹配輸出腳MAT0.0(P03)及MAT0.2(P16)模擬輸出encode的A/B相信號
**********************************************************************************/
void Init_MATCH(void)
{
PINSEL0 = PINSEL0+MAT00;// 設定匹配輸出腳MAT0.0
PINSEL1 = PINSEL1+MAT02;// 設定匹配輸出腳MAT0.2
PCONP=PCTIM0; // 致能Timer0工作
T0PR = 0; // 設定Timer0預除倍數=T0PR+1=1
T0MCR = MR2Res; // MR2Res=1,當T0TC=T0MR2時,會重置T0TC=0
T0MR0 = Fpclk * 0.05; // MR0匹配時間=0.05秒
T0MR2 = Fpclk * 0.1; // MR2匹配時間=0.1秒反相,週期時間=0.2秒
T0EMR = 0x330; // 1111 0000 匹配接腳輸出設定
// bit5:4=11,T0TC=T0MR0時,MAT0.0(P03)腳反相輸出
// bit9:8=11,T0TC=T0MR2時,MAT0.2(P16)腳反相輸出
T0TCR = CntRes; // 重置T0TC=0
T0TCR = CntEn; // 致能T0TC開始計數
}
/*********************************************************************************
** 函數名稱: Init_CAP
** 功能描述: 設定Timer1由捕捉腳CAP1.0(P10)中斷輸入ENCODE信號。
**********************************************************************************/
void Init_CAP(void)
{
PINSEL0 = PINSEL0+CAP10;// 設定捕捉腳CAP1.0
PCONP=PCONP+PCTIM1; // 增加致能Timer 1工作
T1PR = 0; // 設定Timer1預除倍數=T1PR+1=1
T1CCR =CAP0_fal+CAP0_event;
// CAP0_fal=1,CAP1.0輸入負緣觸發
// CAP0_event=1,CAP1.0輸入負緣觸發,會產生中斷
T1TCR = CntRes; // 重置T1TC=0;
T1TCR = CntEn; // 致能T1TC開始計數

/* 設定Timer1中斷IRQ */
VICIntSelect = 0x00; // 所有中斷通道設定為IRQ中斷
VICVectCntl0 = CntlTimer1; // Timer1中斷通道為最高優先
VICVectAddr0 = (uint32)IRQ_CAP;// 設定中斷服務程式位址
VICIntEnable = IntTimer1; // 致能Timer1中斷
}
//**************************************************************
void main(void)
{
uint8 i;
LCD_init(); // 啟始LCD工作
for(i=0 ; i< 8 ; i++) // 讀取列表"count="字元
Send_Data(Table1[i]); // 到LCD顯示出來

LCD_Cmd(0xC0);
for(i=0 ; i< 8 ; i++) // 讀取列表"Time="字元
Send_Data(Table2[i]); // 到LCD顯示出來

Init_MATCH(); // 設定計時匹配輸出
Init_CAP(); // 設定捕捉器中斷輸入
while(1) ; // 空轉,等待捕捉器中斷輸入
}

/**********************PWM單邊緣輸出範例*********************************
*檔名︰PWM1.C
*功能︰設定PWMMR0週期頻率=Fpclk/(Fpclk/10000)=10KHz,
* 令PWM1-6單邊緣輸出不同脈波寬度的PWM波形,
*模擬:開啟PWM視窗,單步執行觀察PWM1-6輸出及暫存器變化
*操作:可使用示波器量測波形、用三用電錶量測直流電壓,或控制LED的亮度
*******************************************************************/
#include "LPC2106.h"
void main(void)
{
PINSEL0 = PWM1+PWM2+PWM3+PWM4+PWM6; // 設定PWM1-4,PWM6接腳
PINSEL1 = PWM5; // 設定PWM5接腳

PCONP=PCPWM; // PCPWM=1,致能PWM工作
PWMPR = 0; // 預除倍數PR+1=1
PWMMCR = PWM0Res; // 設定PWMTC=PWMMR0時,重置PWMTC=0
PWMMR0 = Fpclk/1000; // 設定PWM週期頻率=Fpclk/(Fpclk/1000)=1KHz

PWMMR1 = PWMMR0 * 0.1; // PWM1(P00)脈波時間,DCV=3.3V*0.1=0.33V
PWMMR2 = PWMMR0 * 0.2; // PWM2(P07)脈波時間,DCV=3.3V*0.2=0.66V
PWMMR3 = PWMMR0 * 0.4; // PWM3(P01)脈波時間,DCV=3.3V*0.4=0.55V
PWMMR4 = PWMMR0 * 0.6; // PWM4(P08)脈波時間,DCV=3.3V*0.6=1.98V
PWMMR5 = PWMMR0 * 0.8; // PWM5(P21)脈波時間,DCV=3.3V*0.8=2.64V
PWMMR6 = PWMMR0 * 0.9; // PWM6(P09)脈波時間,DCV=3.3V*0.9=2.97V
// 致能PWMMR0-6寫入鎖住
PWMLER = PWM0LE+PWM1LE+PWM2LE+PWM3LE+PWM4LE+PWM5LE+PWM6LE;
// 致能PWM1-6為單邊緣輸出
PWMPCR = PWM1En+PWM2En+PWM3En+PWM4En+PWM5En+PWM6En;
PWMTCR = PWMEn+CntEn; // 致能PWM輸出及致能PWM計時器
while(1); // 空轉,輸出PWM波形
}

       圖.  PWM1-6單邊緣輸出波形

 

/**********************PWM雙邊緣輸出範例*********************************
*檔名︰PWM2.C
*功能︰設定PWMMR0週期頻率=Fpclk/(Fpclk/10000)=10KHz,
* 令PWM2、4、6雙邊緣輸出三相PWM波形,
*模擬:開啟PWM視窗,單步執行觀察PWM1-6輸出及暫存器變化
*操作:可使用示波器量測波形
*******************************************************************/
#include "LPC2106.h"
void main(void)
{
PINSEL0 = PWM2+PWM4+PWM6;// 設定PWM2、4、6接腳

PCONP=PCPWM; // PCPWM=1,致能PWM工作
PWMPR = 0; // 預除倍數PR+1=1
PWMMCR = PWM0Res; // 設定PWMTC=PWMMR0時,重置PWMTC=0
PWMMR0 = Fpclk/1000; // 設定PWM週期頻率=Fpclk/(Fpclk/1000)=1KHz

PWMMR1 = PWMMR0 * 0.1; // PWM2(P07)脈波時間= 0.1~ 0.3
PWMMR2 = PWMMR0 * 0.3;

PWMMR3 = PWMMR0 * 0.4; // PWM4(P08)脈波時間= 0.3~ 0.6
PWMMR4 = PWMMR0 * 0.6;

PWMMR5 = PWMMR0 * 0.7; // PWM6(P09)脈波時間= 0.7~0.9
PWMMR6 = PWMMR0 * 0.9;

 PWMLER = PWM0LE+PWM1LE+PWM2LE+PWM3LE+PWM4LE+PWM5LE+PWM6LE;
// 致能PWM6、4、2為雙邊緣輸出
PWMPCR =PWM6En+PWM4En+PWM2En+PWM6Sel+PWM4Sel+PWM2Sel;

PWMTCR = PWMEn+CntEn; // 致能PWM輸出及致能PWM計時器
while(1); // 空轉,輸出PWM波形
}

      圖 雙邊緣輸出波形

 


// 致能PWMMR0-6寫入鎖住/**********************PWM中斷輸出範例***************************************
*檔名︰PWM3.C
*動作:PWM6連續輸出1000個方波,停止輸出一段時間後再重覆,形成1KHz嗶嗶聲
*模擬:開啟PWM視窗,單步執行觀察PWM0及PWM6輸出及暫存器變化
開啟WATCH#1視窗,快速執行觀察變數COUNT及時間的變化
*操作:PWM6(P09)接喇叭或使用示波器量測PWM6的輸出波形。
*************************************************************************/
#include "LPC2106.h"
uint16 COUNT=1000; // PWM重覆1000次,令嗶聲時間=1秒
/*************************************************************
** 函數名稱: IRQ_PWM
** 功能描述: 中斷異常處理程式,PWM0中斷,PWM6重覆1000次,令嗶聲時間=1秒
**************************************************************/
void IRQ_PWM(void) __irq
{
COUNT--; // PWM0重覆次數-1
if (COUNT==0) // 若PWM0重覆次數=0,則停止PWM6輸出
{
PCONP=0; // PCPWM=0,禁能PWM工作
Delay_ms(500); // 嗶聲間隔時間
COUNT=1000; // 重新設定嗶聲時間=1秒
PCONP=PCPWM; // PCPWM=1,致能PWM工作
}
PWMIR=PWM0F; // 清除PWM0中斷旗標
VICVectAddr = 0x00; // 通知VIC中斷處理結束
}
//*********************************************************************************
void main(void)
{
PINSEL0 = PWM6; // 設定PWM6接腳
PCONP = PCPWM; // PCPWM=1,致能PWM工作
PWMPR = 0; // 預除倍數PR+1=1
PWMMCR = PWM0Res+PWM0Int; // 設定若PWMTC=PWMMR0,重置PWMTC=0及產生中斷
PWMMR0 = Fpclk/1000; // 設定PWM週期頻率=Fpclk/(Fpclk/1000)=1KHz
PWMMR6 = PWMMR0*0.5; // PWM6脈波時間,輸出對稱方波
PWMLER = PWM0LE+PWM6LE; // 致能PWM0及PWM6寫入鎖住
PWMPCR = PWM6En; // 致能PWM6單邊緣輸出
PWMTCR = PWMEn+CntEn; // 致能PWM輸出及致能PWM計時器
PWMIR=PWM0F; // 清除PWM0中斷旗標
/* 設定PWM中斷IRQ */
VICIntSelect = 0x00; // 所有中斷通道設定為IRQ中斷
VICVectCntl0 = CntlPWM; // PWM中斷通道為最高優先
VICVectAddr0 = (uint32)IRQ_PWM; // 設定中斷服務程式位址
VICIntEnable = IntPWM; // 致能PWM中斷
while(1); // 空轉,等待PWM中斷
}

        .  PWM類比輸出

 

/**********************PWM類比三角波輸出範例*****************************
*檔名︰PWMDAC1.C
*功能︰控制PWMMR6的脈波寬度,並令PWM6經RC電路輸出三角波
*計算:設定PWMMR0為週期頻率=Fpclk/(Fpclk/1000)=1KHz,
*模擬:開啟PWM視窗,快速執行觀察PWM6輸出及暫存器變化
*操作:將PWM6接LED或喇叭觀察其輸出,或使用示波器觀察PWM6波形及三用電錶量測PWMDAC。
*************************************************************************/
#include "LPC2106.h"
void main(void)
{
uint16 PWMDAC; // 定義DAC變數及設PWM初值
PINSEL0=PWM6; // 設定PWM6(P09)接腳輸出
PCONP=PCPWM; // PCPWM=1,致能PWM工作
PWMPR = 0; // 預除倍數PR+1=1
PWMMCR = PWM0Res; // 設定若PWMTC=PWMMR0,重置PWMTC=0
PWMMR0 = Fpclk/1000; // 設定PWM週期頻率=1KHz
PWMMR6 = 0; // 設定PWM脈波時間為0
PWMLER = PWM6LE+PWM0LE; // PWMMR6、PWMMR0鎖住
PWMPCR = PWM6En; // PWM6En=1, 致能PWM6輸出單邊PWM
PWMTCR = PWMEn+CntEn; // 致能PWM輸出及致能PWM計時器
while(1)
{
for(PWMDAC=0;PWMDAC<PWMMR0;PWMDAC++) //脈波寬度遞加
{
PWMMR6=PWMDAC; // 設定脈波寬度
PWMLER=PWM6LE; // 允許PWMMR6寫入及鎖住
Delay_ms(1); // 間隔延時
}
for(PWMDAC=PWMMR0;PWMDAC>0;PWMDAC--) //脈波寬度遞減
{
PWMMR6=PWMDAC; // 設定脈波寬度
PWMLER=PWM6LE; // 允許PWMMR6寫入及鎖住
Delay_ms(1); // 間隔延時
}
}
}

        兩軸直流馬達工作電路圖

 

/**********************PWM直流馬達控制範例*****************************
*檔名︰MOTOR.C
*功能︰PWM2(P07)及PWM4(P08)輪流輸出脈波,控制直流馬達的正反轉及加減速
*操作:使用三用電錶量測直流馬達兩端,觀察DCV的變化。
*************************************************************************/
#include "LPC2106.h"
void main(void)
{
uint16 i;
PINSEL0=PWM2+PWM4; // 設定PWM2及PWM4接腳
PCONP=PCPWM; // PCPWM=1,致能PWM工作
PWMPR = 0; // 預除倍數PR+1=1
PWMMCR = PWM0Res; // 設定若PWMTC=PWMMR0,重置PWMTC=0
PWMMR0 = Fpclk/1000; // 設定PWM週期頻率=1KHz

PWMPCR = PWM2En+PWM4En; // 致能PWM2及PWM4輸出單邊PWM
PWMTCR = PWMEn+CntEn; // 致能PWM輸出及致能PWM計時器
while(1)
{
PWMMR2=PWMMR4=0;PWMLER=PWM2LE+PWM4LE; //停止運轉
for(i=1000;i<PWMMR0;i=i+10) //脈波寬度遞加,正轉加速
{
PWMMR2=i; // 設定脈波寬度
PWMLER=PWM2LE; // 允許PWMMR2寫入及鎖住
Delay_ms(10); // 間隔延時
}
for(i=PWMMR0;i>1000;i=i-10) //脈波寬度遞減,正轉減速
{
PWMMR2=i; // 設定脈波寬度
PWMLER=PWM2LE; // 允許PWMMR2寫入及鎖住
Delay_ms(10); // 間隔延時
}

//--------------------------------------------------------------
PWMMR2=PWMMR4=0; PWMLER=PWM2LE+PWM4LE; //停止運轉
for(i=1000;i<PWMMR0;i=i+10) //脈波寬度遞加,反轉加速
{
PWMMR4=i; // 設定脈波寬度
PWMLER=PWM4LE; // 允許PWMMR4寫入及鎖住
Delay_ms(10); // 間隔延時
}

for(i=PWMMR0;i>1000;i=i-10) //脈波寬度遞減,反轉減速
{
PWMMR4=i; // 設定脈波寬度
PWMLER=PWM4LE; // 允許PWMMR4寫入及鎖住
Delay_ms(10); // 間隔延時
}
}

}

/***********************看門狗計時器WDT範例****************************
*檔名︰WDT.C
*功能︰LED4-1遞加顯示,若延時超過1秒,來不及清除看門狗計時器,會令系統硬體重置。
*模擬:開啟Watchdog視窗,快速執行,觀察暫存器及時間的變化
****************************************************************************/
#include "LPC2106.h"

void RSTWDT(void) // 重置看門狗計時器
{
WDFEED=0xAA;
WDFEED=0x55;
}
//*************************************************************************
void WDT_Init(void) // 設定並啟動WDT
{
WDTC=Fpclk/4; // 設定WDTC時間=Fpclk/4/(Fpclk/4)=1Hz=1秒
WDMOD=WDEN + WDRESET; // 設定WDT工作模式為致能中斷及重置
RSTWDT(); // 重置看門狗計時器
}
//*************************************************************************
void main(void)
{
uint8 i; // 宣告無符號8-bit變數
IODIR = LED4+LED3+LED2+LED1; // 設定接腳LED4-1為輸出
WDT_Init(); // 設定及啟動WDT
while(1)
{
for (i=0;i<16;i++)
{
IOCLR = LED4+LED3+LED2+LED1; // LED4-1=0000
IOSET = i<<10; // 變數i由LED4-1輸出
Delay_ms(1200); // 延時若超過1秒,會令程式進入系統重置
RSTWDT(); // 必須在WDT時間內,重置看門狗計時器
}
}
}