MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波

MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波

MSP430F5529的定时器还是挺好用的,具有定时计数和捕获的功能,具有高达7个捕获比较寄存器,支持多路捕获/比较。这里我用到了两个定时器产生两个反相的PWM波并通过一个捕获比较器捕获其中一个PWM波,显示在OLED12864显示屏上(本实验使用的是MSP-EXP430F5529LP开发板,使用的软件是IAR)。

实现的功能为:
1、利用MSP430内部PWM波发生器产生两路反相频率为 50Hz到1KHz,占空比为10%到90%的PWM波。
2、要求频率和占空比通过按键S1和S2分别设置。频率按50Hz步进,占空比按10%步进。
3、利用MSP430单片机的捕获/比较器测量该PWM波 的频率和占空比,且显示于oled屏幕上。

(这里使用的显示屏是四针的oled12864)
连接方式为SDA口连接P6.5
SCL口连接P6.0
同时使用的VCC是3V

P1.2口和P1.4口输出反相的可调频率和周期的PWM波
P2.0为捕获输入,所以需要连接P1.2口和P2.0口
连接图如下:
MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波
上代码

定时器设置:

/************************************************************
  文件名称:                timer.c
  文件概述:                对TA0输出PWM波 TA1进行输入捕获的配置工作
  包含的头文件及概述:      timer.h :函数声明及部分宏定义                         
  引脚声明:                
                            TA0 PWM波输出口   :P1.2    P1.4
                            TA1 输入捕获输入口:P2.0
*************************************************************/ 


#include 	"msp430f5529.h"
#include  	"timer.h"

char flag=0;                       //用于标记当前捕获状态 0:就绪 1:捕获到一个上升沿 2:捕获到一个下降沿 
unsigned int pos_time=0;          //用于记录正脉宽
unsigned int period  =0;          //用于记录周期


unsigned int start   =0;          //开始测量上升沿
unsigned int pause   =0;
unsigned int num[3];
unsigned int T,TP,D;
/******************

PWM波初始化
输出两种反相的PWM波

********************/
void PWM_Init( void )
{
        
	P1DIR |= BIT2; //配置P1.2复用为定时器TA0.1
        P1SEL |= BIT2; //配置P1.2为输出
        P1DIR |= BIT4; //配置P1.4复用为定时器TA0.3
        P1SEL |= BIT4; //配置P1.4为输出
        TA0CTL = TASSEL_2 + MC_1 + TACLR + ID_3;//使用SMCLK为时钟源 增计数模式 8分频
        TA0CCTL1 = OUTMOD_7 ; //TA0输出模式7
        TA0CCTL3 = OUTMOD_3 ; //TA3输出模式3
        TA0CCR0 = 10000 ;   //初始化频率50赫兹
        TA0CCR1 = 1000 ;    //初始化占空比为10%
        
}

/******************
捕捉器初始化
Capture 函数

********************/

void Capture_Init(void)
{
          P2DIR &= ~BIT0 ; //配置P2.0复用为定时器TA1.1
          P2SEL |= BIT0 ; //配置P2.0为输入
   
          TA1CTL = TASSEL_2 + MC_2 + TACLR + ID_3 ; //使用SMCLK为时钟源 连续计数模式 8分频
          TA1CCTL1 = CM0 + SCS + CAP + CCIE +CCIS_0; //捕获模式 上升沿捕获 同步 中断使能 CCI1A(P 2.0)
        _BIS_SR( GIE );		                //使能系统总中断
}

/*中断子函数*/

#pragma	vector = TIMER1_A1_VECTOR
__interrupt void Timer_A1 ( void )
{
  if(TA1IV==2)
  {
    if(P2IN&BIT0)
    {
      if(flag==0)
      {
        start = TA1CCR1;
        flag = 1;
      }
      if(flag==2)
      {
        period = TA1CCR1-start;
        flag=3;
        TA1CCR1 = 0;
        TA1CCTL1&=~CCIE;
      }
      else
      {
        if(flag==1)
        {
          pos_time = TA1CCR1-start;
          flag = 2;
        }
      }
      
    }
  }
  
}


按键设置:

/********************************************************************************* 
  *Copyright(C),UESTC
  *FileName:    独立按键配置
  *Author:      Tonge
  *Version:     1.0 
  *Date:        2016.12.2
  *Description:  配置msp430f5529的独立按键

                  MSP430F5529
              -----------------
         /|\|                 |
         |  |                 |
         ---|RST              |
            |             P2.1|-->KEYLEFT
            |             P1.1|-->KEYRIGHT
  *Others:      None
  *Function List:  
         1.void KeyInit(void) 独立按键配置初始化,上电调用一次即可。
         2.enum key_type KeyScan(void)按键扫描程序返回枚举型键值
                  其中key_type{NOKEY,KEYLEFT,KEYRIGHT};
**********************************************************************************/  
#include 	"msp430f5529.h"
#include  	"key.h"

