LPC1768PWM实验

PWM即是脉冲宽度调制。脉冲宽度调制是利用 微处理器的数字输出来对 模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
脉冲宽度调制是一种模拟控制方式,其根据相应载荷的变化来调制晶体管基极或 MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用 微处理器的数字信号对 模拟电路进行控制的一种非常有效的技术。
PWM控制技术以其控制简单,灵活和动态响应好的优点而成为 电力电子技术最广泛应用的控制方式,也是人们研究的热点。由于当今科学技术的发展已经没有了学科之间的界限,结合 现代控制理论思想或实现无谐振波开关技术将会成为PWM控制技术发展的主要方向之一。其根据相应载荷的变化来调制晶体管基极或 MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用 微处理器的数字信号对 模拟电路进行控制的一种非常有效的技术。
脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。
  
  例如,把正弦半波波形分成N等份,就可把正弦半波看成由N个彼此相连的脉冲所组成的波形。这些脉冲宽度相等,都等于 π/n ,但幅值不等,且脉冲顶部不是水平直线,而是曲线,各脉冲的幅值按正弦规律变化。如果把上述脉冲序列用同样数量的等幅而不等宽的矩形脉冲序列代替,使矩形脉冲的中点和相应正弦等分的中点重合,且使矩形脉冲和相应正弦部分面积(即冲量)相等,就得到一组脉冲序列,这就是 PWM波形。可以看出,各脉冲宽度是按正弦规律变化的。根据冲量相等效果相同的原理,PWM波形和正弦半波是等效的。对于正弦的负半周,也可以用同样的方法得到PWM波形。
在PWM波形中,各脉冲的幅值是相等的,要改变等效输出正弦波的幅值时,只要按同一比例系数改变各脉冲的宽度即可,因此在交-直-交变频器中,PWM逆变电路输出的脉冲电压就是直流侧电压的幅值。
根据上述原理,在给出了正弦波频率,幅值和半个周期内的脉冲数后,PWM波形各脉冲的宽度和间隔就可以准确计算出来。按照计算结果控制电路中各开关器件的通断,就可以得到所需要的PWM波形。
下图为变频器输出的PWM波的实时波形。

pwm.h内容

#ifndef _PWM_H
#define _PWM_H
#include "lpc17xx.h"


#define PWM_CYCLE 1200
#define PWM_OFFSET 200
#define MR0_INT 1 << 0
#define MR1_INT 1 << 1
#define MR2_INT 1 << 2
#define MR3_INT 1 << 3
#define MR4_INT 1 << 8
#define MR5_INT 1 << 9
#define MR6_INT 1 << 10

#define TCR_CNT_EN 0x00000001//TCR定时器控制寄存器使能
#define TCR_RESET 0x00000002 //TCR定时器控制寄存器复位
#define TCR_PWM_EN 0x00000008//TCR定时器控制寄存器使能PWM模式

//MCR--PWM匹配控制寄存器,PWM匹配控制寄存器用来控制在PWM匹配寄存器与PWM定时器计数器匹配时所执行的
//操作

#define PWMMR0I 1 << 0
#define PWMMR0R 1 << 1
#define PWMMR0S 1 << 2
#define PWMMR1I 1 << 3
#define PWMMR1R 1 << 4
#define PWMMR1S 1 << 5
#define PWMMR2I 1 << 6
#define PWMMR2R 1 << 7
#define PWMMR2S 1 << 8
#define PWMMR3I 1 << 9
#define PWMMR3R 1 << 10
#define PWMMR3S 1 << 11
#define PWMMR4I 1 << 12
#define PWMMR4R 1 << 13
#define PWMMR4S 1 << 14
#define PWMMR5I 1 << 15
#define PWMMR5R 1 << 16
#define PWMMR5S 1 << 17
#define PWMMR6I 1 << 18
#define PWMMR6R 1 << 19
#define PWMMR6S 1 << 20

