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

          新聞中心

          s3c2440的PWM應(yīng)用

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

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

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

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

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

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

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

          #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;//禁止定時器自動重載,即關(guān)閉定時器
          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ū)無效,自動裝載,電平反轉(zhuǎn),手動更新,定時器開啟
          rTCON &= ~0x2 ;//手動更新位清零,PWM開始工作

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

          stop = FALSE;

          rGPBDAT = ~0x60;//兩個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個LED隨著頻率的高低,時滅時亮
          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定時無效時,是高電平輸出,因此為了使PWM無效時,蜂鳴器不發(fā)聲,我把輸出電平進(jìn)行了反轉(zhuǎn)處理(置TCON中的輸出反轉(zhuǎn)位);

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


          關(guān)鍵詞: s3c2440PWM應(yī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); })();