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灯进行示意。

#define CCLK     120000000
#define PCLK         60000000#define rFIO1DIR   (*(volatile unsigned*)(0x20098020))
#define rFIO1MASK   (*(volatile unsigned*)(0x20098030))
#define rFIO1PIN    (*(volatile unsigned*)(0x20098034))
#define rFIO1SET    (*(volatile unsigned*)(0x20098038))
#define rFIO1CLR    (*(volatile unsigned*)(0x2009803c))#define rCLKSRCSEL  (*(volatile unsigned *)(0x400FC10C))     //时钟源选择寄存器
#define rPLL0CON    (*(volatile unsigned *)(0x400FC080))     //PLL0控制寄存器
#define rPLL0CFG    (*(volatile unsigned *)(0x400FC084))     //PLL0配置寄存器
#define rPLL0STAT   (*(volatile unsigned *)(0x400FC088))     //PLL0状态寄存器
#define rPLL0FEED   (*(volatile unsigned *)(0x400FC08C))     //PLL0馈送寄存器
#define rPLL1CON    (*(volatile unsigned *)(0x400FC0A0))
#define rPLL1CFG    (*(volatile unsigned *)(0x400FC0A4))
#define rPLL1STAT   (*(volatile unsigned *)(0x400FC0A8))
#define rPLL1FEED   (*(volatile unsigned *)(0x400FC0AC))
#define rCCLKSEL    (*(volatile unsigned *)(0x400FC104))     //CPU时钟选择寄存器
#define rUSBCLKSEL  (*(volatile unsigned *)(0x400FC108))     //USB时钟选择寄存器
#define rPCLKSEL    (*(volatile unsigned *)(0x400FC1A8))     //外设时钟寄存器
#define rPCON       (*(volatile unsigned *)(0x400FC0C0))
#define rPXCONP     (*(volatile unsigned *)(0x400FC0C4))
#define rSCS        (*(volatile unsigned *)(0x400FC1A0))     //系统控制和状态寄存器
#define rCLKOUTCFG  (*(volatile unsigned *)(0x400FC1C8))#define rIOCON_P1_02    (*(volatile unsigned *)(0x4002C088))
#define rPCONP      (*(volatile unsigned *)(0x400FC0C4))#define rPWM0IR     (*(volatile unsigned *)(0x40014000))
#define rPWM0TCR    (*(volatile unsigned *)(0x40014004))
#define rPWM0TC     (*(volatile unsigned *)(0x40014008))
#define rPWM0PR     (*(volatile unsigned *)(0x4001400C))
#define rPWM0CTCR   (*(volatile unsigned *)(0x40014070))
#define rPWM0MCR    (*(volatile unsigned *)(0x40014014))
#define rPWM0MR0    (*(volatile unsigned *)(0x40014018))
#define rPWM0MR1    (*(volatile unsigned *)(0x4001401C))
#define rPWM0CCR    (*(volatile unsigned *)(0x40014028))
#define rPWM0PCR    (*(volatile unsigned *)(0x4001404C))
#define rPWM0LER    (*(volatile unsigned *)(0x40014050))#define rISER1      (*(volatile unsigned *)(0xE000E104))
#define rCER1       (*(volatile unsigned *)(0xE000E184))unsigned int duty = 10;
unsigned char match_cnt = 0;void PWM0_IRQHandler(void)
{if(rPWM0IR&0x1){rFIO1PIN |= (1<<18);match_cnt++;rPWM0IR |= 0x1;  //MR0中断复位}if(rPWM0IR&(0x1<<1)){rFIO1PIN &= ~(1<<18);rPWM0IR |= 0x1<<1;  //MR1中断复位}
}void SystemInit()
{  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);
} void PWMInit()
{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和PCrPWM0TCR &= ~(0x1<<1);rPWM0MR0 = 100;rPWM0LER |= 0x1;rPWM0MCR |= 0x1<<1 | 0x1;     //MR0和TC匹配时复位TC和PC.并且产生中断rPWM0MR1 = duty;rPWM0LER |= 0x1<<1;rPWM0MCR |= 0x1<<3;  //MR1和TC匹配时产生中断
}int main ()
{PWMInit();rFIO1DIR |= (0x1<<18);rISER1 |= 0x1<<7;    //PWM0中断使能rPWM0TCR |= 0x1<<1;    //复位TC和PCrPWM0TCR &= ~(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;}}return 1;
}

程序在MR0匹配时复位TC,在MR1匹配时触发边沿。可以看到随着MR1匹配值的改变,LED灯的亮灭时间对应改变。(程序中的预分频寄存器PR设置为了让LED效果明显)

LPC1788的PWM可以进行双边沿的控制。如PWM0.2可以用MR0控制PWM的周期频率,用MR1和MR2控制PWM0.2的边沿。

本文章转载自 Cortex-M3 (NXP LPC1788)之PWM

