您好!
这是我第一次使用 MSP430。
我开始处理一个使用 MSP430的项目。 一个老男人为 这个项目写了程序,我被要求修复它。
他不知道如何使用计时器、因此他执行了非常低效的延迟(具有"for "循环的函数)
现在、我想使用计时器和中断来提高 其效率。
但我不想太多(至少还没有)更改原始程序 ,因为它很长,而且可以正常工作。
因此、我需要一个延迟函数、该函数激活计时器、然后将 CPU 置于 LPM0中并等待中断
但是,我无法返回到延迟时间的"主要"地点。
我该怎么做?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
这是我第一次使用 MSP430。
我开始处理一个使用 MSP430的项目。 一个老男人为 这个项目写了程序,我被要求修复它。
他不知道如何使用计时器、因此他执行了非常低效的延迟(具有"for "循环的函数)
现在、我想使用计时器和中断来提高 其效率。
但我不想太多(至少还没有)更改原始程序 ,因为它很长,而且可以正常工作。
因此、我需要一个延迟函数、该函数激活计时器、然后将 CPU 置于 LPM0中并等待中断
但是,我无法返回到延迟时间的"主要"地点。
我该怎么做?
这是每个人似乎都需要的东西之一、但没有公开的示例。 这是一个小型/简单的解决方案。
它使用 Timer A (下面的"TA0")、但可以更改为使用 Timer B ("TB0")。 我在 Launchpad 上的 G2553上运行了该程序。
标准免责声明:无保修、无支持、等等。
[编辑:更正了拼写错误]
////// tddemo.c // 使用计时器 A0实现简单延迟和时钟。 // 设置 DEMO=1进行演示。 // 无保修、无支持、等等。 // #define demo 1. //在 #include 下包含 main()程序 #include define Hz 1000000UL //复位时时钟为~1MHz //#include "timer.h" //您可能需要其中一个最终 为 extern void timer_init (void); //您可以 extern void timer_wait_ms (uint16_t ms);//将这些 extern uint16_t timer_fetch (void);// 变量 uint16_t timer_ms; #pragma vector=TIMER0_A0_vector __interrupt void timer_ISR (void) { ++定时器_ms; //时钟节拍 LPM0_EXIT; //唤醒前台 return; } void timer_init (void) { TA0CCR0 = Hz / 1000 - 1; // 1ms 节拍 TA0CCTL0 = CCIE; //中断 TA0CTL = tassel_2 | ID_0 | MC_1 | TACLR;// SMCLK/1、向上计数模式(、清除) return; } uint16_t timer_fetch (void) { 返回(timer_ms); //这很简单 } void timer_wait_ms (uint16_t ms) { uint16_t start = timer_fetch (); while (timer_fetch ()- start < ms)//区分可避免一些竞争 LPM0; //每1ms 唤醒一次以查看。 return; } #if demo // //// main() // int main (void) { WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器 // Launchpad P1.0 LED P1OUT &=~BIT0; //初始关闭(高电平有效) P1DIR |= BIT0; //输出 timer_init(); _enable_interrupt (); while (1) { P1OUT ^= BIT0; //切换 LED 以显示 Timer_wait_ms (500); // 500ms -> 1Hz 闪烁 } /*NOTREACHED*/ 返回0; } #endif // demo
多种不同的实现方式。
我的应用中通常有一个自由运行的计时器、用于返回当前计时器节拍。 这样、下面的一段简单代码就可以正常工作:
如果(tectches_Now ()- tectces_prev > DLY_ticks){//是否已经历足够的 tick
ticks_prev += DLY_ticks;//更新前一个 tick 计数器
do 什么();//执行用户代码
}
这种方法允许从一个(自由运行)定时器执行多个任务。 它具有高度便携性。 其缺点是如果 main()循环太长,它会受到抖动的影响。
如果需要更多的实时应用程序,您可以安装一个计时器 ISR 来执行您的代码(如果它很短),或者在 main()循环中生成一个用于执行它的标志-同样,它受抖动的影响-如下所示:
如果(timer_OVF ()){//if time is up - timer_OVF ()自行清除该标志
do 什么();//执行用户代码
}