• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > Cortex-M3 (NXP LPC1788)之PWM

    Cortex-M3 (NXP LPC1788)之PWM

    作者: 時間:2016-11-19 來源:網絡 收藏
    PWM即脈寬調制,可用于輸出一定占空比的方波。LPC1788有兩個PWM,每個PWM可以由6路的輸出,PWM1~PWM6。下面介紹使用PWM0.1輸出PWM波。

    1,PWM使用公共的PCLK,因此要配置系統時鐘和外設時鐘。之前的文章中有具體的時鐘配置過程。

    本文引用地址:http://www.czjhyjcfj.com/article/201611/318448.htm

    2,使能PWM模塊。配置外設功率配置寄存器PCONP,使能PWM0的時鐘控制位。

    3,PWM0.1的輸出管腳和P1_2管腳復用,因此要配置IOCON_P1_02寄存器,將其設置成PWM0.1的輸出。

    4,設置PWM的脈沖寬度,基本的原理就是比較PWM定時器計數器TC和匹配寄存器MR中的值,如果匹配我們可以通過匹配控制寄存器MCR選擇操作,如產生一個中斷,復位TC,停止TC和預分頻計數器PC且停止計數。匹配寄存器MR0通過在匹配是將計數器TC復位來控制PWM的周期頻率。另一個匹配寄存器控制PWM沿的位置。如PWM0.1的輸出,將使用MR0控制PWM的周期頻率,MR1控制邊沿的位置。

    5,最后是對于PWM的具體控制,配置PWM預分頻寄存器PWMPR,該32位寄存器規定了PWM預分頻計數的最大值,PWM預分頻計數器寄存器PWMPC在每個PCLK上遞增一次,當PWMPC和PWMPR值相等時,PWMTC的值會遞增,而PWMPR在系一個PCLK周期被復位。這樣,當PWMPR=0時,PWMTC會在每個PCLK上遞增,而當PWMPR=1時,在每2個PCLK上遞增。匹配寄存器PWMMR中的值和PWMTC的值比較,如果相等則觸發在PWMMCR中配置的操作。當MR0和TC相等時,我們進行復位TC從新計數從而固定了PWM的周期頻率。當定時器處于PWM模式時,軟件對PWM匹配寄存器MR的寫操作,寫入值實際上被保存在一個映像寄存器中,不會被立即使用。所以在我們需要操作PWM鎖存使能寄存器PWMLER,典型序列為:將新值寫入MR,寫PWMLER中相應的位,更改的MR值將在下一次定時器復位時生效。

    在下面的程序中,將給MR1中寫入不同的匹配值,來控制PWM的占空比。為了方便使用LED燈進行示意。

    1. #defineCCLK120000000
    2. #definePCLK60000000
    3. #definerFIO1DIR(*(volatileunsigned*)(0x20098020))
    4. #definerFIO1MASK(*(volatileunsigned*)(0x20098030))
    5. #definerFIO1PIN(*(volatileunsigned*)(0x20098034))
    6. #definerFIO1SET(*(volatileunsigned*)(0x20098038))
    7. #definerFIO1CLR(*(volatileunsigned*)(0x2009803c))
    8. #definerCLKSRCSEL(*(volatileunsigned*)(0x400FC10C))//時鐘源選擇寄存器
    9. #definerPLL0CON(*(volatileunsigned*)(0x400FC080))//PLL0控制寄存器
    10. #definerPLL0CFG(*(volatileunsigned*)(0x400FC084))//PLL0配置寄存器
    11. #definerPLL0STAT(*(volatileunsigned*)(0x400FC088))//PLL0狀態寄存器
    12. #definerPLL0FEED(*(volatileunsigned*)(0x400FC08C))//PLL0饋送寄存器
    13. #definerPLL1CON(*(volatileunsigned*)(0x400FC0A0))
    14. #definerPLL1CFG(*(volatileunsigned*)(0x400FC0A4))
    15. #definerPLL1STAT(*(volatileunsigned*)(0x400FC0A8))
    16. #definerPLL1FEED(*(volatileunsigned*)(0x400FC0AC))
    17. #definerCCLKSEL(*(volatileunsigned*)(0x400FC104))//CPU時鐘選擇寄存器
    18. #definerUSBCLKSEL(*(volatileunsigned*)(0x400FC108))//USB時鐘選擇寄存器
    19. #definerPCLKSEL(*(volatileunsigned*)(0x400FC1A8))//外設時鐘寄存器
    20. #definerPCON(*(volatileunsigned*)(0x400FC0C0))
    21. #definerPXCONP(*(volatileunsigned*)(0x400FC0C4))
    22. #definerSCS(*(volatileunsigned*)(0x400FC1A0))//系統控制和狀態寄存器
    23. #definerCLKOUTCFG(*(volatileunsigned*)(0x400FC1C8))
    24. #definerIOCON_P1_02(*(volatileunsigned*)(0x4002C088))
    25. #definerPCONP(*(volatileunsigned*)(0x400FC0C4))
    26. #definerPWM0IR(*(volatileunsigned*)(0x40014000))
    27. #definerPWM0TCR(*(volatileunsigned*)(0x40014004))
    28. #definerPWM0TC(*(volatileunsigned*)(0x40014008))
    29. #definerPWM0PR(*(volatileunsigned*)(0x4001400C))
    30. #definerPWM0CTCR(*(volatileunsigned*)(0x40014070))
    31. #definerPWM0MCR(*(volatileunsigned*)(0x40014014))
    32. #definerPWM0MR0(*(volatileunsigned*)(0x40014018))
    33. #definerPWM0MR1(*(volatileunsigned*)(0x4001401C))
    34. #definerPWM0CCR(*(volatileunsigned*)(0x40014028))
    35. #definerPWM0PCR(*(volatileunsigned*)(0x4001404C))
    36. #definerPWM0LER(*(volatileunsigned*)(0x40014050))
    37. #definerISER1(*(volatileunsigned*)(0xE000E104))
    38. #definerCER1(*(volatileunsigned*)(0xE000E184))
    39. unsignedintduty=10;
    40. unsignedcharmatch_cnt=0;
    41. voidPWM0_IRQHandler(void)
    42. {
    43. if(rPWM0IR&0x1)
    44. {
    45. rFIO1PIN|=(1<<18);
    46. match_cnt++;
    47. rPWM0IR|=0x1;//MR0中斷復位
    48. }
    49. if(rPWM0IR&(0x1<<1))
    50. {
    51. rFIO1PIN&=~(1<<18);
    52. rPWM0IR|=0x1<<1;//MR1中斷復位
    53. }
    54. }
    55. voidSystemInit()
    56. {
    57. rSCS&=~(0x1<<4);//頻率12M
    58. rSCS|=(0x1<<5);//使能主振蕩器
    59. while(0==(rSCS&(0x1<<6)));//等待主振蕩器穩定
    60. rCLKSRCSEL=0x1;
    61. rPLL0CFG=0x9;//配置CCLK=120M
    62. rPLL0CON=0x01;
    63. rPLL0FEED=0xAA;
    64. rPLL0FEED=0x55;
    65. while(0==(rPLL0STAT&(0x1<<10)));
    66. rCCLKSEL=(0x1|(0x1<<8));
    67. rPCLKSEL=0x2;//配置PCLK=60M
    68. rCLKOUTCFG=0x0|(0xb<<4)|(0x1<<8);
    69. }
    70. voidPWMInit()
    71. {
    72. rIOCON_P1_02&=~0x7;
    73. rIOCON_P1_02|=0x3;//P1.02配置成PWM0[1]
    74. rPCONP|=0x1<<5;//使能PWM0外設
    75. rPWM0IR=0x73F;//初始化PWM相關控制寄存器
    76. rPWM0TCR=0;
    77. rPWM0CTCR=0;
    78. rPWM0MCR=0;
    79. rPWM0CCR=0;
    80. rPWM0PCR=0;
    81. rPWM0LER=0;
    82. rPWM0PR=0x1<<20;//每0x1<<20+1個PLCK上升沿,TC遞增
    83. rPWM0TCR|=0x1<<1;//復位TC和PC
    84. rPWM0TCR&=~(0x1<<1);
    85. rPWM0MR0=100;
    86. rPWM0LER|=0x1;
    87. rPWM0MCR|=0x1<<1|0x1;//MR0和TC匹配時復位TC和PC.并且產生中斷
    88. rPWM0MR1=duty;
    89. rPWM0LER|=0x1<<1;
    90. rPWM0MCR|=0x1<<3;//MR1和TC匹配時產生中斷
    91. }
    92. intmain()
    93. {
    94. PWMInit();
    95. rFIO1DIR|=(0x1<<18);
    96. rISER1|=0x1<<7;//PWM0中斷使能
    97. rPWM0TCR|=0x1<<1;//復位TC和PC
    98. rPWM0TCR&=~(0x1<<1);
    99. rPWM0TCR|=0x1;//PC和TC計數使能
    100. rPWM0TCR|=0x1<<3;//PWM模式使能
    101. while(1)
    102. {
    103. if(match_cnt>=1)
    104. {
    105. match_cnt=0;
    106. duty=duty+10;
    107. if(duty>=100)
    108. {
    109. duty=0;
    110. }
    111. rPWM0MR1=duty;
    112. rPWM0LER|=0x1<<1;
    113. rPWM0MCR|=0x1<<3;
    114. }
    115. }
    116. return1;
    117. }
    程序在MR0匹配時復位TC,在MR1匹配時觸發邊沿。可以看到隨著MR1匹配值的改變,LED燈的亮滅時間對應改變。(程序中的預分頻寄存器PR設置為了讓LED效果明顯)

    LPC1788的PWM可以進行雙邊沿的控制。如PWM0.2可以用MR0控制PWM的周期頻率,用MR1和MR2控制PWM0.2的邊沿。



    關鍵詞: Cortex-M3NXPLPC1788PW

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 萨嘎县| 界首市| 莱阳市| 安吉县| 班戈县| 安吉县| 临夏县| 东乡族自治县| 赤城县| 阿图什市| 马公市| 清涧县| 勃利县| 大荔县| 芒康县| 玉林市| 武鸣县| 安徽省| 德格县| 黄石市| 徐水县| 龙门县| 磴口县| 雷波县| 靖西县| 华安县| 宁德市| 上饶县| 鹿邑县| 周宁县| 木兰县| 云龙县| 滁州市| 武山县| 孟村| 黄梅县| 原平市| 富平县| 宜宾市| 华蓥市| 易门县|