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.

[参考译文] MSP430F5638:TB0 PWM 和 ISR 问题

Guru**** 2024750 points
Other Parts Discussed in Thread: MSP430F5638
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1015251/msp430f5638-tb0-pwm-and-isr-questions

器件型号:MSP430F5638

使用 CCS v10、并且当前在定制 SBC 上运行 MSP430F5638。 使用 TB0创建用于 LED 调光的 PWM。 TB0工作正常、在示波器上获得所需的频率和占空比。 但我有很多问题。 我包含了与完整版相同的简化版部分。 完整程序会将大量数据发送到所连接的 LCD 以进行测试和开发-为清晰起见、删除了该代码。

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
// setup functions
// setup_430_ports();
setup_430_clocks(); // use XT2 @ 20 MHz
// setup testing for LED PWM Dimmer
set_LED_TB0_dim();
// no code accessible after LED function runs
// LCD_put_string_4_cc(170, 20, "AFTER LED TB0 CALL", red, white);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void set_LED_TB0_dim(void)
{
float xt2 = 20e6, frequency, dutycycle;
WDTCTL = WDTPW+WDTHOLD; // Stop WDT
P4SEL |= BIT6; // P4.6 peripheral option select
P4DIR |= BIT6; // P4.6 output
// left most 0 not required since only 1 TB
TBCCR0 = 100; // set CCR0 cycle period register
TBCCTL6 = OUTMOD_7; // set CCR6 Output mode, reset/set
TBCCR6 = 50; // set CCR6 PWM duty cycle
TBEX0 = 0; // has no effect, 0 = '/1' by default
// enable CCR6 interrupt - required for ISR to run
// but disables TB0, no PWM out
//TBCCTL6 = CCIE;
// ID_0 = /1 by default
// add enable interrupt - not necessary (+ TBIE), removed
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

main()问题

1.在调用 SET_LED_TB0_DIM ()后,为什么 main()中的任何代码都不运行?

Set_LED_TB0_DIM ()问题

  1. MSP430F5638只有一 TB、因此看起来0后缀是多余的 TBCCR0、TB0CCR0都起作用
  2. TBCCTL6 = ISR 运行需要 CCIE、但禁用 TB0、无 PWM 输出
  3. 为什么 SET_LED_TB0_DIM ()进入 LPM 模式? 没有它就无法运行。
  4. 为什么需要 CCIE、但不需要 TBIE?
  5. __bis_SR_register (LPM0_bits + GIE)可与 LPM0_bits 配合使用或不与 LPM0_bits 配合使用(我不是实时检查功耗–但看起来是相同的142ma)

我真的不希望 TB0将 CPU 放入 LPM 中、但没有它、代码就无法运行。

ISR 问题

为什么 ISR 名称在矢量和函数名称中要求 B1、而不要求 B0? 这是 TB0、但不适用于 B0。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看到两个问题。

    第一个是注释掉启用定时器中断的代码。 这意味着当您设置 LPM0时、没有 ISR 导致退出。 当然、您启用中断的代码也会对该寄存器中先前的设置进行削减、这就是 PWM 停止的原因。 "|="可能是您的意思。

    但是、如果启用了中断、您没有太多时间为 ISR 提供服务。 我怀疑大约100个 SMCLK 周期与 MCLK 相同。 LCD 字串调用很容易会消耗更多的电量。 这意味着在 ISR 返回之前会触发另一个计时器中断。 一种启动时钟周期主程序的可靠方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回答。 我未注释 的 TBCCTL6 = CCIE;

    将 TBCTL =更改为|=

    并从 ISR 中删除了 LCD 语句。 TB0未运行、上面未注释的语句没有任何输出。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我期待大卫的意思  

    TBCCTL6 |= CCIE;   //启用 CCR6 IFG,但保持 OUTMOD 置位

    TBIE 被忽略、原因是:

    > 案例14:中断;  

    [编辑:对于您的最后一个问题、 TIMERB1_vector 正式为 TIMER0_B1_vector、其中 B0_vector (仅)应用于 CCR0、B1_vector 应用于所有其他器件。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Bruce 和 David;现在 TB0 PWM 和 ISR 都在同时运行。 我还有其他问题:main 1、SET_LED 1、3、5和 ISR 1。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    main() 1:正如 David 指出的,你没有设置 TB0CCTL6:CCIE,所以 LPM 永远不会被吵醒。

    SET_LED 1:TB0是规范名称。 如果您将代码移动到具有2个 Tb/s 的器件、则会有"TB"和"TB1"、这将很难读取。

    Set_LED 3: 请描述您的症状。

    SET_LED 5:请描述您的症状。

    ISR 1: TIMERB1_Vector 正式为 TIMER0_B1_VECTOR、其中 B0_VECTOR (仅限)应用于 CCR0、B1_VECTOR 应用于所有其他对象。 [参考用户指南(SLAU208Q)第18.2.6节]

    主动:正如 David 指出的、您的计时器运行速度非常快。 如果不使 CPU 饱和、ISR 中就无法执行其他操作。 (您也无法读取每5微秒变化一次的 LCD。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Bruce、

    主要() 1 ----------------------------------------------

    我现在将 通过 TB0CCTL6 = OUTMOD_7 + CCIE 来设置 CCIE;

    我的 ISR 案例是这样的

    案例12:// CCR6溢出

    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0,只能从 ISR 运行
    LCD_PUT_STRING_4_cc (170、20、"在 TB0 ISR 案例12中"、红色、白色);
    中断;

    LCD 语句运行、如果我将其注释掉、我仍然有问题。  main 中没有任何内容、在调用 SET_LED 运行后、我仍然对此执行错误操作。

    SET_LED 3和5 --------------------------------------------------

    此仪器将在 RTC 设置的2秒周期运行。 它会启动、读取数据、执行它的操作、更新 LCD 并返回到睡眠状态。 有几个按钮、每个按钮都有自己的 ISR、大多数按钮只是设置一个全局变量、主第二个循环会处理该全局变量。 但是、一个开关将通过连续按来设置功率级别来打开 LED 闪光灯、最后将其关闭。 这就是我不希望 SET_LED 函数进入 LPM 的原因。 但没有它、函数就无法运行。 还有其他选项吗?

    定时器运行得很快-------

    TB0必须生成100KHz 至1MHz 的方波信号才能驱动 LED 驱动器 IC。 ACLK 太慢、但我可以将 SMCLK 除以8、并且仍然会从100KHz 到800KHz 获取脉冲、或/4以准确地达到范围。 这应该有所帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    让计时器以200kHz (甚至1MHz)的频率生成 PWM 是可以的。 以200kHz (或400kHz、如果您仍在设置 TBIE)中断是另一种情况、因为每个 ISR 需要大约30个 CPU 时钟才能进入和退出。 由于 您的所有 CPU 都专用于 ISR 调用、因此未执行 main()。

    如果该 LCD 调用正在更新(人类可读)显示、则每秒更新200、000次没有任何价值、因为人类可能无法这么快地读取它。

    我建议您采用另一个计时器(您有4x+RTC 可供使用)并以人机速度运行该计时器、例如每秒1-2次中断、以更新显示。 让 TB0在后台独立运行(无中断)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在从中断连接到 CPU 上的情况下、这是可以的。

    我最初的问题之一是:如何在不创建任何中断的情况下将 TB0用作 PWM 发生器。 我从不需要 TB0 ISR。 我想使用 TB0作为自打开时起的哑铃脉冲发生器、直到我决定将其关闭。

    LCD 每2秒更新一次。 我只在 ISR 中卡住了一个调用、以查看它是否实际到达那里-它是这样的。

    我用于 TB0的两个 TI 示例是:msp430f66xx_TB_03.c 和 msp430f66xx_10.c、10个示例调用_ bis_SR_register (LPM0_bits + GIE);为什么它会调用它呢?

    ----------------------------------------------------

    我想知道:如何将 TB0用作单调 PWM 而不使用 ISR!

    请勿设置 CCIE 或 TBIE、并注释掉_bis_SR 调用、程序流正常、但 TB0不执行任何操作。 嗯、不是真的、在 main 结束前、示波器上有一个非常短的脉冲闪存(如果我在正确的微秒时间内查看示波器)并关闭所有外设。 向该测试代码添加了一个循环、以查看脉冲稳定状态。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    许多示例在 main()末尾进入 LPM,只是因为它们没有执行什么操作。 在示例10中、它间接用作演示、演示一旦启动、PWM 就会自动运行、您不必执行任何操作。

    您的代码是否仍然与您在上面发布的代码类似?  该代码在调用 SET_LED_TB0_DIM 后从 main 返回、因此 它最终会进入启用的循环(在 ABORT()中)。 我认为没有任何东西会停止计时器、因此 PWM 将永远继续。 我怀疑它是停止 PWM 的其他东西。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如上所示:LCD 调用现在正在工作-它被过多的中断调用所困扰-正如您指出的那样。 TB0只创建一个单一脉冲序列、然后关闭。 如果我在 LCD 调用之后添加一个无限循环、脉冲将永远运行。

    在 SET_LED_()中,我刚刚注释掉了对__bis_SR_register()的调用。 ISR 未运行。

    那么问题是:一旦 main 结束、内部外设是关闭还是保持运行? 在我看来、它们被关闭(至少 TB0)。 主停止后、SBC 的功耗大约下降4mA、而不是在环路中运行。 这只是平均电流、看不到与时间相关的电流。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在嵌入式系统中,不应让 main()退出,因为没有任何地方可以退出。 C 运行时库通常会在 main()退出时放置一些内容。 通常只是一个无限循环、但它可能会进入低功耗模式。 如果不检查目标代码、就无法确定。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 David 和 Bruce

    这是一个非常有启发性的问题、有很多细微差别。 我将关闭它。