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.

MSP430F5438A: 请教:DMA+SPI通讯,DMA将内存地址增长设置为地址不变,但是程序运行异常。

Part Number: MSP430F5438A

额,我遇到的问题比较奇怪,我尽可能描述清楚问题。

我使用MSP430F5438a,以下使用单片机代替MSP430F5438a

单片机与DSP通过DMA+SPI进行通讯。单片机作为SPI通讯的主机。

1、由于每次通讯单片机都是接收数据,但是标准SPI通讯要求发送同时接收,因此单片机维持着两段内存,分别是send_buf和recv_buf。send_buf是发送端缓存,而recv_buf是接收端缓存。

2、由于单片机与DSP通讯的目的是用于从DSP接收数据,单片机发送数据仅仅是为了保证SPI真正实现双端通讯,DSP端根本不关心接收到的数据是什么,会直接丢掉。

3、我使用两路DMA来保证SPI通讯双端通讯。到目前为止,一切正常。

4、由于单片机RAM紧张,我希望压缩send_buf缓存尺寸。由于发送数据DSP根本“不敢兴趣”,因此我在使用DMA发送数据时,将DMA发送端内存地址设置为地址不变,即发送端每次发送的都是固定地址的数据。

按照我的理解,这样做应该是可行的。但是,程序在大多数情况下运行是正常的,但是偶然情况下(可能一天会出现1~2次)会修改我栈中的数据,从而导致其它程序运行异常。

恳请各位帮助,不胜感激。

  • 因此我在使用DMA发送数据时,将DMA发送端内存地址设置为地址不变,即发送端每次发送的都是固定地址的数据。

    能否给出相关代码?

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    /*
    * Configure DMA channel 0
    * Use TxString as source
    * Increment source address after every transfer
    */
    DMA_setSrcAddress(DMA_CHANNEL_0,
    (uint32_t)(uintptr_t)&TxString,
    DMA_DIRECTION_INCREMENT);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    是可以选择 #define DMA_DIRECTION_UNCHANGED                                  (DMASRCINCR_0) 的

    按照我的理解,这样做应该是可行的。

    是的,我也是这样认为的

    但是偶然情况下(可能一天会出现1~2次)会修改我栈中的数据,从而导致其它程序运行异常。

    能否详细说明一下?

  • 非常感谢你的回复。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /* */
    __data16_write_addr((unsigned short)&DMA0SA, (unsigned long)SrcAddr);
    __data16_write_addr((unsigned short)&DMA0DA, (unsigned long)&UCB0TXBUF);
    DMA0SZ = Len;
    DMA0CTL = DMADT_1 + DMASRCINCR_0 + DMADSTBYTE + DMASRCBYTE + DMALEVEL;
    /* DMA */
    __data16_write_addr((unsigned short)&DMA1SA, (unsigned long)&UCB0RXBUF);
    __data16_write_addr((unsigned short)&DMA1DA, (unsigned long)DstAddr);
    DMA1SZ = Len;
    DMA1CTL = DMADT_1 + DMADSTINCR_3 + DMADSTBYTE + DMASRCBYTE + DMALEVEL + DMAIE;
    break;
    /* 5 DMASRCINCR_0 */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    栈中数据出错表现为:(类似现象举例如下)

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void func(void)
    {
    bool flag = flase;
    if (flag)
    {
    /* 怀 */
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • 建议您先参考下例程内的设置

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /* --COPYRIGHT--,BSD_EX
    * Copyright (c) 2012, Texas Instruments Incorporated
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    在msp430f5348a.h内使用的是

    SFR_20BIT(DMA0SA);                            /* DMA Channel 0 Source Address */ 

    所以在此使用的是 __data20_write_long

  • 感谢你的回复。

    你说的非常有道理,是应该使用20-bit地址长度的,我已改正。

    但我查看内存map,我所使用的变量未超过16-bit,即我的问题应该与20-bit地址长度无关。我还需要继续查找原因。

    还是非常感谢你。

  • 好的,期待您的反馈

  • 是我的代码出现问题了,与DMA和SPI无关。

    望知晓,麻烦各位了。

    感谢!