TI中文支持网
TI专业的中文技术问题搜集分享网站

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次)会修改我栈中的数据,从而导致其它程序运行异常。

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

Susan Yang:

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

能否给出相关代码?

/** 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);

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

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

是的,我也是这样认为的

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

能否详细说明一下?

,

chang liu:

非常感谢你的回复。

/* 此时不关心发送数据,因此禁止发送数据内存地址自增 */__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 即代表发送端内存地址保持不变 */

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

void func(void)
{bool flag = flase;if (flag){/* 函数可以执行到这里,所以我严重怀疑栈数据出错!!! */}
}

,

Susan Yang:

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

/* --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,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.**********************************************************************************MSP430 CODE EXAMPLE DISCLAIMER** MSP430 code examples are self-contained low-level programs that typically* demonstrate a single peripheral function or device feature in a highly* concise manner. For this the code may rely on the device's power-on default* register values and settings such as the clock configuration and care must* be taken when combining code from several examples to avoid potential side* effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware* for an API functional library-approach to peripheral configuration.** --/COPYRIGHT--*/
//******************************************************************************
//MSP430F543xA Demo - SPI TX & RX using DMA0 & DMA1 Single Transfer in Fixed
//Address Mode
//
//Description: This code has to be used with MSP430F543xA_uscia0_spi_10.c as
//slave SPI. DMA0 is used to transfer a single byte while DMA1 is used to
//RX from slave SPI at the same time. This code will set P1.0 if RX character
//is correct and clears P1.0 if received character is wrong. Watchdog in
//interval mode triggers block transfer every 1000ms.
//ACLK = REFO = 32kHz, MCLK = SMCLK = default DCO 1048576Hz
//
//MSP430F5438A
//-----------------
///|\|XIN|-
//| || 32768Hz
//--|RSTXOUT|-
//||
//|P1.0|-> LED
//||
//|P3.4|-> Data Out (UCA0SIMO)
//||
//|P3.5|<- Data In (UCA0SOMI)
//||
//|P3.0|-> Serial Clock Out (UCA0CLK)
//
//M. Morales
//Texas Instruments Inc.
//June 2009
//Built with CCE v3.1 Build 3.2.3.6.4 & IAR Embedded Workbench Version: 4.11B
//******************************************************************************#include <msp430.h>
#include <stdint.h>char TxString;
char RxString;int main(void)
{WDTCTL = WDT_ADLY_1000;// WDT 1000ms, ACLK, interval timerSFRIE1 |= WDTIE;// Enable WDT interruptP1OUT &= ~0x01;// Clear P1.0P1DIR |= 0x01;// P1.0 = OutputP3SEL |= 0x31;// P3.0,4,5 = USCI_A0 SPI OptionUCA0CTL1 |= UCSWRST;// **Put state machine in reset**UCA0CTL0 = UCMST+UCSYNC+UCCKPL+UCMSB;// 3-pin, 8-bit SPI master// Clock polarity high, MSBUCA0CTL1 = UCSSEL_2;// SMCLKUCA0BR0 = 0x02;// /2UCA0BR1 = 0x00;//UCA0MCTL = 0x00;// No modulationUCA0CTL1 &= ~UCSWRST;// **Initialize USCI state machine**DMACTL0 = DMA1TSEL_16+DMA0TSEL_17;// DMA0 - UCA0TXIFG// DMA1 - UCA0RXIFG// Setup DMA0__data20_write_long((uintptr_t) &DMA0SA,(uintptr_t) &TxString);// Source block address__data20_write_long((uintptr_t) &DMA0DA,(uintptr_t) &UCA0TXBUF);// Destination single addressDMA0SZ = 1;// Block sizeDMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL;// inc src// Setup DMA1__data20_write_long((uintptr_t) &DMA1SA,(uintptr_t) &UCA0RXBUF);// Source block address__data20_write_long((uintptr_t) &DMA1DA,(uintptr_t) &RxString);// Destination single addressDMA1SZ = 1;// Block sizeDMA1CTL = DMADSTINCR_3+DMASBDB+DMALEVEL;// inc dstTxString = RxString = 0;// Clear TxString// Clear RxString__bis_SR_register(LPM3_bits + GIE);// Enter LPM3 w/ interrupts__no_operation();// Required only for debugger
}//------------------------------------------------------------------------------
// Trigger DMA0 & DMA1 block transfer.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(WDT_VECTOR))) WDT_ISR (void)
#else
#error Compiler not supported!
#endif
{if(TxString-1 == RxString)P1OUT |= 0x01;// Set P1.0 if TrueelseP1OUT &= ~0x01;// Clear P1.0 if FalseTxString++;// Increment TxString counterDMA1CTL |= DMAEN;// DMA1 EnableDMA0CTL |= DMAEN;// DMA0 Enable
}

在msp430f5348a.h内使用的是

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

所以在此使用的是 __data20_write_long

,

chang liu:

感谢你的回复。

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

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

还是非常感谢你。

,

Susan Yang:

好的,期待您的反馈

,

chang liu:

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

望知晓,麻烦各位了。

感谢!

赞(0)
未经允许不得转载:TI中文支持网 » MSP430F5438A: 请教:DMA+SPI通讯,DMA将内存地址增长设置为地址不变,但是程序运行异常。
分享到: 更多 (0)