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.

[参考译文] MSP430F6736:访问奇数地址

Guru**** 2905430 points

Other Parts Discussed in Thread: MSP430F6736

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1058397/msp430f6736-accessing-odd-numbered-addresses

器件型号:MSP430F6736

各位专家、您好!

我的客户正在使用 MSP430F6736、他们想知道 MSP430上的闪存。

问题1:访问 Flash 存储器时、是否可以访问(读/写)奇数地址?

问题2:如果是、 您能否告诉我在访问奇数地址时是否需要采取任何预防措施?

在"MSP430x5xx 和 MSP430x6xx 系列用户指南(修订版 Q)"中、我发现可以进行1字节访问、但没有说明是否可以先访问奇数地址。 例如、当多次记录3Byte 数据时、如果没有采取任何对策、奇数地址可被写为第一个地址。  在本例中、我们想知道是否最好以3+1Byte 单位写入数据。

我检查了以下线程、但最后我无法确定是否可以访问奇数地址。
e2e.ti.com/.../mov-b-at-odd-address-writes-the-even-address

由于我们没有遇到特定问题、因此可能很难回答、但如果您能分享 Q1是否可行以及一些参考信息、那将会有所帮助。

此致、
还不错

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

    A1:当然、您可以写入闪存的奇数字节。 否则字节写入模式将非常无用。

    A2:需要注意的一点是、在某些器件上、您可以在将128字节写入闪存块之前超过累积编程时间。 检查数据表以确保您正常。

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

    大家好、David Schultz、

    很抱歉耽误你的回答。 感谢您的回复。

    [引用 userid="215629" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/MSP-low-power-microcontroller-forum/1058397/msp430f6736-accessing-odd-addresses/3915832#3915832"]A1:当然、您可以将闪存写入奇数字节。 否则字节写入模式将非常无用。[/quot]

    实际上、我针对奇数的地址测试了读取/写入。 (但器件为 F6638。。。)。

    我注意到的一件事是、如果我像下面的线程那样为奇数地址放置一个变量、当使用16位指针进行访问时、它似乎从之前的1字节(偶数地址)进行访问。 如果是8位指针、则可以访问指定地址的内容。

    我认为这是需要指出的一点,但如果我错了,或者还有其他问题需要注意,请告诉我。

    [引用 userid="215629" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/MSP-low-power-microcontroller-forum/1058397/msp430f6736-accessing-odd-addresses/3915832#3915832"]A2:在闪存编程时、您需要注意的一件会超过128个字节的累积编程时间。 检查数据表以确保您正常。[/quot]

    我已经检查了数据表中的内容、我知道无论数字是奇数还是偶数、这都是需要注意的一点。

    此致、
    还不错

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

    您是否真的在尝试访问奇数地址的16位变量? 虽然这可能适用于允许未对齐访问(MC68020)的情况、但 MSP430不会为您拆分访问。 对于16位访问、地址的 lsb 将为零。 始终。

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

    大家好、David Schultz、

    以下是测试结果。 (很抱歉、造成了复杂情况、但我使用 F67791对其进行了重新测试)。  编译器为 v20.2.5.LTS。  我可能会遇到一些基本错误...

    最好的爬梯
    还不错

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

    您好、O.H、

    我对您为什么需要3字节格式的文件有点好奇。 除了较小的数据类型外、大多数变量数据类型都已在偶数字节集中。 例如、在这里、unsigned int 为2个字节、您甚至可以在表达式部分中看到每个地址从2个字节开始。 在这里执行长数据类型可能更容易、因为您可以有3个字节、但默认情况下、它也会填充第4个字节。  如果您要创建一个3字节结构、 我相信编译器也会填充该第四个字节以保持偶数寻址(我个人尚未验证这方面)。  

    但您可以写入1字节地址。 例如、字符数组将允许您写入奇数地址、因为 arr[1]的点将位于奇数地址中。 这只是一个常规奇数地址写入的示例。

    总之、您可以向奇数地址写入数据、但对于16位处理器、存储器就像偶数一样。 您的示例使用2字节(16位)的 int、使用长数据类型可能是最好和最简单的、因此您总共可以有4个字节、但您只关心其中的3个字节。

    此致、

    Luke

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

    您好、Luke、

    感谢你的答复。

    总之、如果我们有足够的存储器、请使用它、以便尽可能将其放置在偶数地址。 例如、如果我们要写入1字节数据三次、请添加一个额外的虚拟数据字节。 另请注意、在某些情况下、当读取奇数地址时、将被读取的值可能基于偶数地址。

    顺便说一下、当我创建一个3字节结构时、它不会自动填充4字节...  随附 CCS 捕获屏幕和我用于测试的代码。

    #include <msp430.h> 
    
    //test
    unsigned char buffer[6] = {0x00,0x12,0x34,0x56,0x78,0x90};
    
    struct test{
        unsigned char Buf1;
        unsigned char Buf2;
        unsigned char Buf3;
    };
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer
    
        P1OUT &= ~BIT0;                         // Clear P1.0 output latch for a defined power-on state
        P1DIR |= BIT0;                          // Set P1.0 to output directionOUT
    
        struct test TEST[3];
        TEST[0].Buf1 =0x01;
        TEST[0].Buf2 =0x23;
        TEST[0].Buf3 =0x45;
    
        TEST[1].Buf1 =0x01;
        TEST[1].Buf2 =0x23;
        TEST[1].Buf3 =0x45;
    
        while(1)
        {
            volatile unsigned int var_uint0 = *((unsigned int *)&buffer[0]);
            volatile unsigned int var_uint1 = *((unsigned int *)&buffer[1]);
            volatile unsigned int var_uint2 = *((unsigned int *)&buffer[2]);
            volatile unsigned int var_uint3 = *((unsigned int *)&buffer[3]);
    
            volatile unsigned int var_uint0_1 = *((unsigned char *)&buffer[0]);
            volatile unsigned int var_uint1_1 = *((unsigned char *)&buffer[1]);
            volatile unsigned int var_uint2_1 = *((unsigned char *)&buffer[2]);
            volatile unsigned int var_uint3_1 = *((unsigned char *)&buffer[3]);
        }
    }

    此致、
    还不错