代码编织梦想

可恶的慕课老师啊,给了一堆毫无逻辑的代码,最后还是我自己整出来。

真是可恶啊!

感谢大佬,王冬冬,一点就通,万分感谢!

msp430代码资料挺少,这不,整出来一个,小细节就不说了,就给各位看看原理。

哈哈,小菜鸡,赶紧那去跑吧--------------------

/******************************************************************************
  文件说明:
    按下左键:修改频率 50、155、261、366、472、577、683、[788、894、999]
    按下右键:修改占空比 
      
      
******************************************************************************/
/*
    利用MSP430内部PWM波发生器产生频率为50~1KHZ,占空比为10%~90%的PWM波,
    频率和占空比通过按键设置,
    并利用MSP430单片机的捕获/比较器测量该PWM波的频率和占空比,且显示于数码管上
*/

#include <msp430f5529.h>
#include "IIC.h"         //包含IIC通信功能与显示函数文件



int Pos_X=50,Pos_Y=2;
int vpp=2500;// 参考电压mv
int ccr0=0;// ccr0的值
int duty_Cilcle=0;// 占空比值
int countP11 =0;// P1.1按下次数
int countP21 =0;// P2.1按下次数
unsigned int Cycle[3];// 用于保存连续2次上升沿捕获的值+1次下降沿捕获的值
int i=0;
int overflow=0;// 溢出次数
unsigned long interval_freq=10555;// 计算频率间隔
int frequency=0;// 频率调整
unsigned long measure_freq=0;//测量频率
unsigned int measure_cycle=0;// 测量占空比
unsigned long cycle0=0,cycle1=0;// 记录捕获次数
void delay()//延时函数
{
  unsigned int i;
  i = 40000;                              
  do (i--);
  while (i != 0); 
}
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  
  // 按键IO初始化    
  P1DIR &= ~BIT1;// 输入方向 
  P1IE |= BIT1;// 允许中断
  P1IES |= BIT1;// 下降沿中断
  P1REN |= BIT1;// 上拉使能
  P1OUT |= BIT1;
  
  P2DIR &=~BIT1;
  P2IE |= BIT1;
  P2IES |= BIT1;
  P2REN |= BIT1;
  P2OUT |= BIT1;
  
  P1DIR |= BIT0;        // led初始化
  P4DIR |= BIT7;
  
  
  
  LCD_Init();                                   // 初始化显示屏    
  LCD_ShowString(Pos_X-40,Pos_Y,"Duty",16);
  LCD_ShowChar(Pos_X+50,Pos_Y,'%',16);
  LCD_ShowString(Pos_X-40,Pos_Y+2,"frequ",16);
  LCD_ShowString(Pos_X+60,Pos_Y+2,"Hz",16);
  
   
  // PWM 配置
  P2DIR |= BIT0;                                  // P2.0 
  P2SEL |= BIT0;                       // P2.0 and P2.1 options select
  ccr0=655;
  TA1CCR0 = ccr0-1;                          // PWM Period  50Hz = 0.02s
  TA1CCTL1 = OUTMOD_7;                      // CCR1 reset/set
  duty_Cilcle=65;
  TA1CCR1 = duty_Cilcle;                            // CCR1 PWM duty cycle      10%占空比

  TA1CTL = TASSEL_1 + MC_1 + TACLR;         // ACLK, up mode, clear TAR
  
  // 捕获模式配置
  P1DIR &=~BIT2;        // P1.2捕获输入
  P1SEL |= BIT2;
  TA0CTL=TASSEL_2+TAIE+MC_1+TACLR;// up mode
  TA0CCR0=65535-1;
  TA0CCTL0 = CCIE; 
  TA0CCTL1=CAP+CM_1+CCIE+SCS+CCIS_0;// 上升沿捕获
  

  __bis_SR_register(GIE);
  while (1){ 
    LCD_ShowNum(Pos_X+10,Pos_Y+2,measure_freq,4,16);// 显示频率
    LCD_ShowNum(Pos_X+10,Pos_Y,measure_cycle,2,16);// 显示周期
  };
 
  
}
// TimeA - 捕获中断函数
#pragma vector=TIMER0_A1_VECTOR //定时器A中断处理 
__interrupt void timer_a(void) 
{ 
      switch(TA0IV)       
      { 
      case 2:
        
        Cycle[i]=TA0CCR1;
        ++i;         
        
        if(i==2)        // 捕获了2次上升沿
        {
     
          if(overflow>0)
          {
            cycle0 = 65535-Cycle[0]+(overflow-1)*65535+Cycle[1];
            overflow=0;
          }
          else
            cycle0=Cycle[1]-Cycle[0];
          measure_freq = 1045000/cycle0;// 求频率          
          
          // 修改为下降沿捕获
          TA0CCTL1=CAP+CM_2+CCIE+SCS+CCIS_0;
        }
        // 第3 次计算占空比
        
        if(i==3)
        {
          
          if(overflow>0)// 存在定时器溢出次数
          {
            cycle1 = 65535-Cycle[1]+(overflow-1)*65535+Cycle[2];// 捕获间隔计数值
            overflow=0;
          }
          else
            cycle1=Cycle[2]-Cycle[1];
          measure_cycle=cycle1*100/cycle0;
          TA0CCTL1=CAP+CM_1+CCIE+SCS+CCIS_0;// 改回上升
          i=0;
        }
                
        TA0CCTL1&=~CCIFG;// 清空捕获标志
      

        break;
      default:            
        break;       
      } 
}

#pragma vector=TIMER0_A0_VECTOR //定时器A中断处理 
__interrupt void Overflow(void) 
{
    if(i==1)
      ++overflow;
    P1OUT ^=BIT0;
    P4OUT ^=BIT7;
  
}

// P1.1中断函数——修改频率50-1KHz
#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void)
{
  delay();
  if(P1IFG&BIT1)
  {
    while((P1IN&BIT1)==0);
    ++countP11;
    countP11 %=10;

    frequency = interval_freq*countP11/100+50;
    ccr0 = 32768.0/frequency;
    TA1CCR0 = ccr0-1;   

    duty_Cilcle =ccr0*0.1*(countP21+1);
    TA1CCR1=duty_Cilcle;
       
  }
  P1IFG &=~BIT1;                // 清除标志
}


// P2.1中断函数——修改占空比10%—90%
#pragma vector=PORT2_VECTOR
__interrupt void P2_ISR(void)
{
  delay();
  if(P2IFG&BIT1)
  {
    while((P2IN&&BIT1)==0);
    ++countP21;
    countP21 %=9;
    duty_Cilcle =ccr0*0.1*(countP21+1);// 占空比+10%
    TA1CCR1=duty_Cilcle;
    
    
  }
  P2IFG &=~BIT1;                // 清除标志
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_52519271/article/details/131027795