概述
- 使用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;
}
来源:CSDN
作者:乔宕一
链接:https://blog.csdn.net/qq_36148047/article/details/104054824