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.

[参考译文] 将 USCI 中断使能

Guru**** 2487425 points
Other Parts Discussed in Thread: MSP430F5529

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1221857/setting-the-usci-interrupt-enable

器件型号:MSP-EXP430F5529LP
主题中讨论的其他器件:MSP430F5529

好-不确定这里发生了什么、试图在 UART 上启用中断、这是通过 MSP430F5529上的 USCI 完成的。

要设置和读取的代码:

  HWREGB( USCI_A1_BASE | UCAxIE ) |= 0x03;
  *print=HWREGB( USCI_A1_BASE | UCAxIE )+'0';

其中 HWREGB 是一个访问位于存储器位置的字节的宏。 第二行仅移动到一个打印缓冲区的值、该缓冲区的偏移量为"0"字符。 我预计在输出上看到"3"。 我得到的只是"0"。 已检查汇编器以确保 其合理、和:

    45a0:       f2 d0 03 00     bis.b   #3,     &0x061c ;
    45a4:       1c 06 
    45a6:       5c 42 1c 06     mov.b   &0x061c,r12     ;0x061c
    45aa:       7c 50 30 00     add.b   #48,    r12     ;#0x0030

因此对于 msp430f5529上 USCI_A1_base 的 UCAxIE 来说、这是所有合理的、正确的存储器位置;它带有"bis"的设置位是最好的方法、因为手动只说前两个位是 RW、其余的只是 R。

