工具/软件:Code Composer Studio
大家好、我正在使用 msp430fr2355、我正在尝试使用 TB0实现以毫秒和微秒为单位的阻止延迟。 我最近需要在我的代码中使用这些代码。
当我以毫秒为单位延迟时、定时器 TB0以 SMCLK 为源。
当我以微秒为单位进行延迟时、定时器 TB0由 ACLK 提供。
我想使用 TB2和 TB3来实现两个 PWM、这两个 PWM 都来自 SMCLK。
我可以让两个 PWM 都以毫秒为单位工作、但当我更改并使用微秒为单位的延迟时、PWM 的频率和延迟也会发生变化。 为什么会发生这种情况? 我缺少什么?
以下是我的代码:
uint16_t ms_counter;
uint16_t us_counter;
void delay_ms (uint16_t delay_ms)
{
MS_COUNTER = 0;
TB0CCTL0 |= CCIE; // TBCCR0中断被使能
TB0CCR0 = 33;
TB0CTL |= TBSSEL_ACLK | MC__UP; // ACLK、连续模式
while (ms_counter!= delay_ms);
ms_counter = 0;
}
void delay_us (uint16_t delay_us)
{
US_COUNTER = 0;
TB0CCTL0 |= CCIE; // TBCCR0中断被使能
TB0CCR0 = 24;
TB0CTL |= TBSSEL_SMCLK | MC__UP; // ACLK、连续模式
while (us_counter!= delay_us);
US_COUNTER = 0;
}
void init_clock (void)
{
//根据 MCLK 的器件数据表的要求配置两个 FRAM 等待状态
//在24MHz (超过8MHz)_Before 配置时钟系统。
FRCTL0 = FRCTLPW | NWAITS_2;
P2SEL1 |= BIT6 | BIT7; // P2.6~P2.7:晶振引脚
操作
{
CSCTL7 &=~(XT1OFFG | DCOFFG); //清除 XT1和 DCO 故障标志
SFRIFG1 &=~OFIFG;
} while (SFRIFG1和 OFIFG); //测试振荡器故障标志
_bis_SR_register (SCG0); //禁用 FLL
CSCTL3 |= SELREF_XT1CLK; //将 XT1设置为 FLL 基准源
CSCTL0 = 0; //清除 DCO 和 MOD 寄存器
CSCTL1 |= DCORSEL_7; //设置 DCO = 24MHz
CSCTL2 = FLLD_0 + 731; // DCOCLKDIV = 24MHz
_DELAY_CYCLES (3);
_BIC_SR_register (SCG0); //启用 FLL
while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));// FLL 锁定
CSCTL4 = SELMS_DCOCLKDIV | SELA_XT1CLK;//将 XT1 (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz
//默认 DCOCLKDIV 作为 MCLK 和 SMCLK 源
}
void init_pwm_pins (void)
{
//配置 GPIO
//右侧 PWM P5.0,左侧 PWM P6.0
// P1DIR |= BIT0 | BIT1; //将 ACLK SMCLK 引脚设置为输出
// P1SEL1 |= BIT0 | BIT1; //将 ACLK 和 SMCLK 引脚设置为第二功能
P5DIR |= BIT0;
P5SEL0 |= BIT0;
P6DIR |= BIT0;
P6SEL0 |= BIT0;
SMCLK 和 SMCLK 的//记住计时器设置为24MHz
//设置 P6.0的 Timer3_B7
TB3CCR0 = 1000-1; // PWM 周期
TB3CCTL1 = OUTMOD_7; // CCR1复位/置位
TB3CCR1 = 500; // CCR1 PWM 占空比
//设置 P5.0的 Timer2_B3
TB2CCR0 = 1000-1; // PWM 周期
TB2CCTL1 = OUTMOD_7; // CCR1复位/置位
TB2CCR1 = 500; // CCR1 PWM 占空比
//
TB2CTL = TBSSEL_2 | MC_1 | TBCLR; // SMCLK、向上计数模式、清除 TBR
TB3CTL = TBSSEL_2 | MC_1 | TBCLR; // SMCLK,向上计数模式,清除 TBR
}
int main (void)
{
MSG_Received=0;
//ms_counter_value = 0;
WDTCTL = WDTPW | WDTHOLD; //停止 WDT
P3DIR |= BIT6;
P3OUT &=~BIT6;
init_clock();
init_pwm_pins ();
PM5CTL0 &=~LOCKLPM5;
_enable_interrupt ();
while (1)
{
P3OUT ^= BIT6;
delay_ms (1000);
//_bis_SR_register (LPM3_bits | GIE); //输入 LPM3
}
//__no_operation(); //用于调试
}
//计时器 B0中断服务例程
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = TIMER0_B0_Vector
__interrupt void Timer_B (void)
#Elif defined (__GNU__)
#void __attribute_(TIMER0_bvector
)(void Timer_b0)(void Timer_bid)(void Timer0_error)(void Timer0_bid)(void Timer0_bid)(void)
#endif
{
ms_counter++;
US_COUNTER++;
}
提前感谢!
Diana