Cortex-M3 (NXP LPC1788)之PWM(脉宽调制器)相关推荐

  1. PWM脉宽调制信号转直流电压电流模拟信号输出隔离变送器5v10v4-20ma

    PWM脉宽调制信号输入模拟信号输出隔离变送器 主要特性: >>精度等级:0.2级.0.5级.产品出厂前已检验校正,用户可以直接使用 >>辅助电源:5V/12V/15V/24VD ...

  2. dda算法控制电机_求PWM速度控制系统是通过脉宽调制器对大功率晶体管的开关时间进...

    行控制,将直流电压转换成某种频率的方波电压,并通过对脉冲宽度的控制,改变输出直流平均电压的自动调速系统.以脉冲编码器作为检测器件的常见PWM直流伺服系统的框图如图5-3所示.其工作过程如下: 图5-3 ...

  3. PWM脉宽调制信号转模拟电流电压4-20ma0-5v10v隔离变送器

    主要特性: 精度等级:0.2级.0.5级.产品出厂前已检验校正,用户可以直接使用 辅助电源:5V/12V/15V/24VDC(范围±10%) PWM脉宽调制信号输入: 50Hz~100KHz 输出标准 ...

  4. 用Arduino剖析PWM脉宽调制

    PWM(Pulse Width Modulation)简介 PWM,也就是脉冲宽度调制,用于将一段信号编码为脉冲信号(一般是方波信号).是在数字电路中 达到 模拟输出效果的一种手段.即:使用数字控制产 ...

  5. cortex m3的操作模式和状态

    1.操作状态(operation state): debug state:处理器在调试器发起halt或匹配到断点时,会进入debug state并停止执行指令. thumb state:处理器正在运行 ...

  6. Cortex、ARMv8、arm架构、ARM指令集、soc?Cortex A8、A9都是ARMv7a 架构;Cortex M3、M4是ARMv7m架构;前者是处理器(内核)后者是指令集的架构(架构)

    架构组成元素的指令集状态或者语法thumb指令集与arm指令集的区别例如thumb指令集是什么_thumb指令集与arm指令集的区别以及thumb-2的关系在下一文中介绍,本文暂时不讨论 有粉丝问我到 ...

  7. matlab脉宽调制pwm,PWM脉宽调制直流调速系统设计及MATLAB仿真验证

    PWM 脉宽调制直流调速系统设计及MATLAB 仿真验证 第一章 系统概述 1.1 设计目的 1. 掌握转速,电流双闭环控制的双极式PWM 直流调速原理. 2. 掌握并熟练运用MATLAB 对系统进行 ...

  8. Cortex M3 NVIC与中断控制

    Cortex M3 NVIC与中断控制 宗旨:技术的学习是有限的,分享的精神是无限的. 一.NVIC概览 --嵌套中断向量表控制器 NVIC 的寄存器以存储器映射的方式来访问,除了包含控制寄存器和中断 ...

  9. Cortex M3内核架构

    CortexM3内核架构 宗旨:技术的学习是有限的,分享的精神是无限的. 1.ARMCortex-M3处理器 Cortex-M3处理器内核是单片机的中央处理单元( CPU). 完整的基于CM3的MCU ...

  10. Cortex M3 Bit-banding简介

    http://blog.csdn.net/shevsten/article/details/7676397 Cortex M3 Bit-banding简介 分类: ARM MCU2012-06-19 ...

最新文章

  1. java 单例写法_java 单例模式的几种写法
  2. Filling Shapes
  3. 卷积神经网络(卷积层,激活函数Relu,池化层,计算公式及API解释)
  4. Hive更改表名FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Una ble
  5. java算法之冒泡排序
  6. HTML5 main元素
  7. bzoj1951 [Sdoi2010]古代猪文 lucas+CRT+exgcd
  8. DNS IP DOMAIN 详解
  9. 数据结构与算法(八)-二叉树(斜二叉树、满二叉树、完全二叉树、线索二叉树)...
  10. cocos2d-html5 sprite打印宽高都为0的问题
  11. H.266/VVC代码学习38:VTM6.0帧间merge预测(xCheckRDCostMerge2Nx2N)
  12. java计算机毕业设计中小型超市管理系统录像补源码+数据库+系统+lw文档+mybatis+运行部署
  13. jupyter notebook 内核似乎挂掉了
  14. 计算机鼠标老跳动,鼠标跳动是什么原因 鼠标经常抖动的解决方法
  15. java实现12306查票_java抓取12306信息实现火车余票查询示例
  16. oracle归档默认路径,更改ORACLE归档路径及归档模式
  17. excel无法打开文件,因为文件格式或文件扩展名无效
  18. Android App软件框架搭建
  19. 高精度减法(C语言实现)
  20. MakerDAO亚洲区负责人王奇君:我的DAI很稳!

热门文章

  1. SSM框架整合详细教程
  2. 计算机制作ppt考试题,计算机二级PPT真题:制作计算机发展简史PPT
  3. 【老生谈算法】基于matlab的指纹处理和识别算法详解及程序源码——指纹识别算法
  4. 电容 电阻0201/0402/0603/等封装长宽高定义
  5. Springboot中使用Junit5(Jupiter)和Mockito
  6. Centos 7 WPS简单安装方法
  7. MindManager 2020注册机下载
  8. angular应用coreui框架
  9. LogViewer_2
  10. 大数据培训(第一季) java基础-徐培成-专题视频课程