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.

[参考译文] MSP430FR5969:正确转换为_SFR_FARPTR

Guru**** 2779745 points

Other Parts Discussed in Thread: MSP430FR5969

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1605831/msp430fr5969-correctly-casting-to-__sfr_farptr

器件型号: MSP430FR5969

大家好!

 

我相信我遗漏了一些明显的东西。 我正在使用 MSP430FR5969(即具有 20 位存储器寻址的器件)、并且我想执行 DMA 传输到 CRC 模块。 听起来很简单!

显然、要做到这一点、我需要将目标地址设置为 CRC 寄存器。 我得到的是:

DMA0DA = (__SFR_FARPTR) (&CRCDIRB);

这会触发无效类型转换警告(警告#173-D)。 我曾尝试过通过 void *进行转换、通过 Uint32 和 unsigned long 进行转换、通过 uintptr_t 进行转换、甚至通过 uint32_t void *进行转换。 无解决问题。

有人能给我提供正确的代码行、将 CRCDIRB 寄存器的地址加载到 DMA0 目标地址(即 DMA0DA)寄存器吗?

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

    我只需注意、_SFR_FARPTR 的定义如下:

    typedef void (* __SFR_FARPTR)();

    我不知道为什么在它被用于一组寄存器时它会被定义为函数指针(例如,DMA0DA 的类型为 SFR_20BIT、它刚刚直接转换为__SFR_FARPTR — 很明显,将函数指针馈送到您的 DMA 目标寄存器可能会导致一些纬度)。

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

    请使用此行设置地址

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

    DMA0DA =&CRCDIRB;

    由于该地址的高 4 位为零、因此无需特殊处理。 编译器可能会生成警告、但可以安全地将其忽略。

    要加载 20 位地址、安全方法是使用 data16_write_addr () 内在函数。

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

    好的、谢谢 Gary。 是否会尝试这样做、我假设我可以将 0x1C40 替换为&CRCDIRB?

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

    好的、谢谢 Gary。 是否会尝试这样做、我假设我可以将 0x1C40 替换为&CRCDIRB?

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

    谢谢大卫,也许我应该努力禁用警告,而不是“解决“的问题。

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

    通过 GCC A 转换到__int20 来静音警告。 另一方面、它会导致加载这个 20 位常量的代码非常糟糕:

      DMA0DA = (__int20)&CRCDIRB;
        445c:       8c 00 52 01     mova    #338,   r12     ;0x00152
        4460:       00 18 4d 4c     movx.a  r12,    r13     ;
        4464:       0c 4c           mov     r12,    r12     ;
        4466:       0f 18 4d 11     rpt #16 { rrax.a        r13             ;
    
    0000446a <.Loc.17.1>:
        446a:       82 4c 16 05     mov     r12,    &0x0516 ;
        446e:       82 4d 18 05     mov     r13,    &0x0518 ;
    

    所有要做的事情本来可以用一个指令完成。

      asm(" movx.a #CRCDIRB,&DMA0DA\n");
        445c:       00 18 f2 40     movx.a  #338,   &0x00516;0x00152
        4460:       52 01 16 05 
    

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

    好的、我尝试了这个方法、但它不起作用。 它转换为两个字写入、并且(根据数据表)“在使用字指令写入 DMAxDA 时、位 19-16 将被清除“。 这正是我看到的、即使汇编程序显示对高位的写入、也只会设置最低 16 位。

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

    David Schultz 成功! 非常感谢您的参与。 与__data20_write_long 内在函数不同、__data16_write_addr 正确地将整个 20 位地址移动到寄存器中、然后将其放入 DMA0DA 中。