但唉、它似乎没有设置这些位。 发生了一些奇怪的事情。 有什么想法吗?

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

    好-*非常*仔细地阅读手册,和

    36.3.1 USCI 初始化和复位
    USCI 在一个 PUC 后或者通过设置 UCSWRST 位来复位。 一个 PUC 后、UCSWRST 位为
    自动置位、将 USCI 保持在一个复位状态。 当置位时、UCSWRST 位复位 UCRXIE、
    UCTXIE、UCRXIFG、UCRXERR、UCBRK、UCPE、 UCOE、UCFE、UCSTOE 和 UCBTOE 位置位
    UCTXIFG 位。 清零 UCSWRST 会使 USCI 处于运行状态。

    因此、我需要按以下顺序编写代码:

      // enable USCI A1
      HWREGB( USCI_A1_BASE | UCAxCTL1 ) &= ~UCSWRST;
      // interupts on both TX(2) and RX(1) UCTXIE and UCRXIE
      HWREGB( USCI_A1_BASE | UCAxIE ) |= 0x03;

    并在启用 UART 后启用中断(在 USCI A1上)

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

    USCI_A1_base | UCAxIE 在这里可能工作、但很危险。 当使用基地址和偏移量时、您需要加法、而不是按位或。

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

    你(们)好。 "我知道你的意思。"

    我自己有两个想法。 一方面、这些内存映射的外部器件(到主 CPU)通常被映射在一个与之对齐的小窗口内。 而这在设计芯片时通常是一种很好的方法、TI 也会遵循这个方法。 现在存在异常、TIMER_B0_BASE 具有跨越一页的存储器地址、例如 TBxEX0 (0x20 + 0x3V0);因此 TBxEX0刚刚移动到下一个32字节窗口、TIMER_B0存储器映射是否跨越64字节?

    对我来说、我可以看到、对于大多数情况、"+"和"|"都是等效的;使用常量编译时、编译器会执行操作;因此代码没有区别。 你在某种程度上看运算"+"是算术加法、"|"是逻辑加法。 因此、"BIT0 | BIT1"比"BIT0 + BIT1"更自然。

    所以对于一个内存映射器件、包括基地址和偏移量-它的外观是多么的好。 说明了大多数器件都映射为一个页面、通常为32字节、因此我希望在该页面上按设计处理该操作。 这是"|"操作。

    所以我知道你在说什么,是的,是的,我知道这个问题。 "你是我的女人,我也不是我的女人,而是我的女人。" 我可以看到这两种方法、只是不确定我喜欢哪种方法。 这两个都有故障。

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

    需要深入了解细节才能知道按位 OR 将起作用。 但它仍然是一个坏主意。

    我还想知道当像 UCA1IE 这样的符号可用时、为什么会这样做。 只有在编写与所有端口一起使用的驱动程序时、基线和偏移路由才有用。 会在运行时通过向基址传递指针来选择哪个。

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

    也就是说、您认为存储器地址是偏移量、因此您始终使用"+"。

    我之前说过、存储器映射器件是存储器对齐的、您应该对存储器对齐区域进行写入。

    那么、为了从我的 msp430f5529中给出一个示例、请查看按顺序出现的存储器地址:

    #define __MSP430_BASEADDRESS_PORT1_R__ 0x0200
    #define __MSP430_BASEADDRESS_PORT2_R__ 0x0200
    #define __MSP430_BASEADDRESS_PORTA_R__ 0x0200
    #define __MSP430_BASEADDRESS_PORT3_R__ 0x0220
    #define __MSP430_BASEADDRESS_PORT4_R__ 0x0220
    #define __MSP430_BASEADDRESS_PORTB_R__ 0x0220
    #define __MSP430_BASEADDRESS_PORT5_R__ 0x0240
    #define __MSP430_BASEADDRESS_PORT6_R__ 0x0240
    #define __MSP430_BASEADDRESS_PORTC_R__ 0x0240
    #define __MSP430_BASEADDRESS_PORT7_R__ 0x0260
    #define __MSP430_BASEADDRESS_PORT8_R__ 0x0260
    #define __MSP430_BASEADDRESS_PORTD_R__ 0x0260
    #define __MSP430_BASEADDRESS_PORTJ_R__ 0x0320
    #define __MSP430_BASEADDRESS_T0A5__ 0x0340
    #define __MSP430_BASEADDRESS_T1A3__ 0x0380
    #define __MSP430_BASEADDRESS_T2A3__ 0x0400
    #define __MSP430_BASEADDRESS_T0B7__ 0x03C0
    #define __MSP430_BASEADDRESS_USCI_A0__ 0x05C0
    #define __MSP430_BASEADDRESS_USCI_B0__ 0x05E0
    #define __MSP430_BASEADDRESS_USCI_A1__ 0x0600
    #define __MSP430_BASEADDRESS_USCI_B1__ 0x0620
    

    您可以看到、端口与0x20对齐、计时器与0x40对齐、USCI 器件与0x20对齐。

    数字 IO 的最大偏移量为0x1f、定时器的最大偏移量为0x20、USCI 的最大偏移量为0x1E。

    所以每个偏移都是在每个器件的窗口中设置的。

    这几乎可以肯定、在设计 TI 器件时、它们将器件存储器地址设计为存储器对齐。

    然后我想归结为文档、然后在文档中做一些说明、即内存映射器件是内存对齐的。

    因此、考虑您的示例 UXAxIE 的偏移值为0x1c;它用于寻址存储器对齐为0x20的 USCI 器件。 因此"|"可与此配合使用、因为 USCI 器件始终将最低五位设置为零、并且所有偏移均为5位长。

    我不认为在那里我发现了一些代码"|"不工作,计时器是我见过的最糟糕的,但他们的内存对齐增加到0x40。

    您说"|"不安全、对于某些地址(TI 未使用)、它可能会为英文单词"offset"提供错误的值。 我说"|"可以确保偏移始终在设备的内存对齐范围内、从而确保您写入该设备的内存-我的内存是安全的。

    因此,当我们说"安全"时,我们有不同的含义,你说的"偏移"在英语中总是一个数字加法。 当我说"安全"时、我谈论的是器件的内存对齐、因此代码应始终在器件的内存对齐内写入、因此不正确的代码只会混乱您要写入的器件、而不会扰乱其它器件。

    我想我们这里只是使用不同的语言、但我们可以说其中一种肯定是更好的编码风格吗?  正如我之前所说的那样-它有一点无关紧要、因为好的编译器将在编译时合并这样的常量、并为"+"和"|"同时合并这两个常量。 因此、以任一方式编写的代码都将创建相同的汇编代码。

     

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

    意识到你是指 UCA1IE 而不是 UCAxIE。 问得好。 老实说,我没有意识到它被定义了,但现在看到它。 请快速看、先想一想。

    我当时认为 USCI_A1是一个内存映射器件、具有特定的基地址、并偏移了该地址空间。 取决于文档的编写方式。 然后、我使用从 Tiva C 行派生的代码来直接写入存储器:

    #define HWREGB(x) (*((volatile uint8_t *)(x)))

    我喜欢它的简单性-它写入8位内存。

    我喜欢基地址和偏移量、在我看来、基地址指的是硬件的位、而偏移量指的是硬件中的寄存器、因此对我来说、同时引用这两者是合理的。

    只是想看看 UCA1IE 是如何在标头中定义的、还没有很好地开发出逻辑、看起来它被设置为外部、然后链接器就会处理它。 这有一定的道理、但现在让我感到困惑。 我有点喜欢上面的代码、它直接说、写入存储器中的地址-这在调用链接器之前发生。

    这是 TI 参考顺便 https://software-dl.ti.com/simplelink/esd/simplelink_msp432e4_sdk/3.10.00.11/docs/driverlib/msp432e4/html/types_8h_source.html

    并说明了 UCA1IE 的实现方式:

    在:msp430f5529.h:#define UCA1IE UCA1ICTL_L                    /* USCI A1中断使能寄存器*/中
    in:msp430f5529_symbols.ld:provide (UCA1ICTL_L        = 0x061C);

    因此、它在 c 代码中未解析、并且链接器提供缺少的引用。 在我看来、这有点令人困惑的实施方案-但这可能只是我而已。 据我所见、它仅仅定义了一个地址、并未指出地址处数据的大小、例如、不表示它是一个字节还是一个字。

    我想您的解决方案会是这样

      HWREGB( UCA1IE ) |= BIT0|BIT1;

    再多读一点、然后实现标准 MSP430编码

    UCA1IE |= BIT1|BIT0;
    这可以编译为 BIS 指令。 但是
    UCA1IE=0x3;
    编译器如何知道它应该写入 unit8_t 或 unit16_t 呢? 即使编译器知道(我不知道如何)、这对我来说似乎也不是很透明。

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

    尊敬的 David:

    您的问题是否已得到解决?

    谢谢!

    此致

    Johnson

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

    是的-原来的问题解决了、您只能在启用 USCI 器件后在 UCSI 器件上启用中断、所以只需确保按正确的顺序完成操作。

    然后、Thread 演变为用于对 MSP430器件进行编程的编码风格、Thin David Schultz、我只是有一个略有不同的风格、所以我讨论了我的想法是一个相当小的点。

    但无论如何,是的,原来的问题解决了-做的事情正确的顺序。