<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          s3c2440的PWM應(yīng)用

          作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
          PWM(Pulse Width Modulation)——脈寬調(diào)制,它是利用微控制器的數(shù)字輸出來(lái)對(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是通過(guò)引腳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è)置脈沖的具體寬度,它的基本原理是通過(guò)寄存器TCNTBn來(lái)對(duì)寄存器TCNTn(內(nèi)部寄存器)進(jìn)行配置計(jì)數(shù),TCNTn是遞減的,如果減到零,則它又會(huì)重新裝載TCNTBn里的數(shù),重新開(kāi)始計(jì)數(shù),而寄存器TCMPBn作為比較寄存器與計(jì)數(shù)值進(jìn)行比較,當(dāng)TCNTn等于TCMPBn時(shí),TOUTn輸出的電平會(huì)翻轉(zhuǎn),而當(dāng)TCNTn減為零時(shí),電平會(huì)又翻轉(zhuǎn)過(guò)來(lái),就這樣周而復(fù)始。因此這一步的關(guān)鍵是設(shè)置寄存器TCNTBn和TCMPBn,前者可以確定一個(gè)計(jì)數(shù)周期的時(shí)間長(zhǎng)度,而后者可以確定方波的占空比。由于s3c2440的定時(shí)器具有雙緩存,因此可以在定時(shí)器運(yùn)行的狀態(tài)下,改變這兩個(gè)寄存器的值,它會(huì)在下個(gè)周期開(kāi)始有效。

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

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

          #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)//重啟鍵,開(kāi)啟蜂鳴器
          {
          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為T(mén)OUT0,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ū)無(wú)效,自動(dòng)裝載,電平反轉(zhuǎn),手動(dòng)更新,定時(shí)器開(kāi)啟
          rTCON &= ~0x2 ;//手動(dòng)更新位清零,PWM開(kāi)始工作

          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;
          }
          }
          }

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

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

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


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

          評(píng)論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();