//PCR----PWM控制寄存器,用来使能和选择每个PMW通道的类型
#define PWMSEL2 1 << 2
#define PWMSEL3 1 << 3
#define PWMSEL4 1 << 4
#define PWMSEL5 1 << 5
#define PWMSEL6 1 << 6
#define PWMENA1 1 << 9
#define PWMENA2 1 << 10
#define PWMENA3 1 << 11
#define PWMENA4 1 << 12
#define PWMENA5 1 << 13
#define PWMENA6 1 << 14
//LER---PWM锁存使能寄存器,PWM 匹配寄存器用来产生 PWM 时, PWM 锁存使能寄存器用来控制 PWM 匹配寄存器
//的更新。


#define LER0_EN 1 << 0
#define LER1_EN 1 << 1
#define LER2_EN 1 << 2
#define LER3_EN 1 << 3
#define LER4_EN 1 << 4
#define LER5_EN 1 << 5
#define LER6_EN 1 << 6

extern uint32_t PWM_Init(uint32_t ChannelNum,uint32_t cycle);
extern void PWM_Set(uint32_t ChannelNum,uint32_t cycle,uint32_t offset);
extern void PWM_Start (uint32_t ChannelNum);
extern void PWM_Stop(uint32_t ChannelNum);
extern void LED_Light(void);
#endif

pwm.c内容

#include "lpc17xx.h"
#include "pwm.h"

/*******************************************************************************
** uint32_t PWM_Init(uint32_t ChannelNum,uint32_t cycle)
**PWM初始化
**PWM号:uint32_t ChannelNum
**周期值: uint32_t cycle
**
********************************************************************************/
uint32_t PWM_Init(uint32_t ChannelNum,uint32_t cycle)
{
LPC_GPIO0->FIODIR  = 0x00200000; // p0.21设置为输出
  LPC_GPIO0->FIOPIN |= 0x00200000;     // p0.21=1,蒙蔽锁存器对LED灯的影响
if(ChannelNum==1)
{
LPC_PINCON->PINSEL4=0x00000555;//设置p2.00~p2.05为pwm输出引脚

LPC_PWM1->TCR = TCR_RESET;
LPC_PWM1->PR  = 0x00;//预分频寄存器设置清零
LPC_PWM1->MCR = PWMMR0R;//设置匹配可控制寄存器
LPC_PWM1->MR0 = cycle;//设置pwm匹配值
LPC_PWM1->MR1 = cycle*5/6;
LPC_PWM1->MR2 = cycle*4/6;
LPC_PWM1->MR3 = cycle*3/6;
LPC_PWM1->MR4 = cycle*2/6;
LPC_PWM1->MR5 = cycle*1/6;
LPC_PWM1->MR6 = 0;

//使能PWM
LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
}
else
{
return (0);//unknow channel number
}
return (1);
}


/**************************************************************
**PWM_Set(uint32_t ChannelNum,uint32_t cycle,uint32_t offset)
**设置pwm的周期值,匹配值,周期值
**匹配值:uint32_t cycle 
**pwm号:uint32_t ChannelNum
**周期值:uint32_t offset
**************************************************************/
void PWM_Set(uint32_t ChannelNum,uint32_t cycle,uint32_t offset)
{
if(1==ChannelNum)
{
LPC_PWM1->MR0 = cycle;//设置pwm匹配寄存器的值
LPC_PWM1->MR1 = cycle *5/6 +offset;
LPC_PWM1->MR2 = cycle *4/6 +offset;
LPC_PWM1->MR3 = cycle *3/6 +offset;
LPC_PWM1->MR4 = cycle *2/6 +offset;
LPC_PWM1->MR5 = cycle *1/6 +offset;
LPC_PWM1->MR6 = offset;

LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
}
}


/*********************************************
**void PWM_Start(uint32_t ChannelNum)
**启动PWM号
**********************************************/
void PWM_Start (uint32_t ChannelNum)
{
if(ChannelNum==1)
{
LPC_PWM1->PCR = PWMENA1 | PWMENA2 | PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge(边沿),all enable
LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable
}
}


