PWM即脉宽调制,可用于输出必定占空比的方波。LPC1788有两个PWM,每个PWM能够由6路的输出,PWM1~PWM6。下面介绍运用PWM0.1输出PWM波。
1,PWM运用公共的PCLK,因而要装备体系时钟和外设时钟。之前的文章中有详细的时钟装备进程。
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灯进行暗示。
- #defineCCLK120000000
- #definePCLK60000000
- #definerFIO1DIR(*(volatileunsigned*)(0x20098020))
- #definerFIO1MASK(*(volatileunsigned*)(0x20098030))
- #definerFIO1PIN(*(volatileunsigned*)(0x20098034))
- #definerFIO1SET(*(volatileunsigned*)(0x20098038))
- #definerFIO1CLR(*(volatileunsigned*)(0x2009803c))
- #definerCLKSRCSEL(*(volatileunsigned*)(0x400FC10C))//时钟源挑选寄存器
- #definerPLL0CON(*(volatileunsigned*)(0x400FC080))//PLL0操控寄存器
- #definerPLL0CFG(*(volatileunsigned*)(0x400FC084))//PLL0装备寄存器
- #definerPLL0STAT(*(volatileunsigned*)(0x400FC088))//PLL0状况寄存器
- #definerPLL0FEED(*(volatileunsigned*)(0x400FC08C))//PLL0馈送寄存器
- #definerPLL1CON(*(volatileunsigned*)(0x400FC0A0))
- #definerPLL1CFG(*(volatileunsigned*)(0x400FC0A4))
- #definerPLL1STAT(*(volatileunsigned*)(0x400FC0A8))
- #definerPLL1FEED(*(volatileunsigned*)(0x400FC0AC))
- #definerCCLKSEL(*(volatileunsigned*)(0x400FC104))//CPU时钟挑选寄存器
- #definerUSBCLKSEL(*(volatileunsigned*)(0x400FC108))//USB时钟挑选寄存器
- #definerPCLKSEL(*(volatileunsigned*)(0x400FC1A8))//外设时钟寄存器
- #definerPCON(*(volatileunsigned*)(0x400FC0C0))
- #definerPXCONP(*(volatileunsigned*)(0x400FC0C4))
- #definerSCS(*(volatileunsigned*)(0x400FC1A0))//体系操控和状况寄存器
- #definerCLKOUTCFG(*(volatileunsigned*)(0x400FC1C8))
- #definerIOCON_P1_02(*(volatileunsigned*)(0x4002C088))
- #definerPCONP(*(volatileunsigned*)(0x400FC0C4))
- #definerPWM0IR(*(volatileunsigned*)(0x40014000))
- #definerPWM0TCR(*(volatileunsigned*)(0x40014004))
- #definerPWM0TC(*(volatileunsigned*)(0x40014008))
- #definerPWM0PR(*(volatileunsigned*)(0x4001400C))
- #definerPWM0CTCR(*(volatileunsigned*)(0x40014070))
- #definerPWM0MCR(*(volatileunsigned*)(0x40014014))
- #definerPWM0MR0(*(volatileunsigned*)(0x40014018))
- #definerPWM0MR1(*(volatileunsigned*)(0x4001401C))
- #definerPWM0CCR(*(volatileunsigned*)(0x40014028))
- #definerPWM0PCR(*(volatileunsigned*)(0x4001404C))
- #definerPWM0LER(*(volatileunsigned*)(0x40014050))
- #definerISER1(*(volatileunsigned*)(0xE000E104))
- #definerCER1(*(volatileunsigned*)(0xE000E184))
- unsignedintduty=10;
- unsignedcharmatch_cnt=0;
- voidPWM0_IRQHandler(void)
- {
- if(rPWM0IR&0x1)
- {
- rFIO1PIN|=(1<<18);
- match_cnt++;
- rPWM0IR|=0x1;//MR0中止复位
- }
- if(rPWM0IR&(0x1<<1))
- {
- rFIO1PIN&=~(1<<18);
- rPWM0IR|=0x1<<1;//MR1中止复位
- }
- }
- voidSystemInit()
- {
- rSCS&=~(0x1<<4);//频率12M
- rSCS|=(0x1<<5);//使能主振荡器
- while(0==(rSCS&(0x1<<6)));//等候主振荡器安稳
- rCLKSRCSEL=0x1;
- rPLL0CFG=0x9;//装备CCLK=120M
- rPLL0CON=0x01;
- rPLL0FEED=0xAA;
- rPLL0FEED=0x55;
- while(0==(rPLL0STAT&(0x1<<10)));
- rCCLKSEL=(0x1|(0x1<<8));
- rPCLKSEL=0x2;//装备PCLK=60M
- rCLKOUTCFG=0x0|(0xb<<4)|(0x1<<8);
- }
- voidPWMInit()
- {
- rIOCON_P1_02&=~0x7;
- rIOCON_P1_02|=0x3;//P1.02装备成PWM0[1]
- rPCONP|=0x1<<5;//使能PWM0外设
- rPWM0IR=0x73F;//初始化PWM相关操控寄存器
- rPWM0TCR=0;
- rPWM0CTCR=0;
- rPWM0MCR=0;
- rPWM0CCR=0;
- rPWM0PCR=0;
- rPWM0LER=0;
- rPWM0PR=0x1<<20;//每0x1<<20+1个PLCK上升沿,TC递加
- rPWM0TCR|=0x1<<1;//复位TC和PC
- rPWM0TCR&=~(0x1<<1);
- rPWM0MR0=100;
- rPWM0LER|=0x1;
- rPWM0MCR|=0x1<<1|0x1;//MR0和TC匹配时复位TC和PC.而且发生中止
- rPWM0MR1=duty;
- rPWM0LER|=0x1<<1;
- rPWM0MCR|=0x1<<3;//MR1和TC匹配时发生中止
- }
- intmain()
- {
- PWMInit();
- rFIO1DIR|=(0x1<<18);
- rISER1|=0x1<<7;//PWM0中止使能
- rPWM0TCR|=0x1<<1;//复位TC和PC
- rPWM0TCR&=~(0x1<<1);
- rPWM0TCR|=0x1;//PC和TC计数使能
- rPWM0TCR|=0x1<<3;//PWM形式使能
- while(1)
- {
- if(match_cnt>=1)
- {
- match_cnt=0;
- duty=duty+10;
- if(duty>=100)
- {
- duty=0;
- }
- rPWM0MR1=duty;
- rPWM0LER|=0x1<<1;
- rPWM0MCR|=0x1<<3;
- }
- }
- return1;
- }
程序在MR0匹配时复位TC,在MR1匹配时触发边缘。能够看到跟着MR1匹配值的改动,LED灯的亮灭时刻对应改动。(程序中的预分频寄存器PR设置为了让LED作用显着)
LPC1788的PWM能够进行双边缘的操控。如PWM0.2能够用MR0操控PWM的周期频率,用MR1和MR2操控PWM0.2的边缘。