在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            s3c2440的PWM應(yīng)用

            作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
            PWM(Pulse Width Modulation)——脈寬調(diào)制,它是利用微控制器的數(shù)字輸出來對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用于測(cè)量、通信、功率控制與變換等許多領(lǐng)域。

            s3c2440芯片中一共有5個(gè)16位的定時(shí)器,其中有4個(gè)定時(shí)器(定時(shí)器0~定時(shí)器3)具有脈寬調(diào)制功能,因此用s3c2440可以很容易地實(shí)現(xiàn)PWM功能。下面就具體介紹如何實(shí)現(xiàn)PWM功能。

            1、PWM是通過引腳TOUT0~TOUT3輸出的,而這4個(gè)引腳是與GPB0~GPB3復(fù)用的,因此要實(shí)現(xiàn)PWM功能首先要把相應(yīng)的引腳配置成TOUT輸出。

            2、再設(shè)置定時(shí)器的輸出時(shí)鐘頻率,它是以PCLK為基準(zhǔn),再除以用寄存器TCFG0配置的prescaler參數(shù),和用寄存器TCFG1配置的divider參數(shù)。

            3、然后設(shè)置脈沖的具體寬度,它的基本原理是通過寄存器TCNTBn來對(duì)寄存器TCNTn(內(nèi)部寄存器)進(jìn)行配置計(jì)數(shù),TCNTn是遞減的,如果減到零,則它又會(huì)重新裝載TCNTBn里的數(shù),重新開始計(jì)數(shù),而寄存器TCMPBn作為比較寄存器與計(jì)數(shù)值進(jìn)行比較,當(dāng)TCNTn等于TCMPBn時(shí),TOUTn輸出的電平會(huì)翻轉(zhuǎn),而當(dāng)TCNTn減為零時(shí),電平會(huì)又翻轉(zhuǎn)過來,就這樣周而復(fù)始。因此這一步的關(guān)鍵是設(shè)置寄存器TCNTBn和TCMPBn,前者可以確定一個(gè)計(jì)數(shù)周期的時(shí)間長(zhǎng)度,而后者可以確定方波的占空比。由于s3c2440的定時(shí)器具有雙緩存,因此可以在定時(shí)器運(yùn)行的狀態(tài)下,改變這兩個(gè)寄存器的值,它會(huì)在下個(gè)周期開始有效。

            4、最后就是對(duì)PWM的控制,它是通過寄存器TCON來實(shí)現(xiàn)的,一般來說每個(gè)定時(shí)器主要有4個(gè)位要配置(定時(shí)器0多一個(gè)死區(qū)位):?jiǎn)?dòng)/終止位,用于啟動(dòng)和終止定時(shí)器;手動(dòng)更新位,用于手動(dòng)更新TCNTBn和TCMPBn,這里要注意的是在開始定時(shí)時(shí),一定要把這位清零,否則是不能開啟定時(shí)器的;輸出反轉(zhuǎn)位,用于改變輸出的電平方向,使原先是高電平輸出的變?yōu)榈碗娖剑碗娖降淖優(yōu)楦唠娖?;自?dòng)重載位,用于TCNTn減為零后重載TCNTBn里的值,當(dāng)不想計(jì)數(shù)了,可以使自動(dòng)重載無效,這樣在TCNTn減為零后,不會(huì)有新的數(shù)加載給它,那么TOUTn輸出會(huì)始終保持一個(gè)電平(輸出反轉(zhuǎn)位為0時(shí),是高電平輸出;輸出反轉(zhuǎn)位為1時(shí),是低電平輸出),這樣就沒有PWM功能了,因此這一位可以用于停止PWM。

            PWM有很多用途,在這里我利用開發(fā)板的資源,用它來驅(qū)動(dòng)蜂鳴器,并通過改變脈寬來改變蜂鳴器發(fā)聲的頻率。下面的程序就是利用PWM來驅(qū)動(dòng)蜂鳴器,脈寬從低到高,再從高到低,周而復(fù)始。我們還利用4個(gè)LED來指示頻率的高低,最高時(shí)LED全亮,最低時(shí)LED全滅。并且我們用兩個(gè)按鈕來分別暫停蜂鳴器和重新開啟蜂鳴器:

            #define _ISR_STARTADDRESS 0x33ffff00

            #define U32 unsigned int
            typedef unsigned char BOOL;
            #define TRUE1
            #define FALSE0

            #define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20))
            #define pISR_EINT1(*(unsigned *)(_ISR_STARTADDRESS+0x24))

            #define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt request status
            #define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
            #define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status

            #define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
            #define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
            #define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

            #define rGPFCON(*(volatile unsigned *)0x56000050)//Port F control

            #define rEXTINT0(*(volatile unsigned *)0x56000088)//External interrupt control register 0

            #define rTCFG0(*(volatile unsigned *)0x51000000)//Timerconfiguration
            #define rTCFG1(*(volatile unsigned *)0x51000004)//Timerconfiguration
            #define rTCON(*(volatile unsigned *)0x51000008)//Timer control
            #define rTCNTB0 (*(volatile unsigned *)0x5100000c)//Timer count buffer 0
            #define rTCMPB0 (*(volatile unsigned *)0x51000010)//Timer compare buffer 0

            BOOL stop;

            static void __irq Key1_ISR(void)//暫停鍵,關(guān)閉蜂鳴器
            {
            rSRCPND = rSRCPND | (0x1<<1);
            rINTPND = rINTPND | (0x1<<1);

            rTCON &= ~0x8;//禁止定時(shí)器自動(dòng)重載,即關(guān)閉定時(shí)器
            stop = TRUE;
            }

            void __irq Key4_ISR(void)//重啟鍵,開啟蜂鳴器
            {
            rSRCPND = rSRCPND | 0x1;
            rINTPND = rINTPND | 0x1;

            stop = FALSE;
            }


            void delay(int a)
            {
            int k;
            for(k=0;k;
            }

            void Main(void)
            {
            int freq;

            rGPBCON = 0x155556;//B0為TOUT0,B5~B8為輸出,給LED
            rGPBUP= 0x7ff;
            rGPFCON = 0xaaaa;//F口為EINT,給按鈕
            //按鈕的一些必要配置
            rSRCPND = 0x07;
            rINTMSK = ~0x07;
            rINTPND =0x07;
            rEXTINT0 = 0x22;

            freq = 2500;

            rTCFG0 &= 0xFFFF00;
            rTCFG0 |= 0x31;//prescal是49
            rTCFG1 &= ~0xF;//1/2,因?yàn)镻CLK為50MHz,所以50MHz/50/2=500kHz
            rTCNTB0 = 5000;
            rTCMPB0 = freq;
            rTCON &= ~0x1F;
            rTCON |= 0xf;//死區(qū)無效,自動(dòng)裝載,電平反轉(zhuǎn),手動(dòng)更新,定時(shí)器開啟
            rTCON &= ~0x2 ;//手動(dòng)更新位清零,PWM開始工作

            pISR_EINT0 = (U32)Key4_ISR;
            pISR_EINT1 = (U32)Key1_ISR;

            stop = FALSE;

            rGPBDAT = ~0x60;//兩個(gè)LED亮

            while(1)
            {
            //頻率遞增
            for ( ; freq<4950 ; )
            {
            freq+=10;
            rTCMPB0 = freq;//重新賦值
            delay(20000);

            while (stop == TRUE)//暫停
            {
            delay(1000);
            if (stop ==FALSE)//判斷是否重啟
            {
            rTCON &= ~0x1F;
            rTCON |= 0xf;
            rTCON &= ~0x2 ;//恢復(fù)PWM功能
            }
            }
            //4個(gè)LED隨著頻率的高低,時(shí)滅時(shí)亮
            if(freq == 100)
            rGPBDAT = ~0x1e0;
            if(freq == 1300)
            rGPBDAT = ~0xe0;
            if(freq == 2500)
            rGPBDAT = ~0x60;
            if(freq == 3700)
            rGPBDAT = ~0x20;
            if(freq == 4900)
            rGPBDAT = ~0x0;

            }

            //頻率遞減
            for( ; freq>50 ; )
            {
            freq-=10;
            rTCMPB0 = freq;
            delay(20000);
            while (stop == TRUE)
            {
            delay(1000);
            if (stop ==FALSE)
            {
            rTCON &= ~0x1F;
            rTCON |= 0xf;
            rTCON &= ~0x2 ;
            }
            }
            if(freq == 100)
            rGPBDAT = ~0x1e0;
            if(freq == 1300)
            rGPBDAT = ~0xe0;
            if(freq == 2500)
            rGPBDAT = ~0x60;
            if(freq == 3700)
            rGPBDAT = ~0x20;
            if(freq == 4900)
            rGPBDAT = ~0x0;
            }
            }
            }

            這里還需要說明幾點(diǎn):

            1、開發(fā)板上的蜂鳴器是高電平發(fā)聲,低電平停止,而TOUT0定時(shí)無效時(shí),是高電平輸出,因此為了使PWM無效時(shí),蜂鳴器不發(fā)聲,我把輸出電平進(jìn)行了反轉(zhuǎn)處理(置TCON中的輸出反轉(zhuǎn)位);

            2、在這里,我是通過按鍵把stop標(biāo)志變量置為FALSE來跳出while循環(huán),重新開始蜂鳴,但不知什么原因,如果在while循環(huán)內(nèi)不加一段等待時(shí)間,則永遠(yuǎn)不能跳出循環(huán)體,因此我不得不加了一個(gè)delay函數(shù),讓它等待一段時(shí)間。關(guān)于這個(gè)問題,我還給不出一個(gè)滿意的解釋,也不知是哪里出了問題!


            關(guān)鍵詞: s3c2440PWM應(yīng)

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