static	enum    key_type key_value = NOKEY;
static  int 	key_down_flag = 0;
enum key_type	KeyScan(void)
{
        
	if( KEY_L )	
            key_value = KEYLEFT;
        
	else if( KEY_R )		
            key_value = KEYRIGHT;
        
        else
            key_value = NOKEY;
        
        //防止一次按下多次响应,不等待按键抬起,不过多占用CPU
        if      (key_down_flag == 0 && key_value != NOKEY)
        {
            key_down_flag = 1;//第一次监测到按键,按下标志置位,返回此时键值

        }
        else if (key_down_flag == 1 && key_value != NOKEY)
        {
            key_value     = NOKEY;//第一次之后检测按键按下,返回空值
        }
        else
        {
            key_down_flag = 0;//检测按键抬起,按下标识复位,为下一次按下准备
        }
	                        
	return	key_value;
}
void KeyInit(void)
{
	P1DIR	&= ~BIT1;       //设置按键IO为输入模式
	P2DIR	&= ~BIT1;
        P1REN   |= BIT1;        //使能按键上、下拉电阻
        P2REN   |= BIT1;
        P1OUT   |= BIT1;        //设置按键IO为上拉电阻模式
        P2OUT   |= BIT1;
}

主函数:

/***************************************************
采用TI公司的MSP430F5529芯片
使用MSP-EXP430F5529LP开发板
实现的功能为:
1、利用MSP430内部PWM波发生器产生频率为 50~1kHz,占空比为10%~90%的PWM波。 
2、要求频率和占空比通过按键S1和S2分别设置。频 率按50Hz步进,占空比按10%步进。
3、利用MSP430单片机的捕获/比较器测量该PWM波 的频率和占空比,且显示于oled屏幕上。

(这里使用的显示屏是四针的oled12864)
连接方式为SDA口连接P6.5
          SCL口连接P6.0
          同时使用的VCC是3V
 
 P1.2口和P1.4口输出反相的可调频率和周期的PWM波
 P2.0为捕获输入,所以需要连接P1.2口和P2.0口
***************************************************/

#include "MSP430F5529.h"
#include "clk.h"
#include "key.h"
#include "timer.h"
#include "IIC.h"

/****************需要显示的一系列字符串***************/
  unsigned char string1[]={"PWM&Capture"};
  unsigned char string2[]={"Frequency:"};
  unsigned char string3[]={"post_duty:"};
  unsigned char string4[]={"Hz"};
  unsigned char string5[]={"%"};
  
void  main( )
{
  enum key_type key;
  unsigned int duty_num=10; //用于控制占空比的变量
  unsigned int fre_num=100; //用于控制频率的变量              
  float  duty=0;           //用于计算占空比
  float  fre=0;            //用于计算频率
  
  WDTCTL = WDTPW+WDTHOLD;  // 关闭看门狗
  ClkInit();               //时钟初始化
  KeyInit();               //独立按键初始化
  LCD_Init();              //显示屏初始化
  PWM_Init();              //PWM波输出初始化
  Capture_Init();          //输入捕获初始化
  
  /*初始化界面*/
  //LCD_ShowString(0,0,string1,16);
  LCD_ShowString(0,0,string2,12);
  LCD_ShowString(0,2,string3,12);
  LCD_ShowString(112,0,string4,12);
  LCD_ShowString(112,2,string5,12);
  
  while(1)
  {
    key = KeyScan();
    if( key != NOKEY )
    {
      switch(key)
      {
        case KEYLEFT : 
          {
            duty_num+=10;
            
            if(duty_num>90) //防止占空比超出范围
            {
            duty_num=10;
            }
            break;
          }      
        case KEYRIGHT :   
          {
            fre_num+=100;
            if(fre_num>2000) //防止频率超出范围
            {
              fre_num=100;
            }
            
            break;
          }
      }
      TA0CCR0=1000000/fre_num ;
      TA0CCR1=(int)(TA0CCR0*(((float)duty_num)/100));
      TA0CCR2=TA0CCR0;
      TA0CCR3=TA0CCR1;
    }
     if(flag==3)
    {
     duty = 100*(((float)pos_time)/((float)period))+1; //计算占空比
     fre=500000/(float)period+1;  //计算频率
     LCD_ShowNum(87,0,(unsigned long)fre,3,12); //显示占空比和频率 
     LCD_ShowNum(87,2,duty_num,3,12); 
      
      flag=0;
      TA1CCTL1|=CCIE;
    }  
  }
}
  

大概的设置就是这样了,放上几张演示图
MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波
MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波
MSP430F5529通过定时器A产生两个反相频率占空比可调PWM波
我也是初学,很多地方都不太懂,错误的地方还请大家斧正。
也欢迎大家和我交流!

另外需要源码的童鞋,我把代码放在下面的链接里了,免费下载。
链接: link.

上一篇:基于STC8G1K17的信号转换方案


下一篇:电力电子技术 第7章 PWM控制技术