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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM 學(xué)習(xí)筆記七 (PWM試驗)

          ARM 學(xué)習(xí)筆記七 (PWM試驗)

          作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
          PWM-脈寬調(diào)制。我的理解是通過控制一個計數(shù)器來實現(xiàn)不同脈寬的輸出,從而驅(qū)動蜂鳴器發(fā)出不同的聲音。

          本實驗用到的寄存器如下:

          本文引用地址:http://www.ex-cimer.com/article/201611/318883.htm

          GPBCON -- I/O端口配置寄存器 B
          00=Input 01=Output 10=PWM 11=Reserved

          GPBDAT -- I/O端口數(shù)據(jù)寄存器 B

          GPFUP --I/O端口上拉電阻使能寄存器 B
          0=Enable 1=Disabled

          TCFG0 -- 時鐘配置寄存器0 (主要是設(shè)置預(yù)分頻)
          定時器輸入時鐘頻率=PCLK/{預(yù)分頻}/{分割值}
          {預(yù)分頻}=1~255
          {分割值}=2,4,8,16,32
          Address: 0x51000000
          Reset value:0x00000000
          [7:0]:These 8 bits determine prescaler value for Timer0 and 1

          TCFG1 --時鐘配置寄存器1(主要是設(shè)置分割值)
          Address: 0x51000004
          Reset value:0x00000000
          [3:0]:Select MUX input for PWM Timer0
          0000=1/2 0001=1/4 0010=1/8
          0011=1/16 01XX=External TCLK0

          TCON -- 時鐘控制寄存器
          Address:0x51000008
          Reset value:0x00000000
          [0]: Determine start/stop for Timer0 (設(shè)置啟動/停止)
          0=Stop 1=Start for Timer0
          [1]: Determine the manual update for Timer0 (設(shè)置允許手動修改計數(shù))
          0=No operation 1=Update TCNTB0 & TCMPB0
          [2]: Determine the output inverter on/off for Timer0 (設(shè)置中斷)
          0=Inverter off 1=Inverter on for TOUT0
          [3]: Determine auto reload on/off for timer0
          0=One-shot 1=Interval mode(auto reload)
          [4]: Determine the dead zone operation
          0=Disable 1=Enable


          TCNTB0 -- timer0計數(shù)緩存寄存器
          Address:0x5100000c
          Reset value:0x00000000
          [15:0]:Set count buffer value for Timer0

          TCMPB0 -- timer0比較緩存寄存器
          Address:0x51000010
          Reset value:0x00000000
          [15:0]:Set compare buffer value for Timer0

          實驗方法:
          1.按下k1鍵,使TOUT0遞增占空比

          2.按下k2鍵,使TOUT0遞減占空比

          3.按下k3鍵,停止輸出

          //代碼1---參考阿南的例子,這個簡單

          #include "2410addr.h"


          #define KEY1 (1<<1) // rGPF[1] =1 ;
          #define KEY2 (1<<4) // rGPF[4] =1 ;
          #define KEY3 (1<<2) // rGPF[2] =1 ;

          unsigned short freq =0;

          //===========================[ SYSTEM ]===================================================
          //static int delayLoopCount = 400;
          static int delayLoopCount = FCLK/10000/10;

          void Delay(int time)
          {
          // time=0: adjust the Delay function by WatchDog timer.
          // time>0: the number of loop time
          // resolution of time is 100us.
          int i,adjust=0;
          if(time==0)
          {
          time = 200;
          adjust = 1;
          delayLoopCount = 400;
          //PCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable
          rWTCON = ((PCLK/1000000-1)<<8)|(2<<3);
          rWTDAT = 0xffff; //for first update
          rWTCNT = 0xffff; //resolution=64us @any PCLK
          rWTCON = ((PCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer start
          }
          for(;time>0;time--)
          for(i=0;i if(adjust==1)
          {
          rWTCON = ((PCLK/1000000-1)<<8)|(2<<3); //Watch-dog timer stop
          i = 0xffff - rWTCNT; //1count->64us, 200*400 cycle runtime = 64*i us
          delayLoopCount = 8000000/(i*64); //200*400:64*i=1*x:100 -> x=80000*100/(64*i)
          }
          }

          void PWM_Ini(unsigned short cycle,unsigned short duty){

          if(duty > cycle) duty = cycle;

          //定時器輸入時鐘頻率=PCLK/{預(yù)分頻}/{分割值}
          rTCFG0 =0x64; //設(shè)置預(yù)分頻為100
          rTCFG1 =0x0;//設(shè)置分割值為1/2

          rTCNTB0 =cycle;
          rTCMPB0 =duty;


          rTCON = 0x0A;//disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, stop timer 0
          //000 01010
          rTCON = 0x09;//disable deadzone, auto-reload, inv-off, no operation, start timer 0
          //1001
          }

          void PWM_Stop(){
          freq = 2000;
          rGPBCON = 0x0;
          rGPBDAT = 0x0;
          }

          void PWM_Output(int number){

          if ( number > 0 ){
          if ( freq < 255 )
          freq += 16;
          else
          freq = 0;
          }

          if ( number < 0 ){
          if ( freq >= 16 )
          freq -= 16;
          else
          freq = 0;
          }

          rTCMPB0=freq;
          }

          void Main(void){

          rGPFUP = 0xf800;// KEY [7:0] => PU En
          rGPFCON=0xfcc0; //KEY[7:0] => INPUT;

          rGPBCON = 0x0;
          rGPBCON = 0x02;//TOUT0為輸出端口

          PWM_Ini(255,freq);

          Delay(0);

          while (1){

          if ( !(rGPFDAT & KEY1) ){
          Delay(1000);
          //if (rGPGDAT & KEY1) continue;
          PWM_Output(1);
          }

          if ( !(rGPFDAT & KEY2) ){
          Delay(1000);
          //if (rGPGDAT & KEY2) continue;
          PWM_Output(-1);
          }

          if ( !(rGPFDAT & KEY3) ){
          Delay(1000);
          //if (rGPGDAT & KEY3) continue;
          PWM_Stop();
          }

          }
          }

          上面的例子就是按鍵去抖功能沒能調(diào)試出來。

          //代碼2---參考開發(fā)板帶的例子,這個不好理解

          #define GLOBAL_CLK 1

          #include "def.h"
          #include "2440addr.h"
          #include "option.h"


          #define KEY1 (1<<1) // rGPF[1] =1 ;
          #define KEY2 (1<<4) // rGPF[4] =1 ;
          #define KEY3 (1<<2) // rGPF[2] =1 ;


          static unsigned int freq;

          void PWM_Ini(){

          ChangeClockDivider(3,1); //獲得PCLK=67.5MHz
          ChangeMPllValue(127,2,1);

          rGPFUP = 0xf800;// KEY [7:0] => PU En
          rGPFCON=0xfcc0; //KEY[7:0] => INPUT;
          }

          void PWM_Stop(){
          freq = 2000;
          rGPBCON = 0x0;
          rGPBDAT = 0x0;
          }

          void PWM_Output(int number){

          rGPBCON = 0x0;
          rGPBCON = 0x02;//TOUT0為輸出端口
          //rGPBUP = 0x01;//禁止上拉電阻

          //定時器輸入時鐘頻率=PCLK/{預(yù)分頻}/{分割值}
          rTCFG0 =0x64; //設(shè)置預(yù)分頻為100
          rTCFG1 =0x0;//設(shè)置分割值為1/2


          if ( number > 0 ){
          if ( freq < 20000 )
          freq += number;
          else
          freq = 2000;
          }

          if ( number < 0 ){
          if ( freq > 300 )
          freq -= number;
          else
          freq = 2000;
          }


          rTCNTB0 =freq;
          rTCMPB0 =rTCNTB0>>1;


          rTCON = 0x0B;//disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
          //000 01011
          rTCON &= ~2;//clear manual update bit
          }

          void Main(void){

          freq = 2000;

          PWM_Ini();

          while (1){

          if ( !(rGPFDAT & KEY1) )
          PWM_Output(100);

          if ( !(rGPFDAT & KEY2) )
          PWM_Output(-100);

          if ( !(rGPFDAT & KEY3) )
          PWM_Stop();

          }
          }

          這個例子每次都要重新設(shè)置PGB端口。



          關(guān)鍵詞: ARMPWM試

          評論


          技術(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); })();