通过PWM做一个简单的呼吸灯

PWM(脉冲宽度调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

本例中我们通过MC9S12XS128微处理器来制作一个简单的呼吸灯,我们利用级联的PWM0和PWM1来做PWM的输出。

如下为本例中配置PWM所用到的寄存器简介:

PWMCTL寄存器
在这里插入图片描述
CON67=0时,6和7是独立的 8bit PWM通道
=1时,6和7级联为一个 16bit PWM通道
CON45=0时,4和5是独立的 8bit PWM通道
=1时,4和5级联为一个 16bit PWM通道
CON23=0时,2和3是独立的 8bit PWM通道
=1时,2和3级联为一个 16bit PWM通道
CON01=0时,0和1是独立的 8bit PWM通道
=1时,0和1级联为一个 16bit PWM通道
PSWAI =0时,在等待模式下允许时钟继续
=1时,在等待模式下禁止时钟输入
PFRZ=0时,在冻结模式下允许脉宽调制继续
=1时,在冻结模式下禁止时钟输入
(级联后由管脚号较大的决定电平极性,时钟信号源等等)

PWMPOL寄存器
通过PWM做一个简单的呼吸灯_第1张图片
PPOLn=0时,PWM在起始周期先为0再为1
=1时,PWM在起始周期先为1再为0

PWMPRCLK寄存器通过PWM做一个简单的呼吸灯_第2张图片
PCKB[2:0]:时钟B的预分频位
通过PWM做一个简单的呼吸灯_第3张图片
PCKA[2:0]:时钟A的预分频位
通过PWM做一个简单的呼吸灯_第4张图片
PWMSCLA寄存器
在这里插入图片描述
Clock SA = Clock A / (2 * PWMSCLA)

PWMCLK寄存器
在这里插入图片描述
PCLK 7,6,3,2= 0时,Clock B作为PWM的时钟
=1时,Clock SB作为PWM的时钟
PCLK 5,4,1,0=0时,Clock A作为PWM的时钟
=1时,Clock SA作为PWM的时钟

PWMPERx寄存器
在这里插入图片描述
PWMx Period = Channel Clock Period x PWMPERx

PWMDTYx寄存器
在这里插入图片描述
PPOL x =0时,占空比 = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%
PPOL x =1时,占空比 = [PWMDTYx / PWMPERx]*100%

PWME寄存器
在这里插入图片描述
PWMEx=0时,通道x禁止输出
PWMEx=1时,通道x允许输出

#include       
#include "derivative.h"      

#define LEDCPU     PORTB_PB1        //定义连接发光二级管的PORTB_PB1口数据寄存
                                   //为LED,写'0'亮,写'1' 灭
#define LEDCPU_dir DDRB_DDRB1       //定义连接发光二级管的PORTB_PB1口方向寄存器
                                   //为LEDCPU_dir,写'0'做输入口,写'1'做输出口


void INIT_PLL(void)       //busclock 32M
{   
   
   CLKSEL_PLLSEL=0;	 //总线时钟来源于晶振 
           
   PLLCTL_PLLON=0;  //先关闭PLL

   SYNR=0x40 | 0x03; 	
   REFDV=0x80 | 0x01;              
   POSTDIV=0x00;  //PLL配置为64MHz     

   PLLCTL_PLLON=1;  //打开PLL

   _asm(nop);         
   _asm(nop);
   while(!(CRGFLG_LOCK==1)); //确定PLL是否稳定LOCK=1 稳定,=0 不稳定  
   CLKSEL_PLLSEL =1;     //总线时钟来源于PLL		       
}

void init_pwm(void) 
 {
  PWMCTL_CON01= 1;   //级联0号和1号通道形成16位PWM通道号,由PWM1输出
  PWMPOL_PPOL1= 1;   //通道01的极性为高电平有效
  PWMPRCLK = 0x55;   //A时钟和B时钟的分频系数为32,频率为1MHz
  PWMSCLA  =   25;   //SA时钟设置寄存器
                     //CLOCK SA=CLOCK A/(2*PWMSCLA)
                     //CLOCK SA=1M/2*25=20KHz
  PWMCLK =0x02;      //通道01用SA时钟作为时钟源
  PWMPER01  = 200;   //通道01的周期为100Hz 
  PWMDTY01  = 0;     //通道01的占空比为0%  
  PWME_PWME1 = 1;    //使能通道01
 }

void delay(void) 
{
    unsigned int i,j;
    for(i=0;i<20;i++)
      for(j=0;j<50000;j++);
}


void main(void) {
  DisableInterrupts;       //禁止所有中断打开
  INIT_PLL();              //初始化PLL模块
  init_pwm();              //初始化pwm模块
  LEDCPU_dir=1;            //设置连接发光二级管的PORTB_PB0口为输出口
  LEDCPU=1;                //初始化发光二极管为亮
  EnableInterrupts;        //允许所有中断打开

  for(;;) 
  {
      delay();
      PWMDTY01=20;     //占空比为10%
      delay();
      PWMDTY01=40;     //占空比为20%
      delay();
      PWMDTY01=60;     //占空比为30%
      delay();
      PWMDTY01=80;     //占空比为40%
      delay();
      PWMDTY01=100;     //占空比为50%
      delay();
      PWMDTY01=120;     //占空比为60%
      delay();
      PWMDTY01=140;     //占空比为70%
      delay();
      PWMDTY01=160;     //占空比为80%
      delay();
      PWMDTY01=180;     //占空比为90%
      delay();
      PWMDTY01=200;     //占空比为100%
      delay();
      PWMDTY01=180;     //占空比为90%
      delay();
      PWMDTY01=160;     //占空比为80%
      delay();
      PWMDTY01=140;     //占空比为70%
      delay();
      PWMDTY01=120;     //占空比为60%
      delay();
      PWMDTY01=100;     //占空比为50%
      delay();
      PWMDTY01=80;       //占空比为40%
      delay();
      PWMDTY01=60;      //占空比为30%
      delay();
      PWMDTY01=40;      //占空比为20%   
  }                     
}

将P1脚接到B口的任意一个管脚就可以看到所对应的LED做出呼吸灯一样的状态了

你可能感兴趣的:(单片机)