MSP430F5529实现LED1无极调光

余生颓废 提交于 2020-01-20 20:35:14

概述

  • 使用TA0的比较模式输出方波,驱动LED1.
  • 方波的频率较小时用相机拍摄LED时会发现在闪烁,为了让相机不能发现LED在闪烁,使用25MHz的时钟源。通过DCO-FLL得到。
  • 机械按键会抖动,使用TA1定时扫描按键,消除抖动。
  • 英文注释部分是code example经过修改的

代码

#include <msp430.h>

void SetVcoreUp (unsigned int level);

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;       //关闭看门狗

  P1DIR &= ~BIT1;                 //把P1.1配置为输入。
  P1REN |= BIT1;                  //启用上/下拉电阻
  P1OUT |= BIT1;                  //使用上拉电阻

  P2DIR &= ~BIT1;                 //把P2.1配置为输入。
  P2REN |= BIT1;                  //启用上/下拉电阻
  P2OUT |= BIT1;                  //使用上拉电阻

  // Increase Vcore setting to level3 to support fsystem=25MHz
  // NOTE: Change core voltage one level at a time..
  SetVcoreUp (0x01);
  SetVcoreUp (0x02);
  SetVcoreUp (0x03);

  UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
  UCSCTL4 = UCSCTL4 = UCSCTL4&(~(SELA_7 | SELS_7)) | ( SELA__DCOCLK | SELS__REFOCLK );   // 设置ACLK选择DCOCLK,SMCLK选择REFOCLK

  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_7;                      // Select DCO range 50MHz operation
  UCSCTL2 = FLLD_0 + 762;                   // Set DCO Multiplier for 25MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (762 + 1) * 32768 = 25MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
  __delay_cycles(782000);

  // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

  P1DIR |= BIT2;                       // 配置P1.2为输出
  P1SEL |= BIT2;                       // 选择外设功能,作为定时器A的比较模式输出

  TA0CCR0 = 500;
  TA0CCTL1 = OUTMOD_7;                      //输出模式7
  TA0CCR1 = 0;                            //配置CCR1,控制占空比
  TA0CTL = TASSEL_1 + MC_1 + TACLR;         // 定时器使用ACLK, 增计数模式, 清除计数器的计数值。
  /*****************************************************************************************************/
  /*配置TA1,用来扫描按键,给按键消抖*/
  TA1CTL = TASSEL_2 + MC_1 + TACLR;         // SMCLK, 增计数模式, clear TAR
  TA1CCTL0 = CCIE;                          // CCR0 interrupt enabled
  TA1CCR0 = 60;
  /*****************************************************************************************************/
  __bis_SR_register(LPM4_bits+GIE);     //进入低功耗模式4,打开全局中断。
  __no_operation();                      // For debugger
}
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
       static unsigned key1_now=0;
       static unsigned key2_now=0;
       unsigned key1_past=0;
       unsigned key2_past=0;
       key1_past=key1_now;
       key2_past=key2_now;
       if( P1IN&BIT1 )
             key1_now=1;
       else
             key1_now=0;
       if( P2IN&BIT1 )
             key2_now=1;
       else
             key2_now=0;
       if( (key1_past==1)&&(key1_now==0) )
       {
             if(TA0CCR1>0)
                                 TA0CCR1 -= 20;
       }
       else if( (key2_past==1)&&(key2_now==0) )
       {
             if(TA0CCR1<TA0CCR0)
                                 TA0CCR1 += 20;
       }
}
void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!