/*********************************************
**void PWM_Stop(uint32_t ChannelNum)
**停止PWM号
**********************************************/
void PWM_Stop(uint32_t ChannelNum)
{
if(ChannelNum==1)
{
LPC_PWM1->PCR = 0;
LPC_PWM1->TCR = 0x00;//stop all PWMs

}
return;
}


void LED_Light(void)
{
int led_fx=1;
int led_dt =0;
if(led_fx==1)
{
led_dt++;
}
else{
led_dt--;
}
if(led_dt>1200) led_fx = 0;
if(led_dt==0) led_fx=1;
LPC_PWM1->MR0 =led_dt;
LPC_PWM1->MR1 = led_dt;
LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
LPC_PWM1->PCR = PWMENA1 | PWMENA2 | PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge(边沿),all enable
LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable


}


//例程(main里面的例程)
//   uint32_t cycle = PWM_CYCLE, offset = 0;

//   LPC_GPIO0->FIODIR = 0x00200000;       
//   LPC_GPIO0->FIOPIN |=  0x00200000; /* 屏蔽锁存器对LED灯的影响 */
//   LPC_GPIO2->FIODIR = 0x000000c0; //设置p2.6,2.7LEED为输出
//   if ( PWM_Init( 1, 0 ) != 1 ) /* 屏蔽锁存器对LED灯的影响 */ 
//   {
// while( 1 );
//   }
//   PWM_Set( 1, cycle, offset ); /*设置PWM的周期值,以及匹配值*/
//   PWM_Start( 1 ); /* pwm输出 */ 
//   while ( 1 )
//   {}


/***********led灯亮度逐渐变化**********/
//   uint32_t cycle = PWM_CYCLE,offset=0;
// uint32_t led_fx=1;
// uint32_t led_dt =0;
// uint32_t i=0,j=0;
// LPC_GPIO2->FIODIR = 0x000000c0;
// if(PWM_Init(1,0)!=1)//
// {
// while(1);
// }
// LPC_PWM1->MR0 =1200;/**************使能pwm前,匹配寄存器MR0的值一定要设置*********/
//     while (1) 
// {

// Delay(10);
// for(i=0;i<1200;i++)
// {
// LPC_PWM1->MR1=j;
// j++;
// Delay(15);
// LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
// LPC_PWM1->PCR = PWMENA1; //| PWMENA2 | PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge(边沿),all enable
// LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable
// }
// Delay(100);
// for(i=0;i<1200;i++)
// {
// LPC_PWM1->MR1=j;
// j--;
// Delay(15);
// LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
// LPC_PWM1->PCR = PWMENA1; //| PWMENA2 | PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge(边沿),all enable
// LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable
// }
//    }
// }


main.c内容

#include "lpc17xx.h"

#include "pwm.h"
int main(void)
{
  uint32_t cycle = PWM_CYCLE,offset=0;
uint32_t i=0,j=0;

SystemInit();
LPC_GPIO2->FIODIR = 0x000000c0;
if(PWM_Init(1,0)!=1)//蒙蔽锁存器对LED灯的影响并初始化PWM
{
while(1);
}

LPC_PWM1->MR0 =1200;//在使能pwm前要赋值匹配寄存器MR0
    while (1) 
{
Delay(10);

//LED逐渐变亮,然后逐渐变暗
for(i=0;i<1200;i++)
{
LPC_PWM1->MR1=j;
j++;
Delay(15);
LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
LPC_PWM1->PCR = PWMENA1| PWMENA2 ;//| PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge enable
LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable
}
Delay(100);
for(i=0;i<1200;i++)
{
LPC_PWM1->MR1=j;
j--;
Delay(15);
LPC_PWM1->LER = LER0_EN|LER1_EN | LER2_EN | LER3_EN | LER4_EN | LER5_EN | LER6_EN ;
LPC_PWM1->PCR = PWMENA1| PWMENA2 ;//| PWMENA3 | PWMENA4 | PWMENA5 | PWMENA6 ;//all single edge(±ßÑØ£©£¬all enable
LPC_PWM1->TCR =TCR_CNT_EN | TCR_PWM_EN;//counter enable,PWM enable
}


   }
}




你可能感兴趣的:(LPC1768)