各位专家好,目前我正采用TMS320F28386S的EMIF连接三星公司型号为K4S641632H-TC70,大小为64Mb的SDRAM芯片(1M×16bit×4bank),作为外部数据缓存,引脚连接设计图如下

程序配置如下
//---------------------------------------------------------------------------
// @functions: void InitEMIF1Gpio(Uint16 cpu_sel)
// @description: 配置EMIF1的I/O引脚为16bit同步模式 Setup EMIF1 Pinmux Sync 16Bit
// @Return value:NONE
// @Parameters: cpu_sel - CPU选择
//---------------------------------------------------------------------------
void InitEMIF1Gpio(Uint16 cpu_sel)
{
//对照芯片手册P1646 table15-7
GPIO_SetupPinMux(29,cpu_sel,2); //SDCKE
GPIO_SetupPinMux(30,cpu_sel,2); //CLK
GPIO_SetupPinMux(31,cpu_sel,2); //WEN
GPIO_SetupPinMux(32,cpu_sel,2); //CS0N
GPIO_SetupPinMux(33,cpu_sel,9); //EMIF1_BA0
GPIO_SetupPinMux(34,cpu_sel,9); //EMIF1_BA1
GPIO_SetupPinMux(35,cpu_sel,9); //EMIF1_A0
GPIO_SetupPinMux(36,cpu_sel,9); //EMIF1_A1
GPIO_SetupPinMux(40,cpu_sel,2); //EMIF1_A2
GPIO_SetupPinMux(41,cpu_sel,2); //EMIF1_A3
GPIO_SetupPinMux(44,cpu_sel,2); //EMIF1_A4
GPIO_SetupPinMux(45,cpu_sel,2); //EMIF1_A5
GPIO_SetupPinMux(46,cpu_sel,2); //EMIF1_A6
GPIO_SetupPinMux(47,cpu_sel,2); //EMIF1_A7
GPIO_SetupPinMux(48,cpu_sel,2); //EMIF1_A8
GPIO_SetupPinMux(49,cpu_sel,2); //EMIF1_A9
GPIO_SetupPinMux(50,cpu_sel,2); //EMIF1_A10
GPIO_SetupPinMux(51,cpu_sel,2); //EMIF1_A11
GPIO_SetupPinMux(69,cpu_sel,2); //EMIF1_D15
GPIO_SetupPinMux(70,cpu_sel,2); //EMIF1_D14
GPIO_SetupPinMux(71,cpu_sel,2); //EMIF1_D13
GPIO_SetupPinMux(72,cpu_sel,2); //EMIF1_D12
GPIO_SetupPinMux(73,cpu_sel,2); //EMIF1_D11
GPIO_SetupPinMux(74,cpu_sel,2); //EMIF1_D10
GPIO_SetupPinMux(75,cpu_sel,2); //EMIF1_D9
GPIO_SetupPinMux(76,cpu_sel,2); //EMIF1_D8
GPIO_SetupPinMux(77,cpu_sel,2); //EMIF1_D7
GPIO_SetupPinMux(78,cpu_sel,2); //EMIF1_D6
GPIO_SetupPinMux(79,cpu_sel,2); //EMIF1_D5
GPIO_SetupPinMux(80,cpu_sel,2); //EMIF1_D4
GPIO_SetupPinMux(81,cpu_sel,2); //EMIF1_D3
GPIO_SetupPinMux(82,cpu_sel,2); //EMIF1_D2
GPIO_SetupPinMux(83,cpu_sel,2); //EMIF1_D1
GPIO_SetupPinMux(85,cpu_sel,2); //EMIF1_D0
GPIO_SetupPinMux(86,cpu_sel,3); //EMIF1_CAS
GPIO_SetupPinMux(22,cpu_sel,10); //EMIF1_RAS
GPIO_SetupPinMux(88,cpu_sel,3); //EMIF1_DQM0
GPIO_SetupPinMux(89,cpu_sel,3); //EMIF1_DQM1
//
//configure Data pins for Async mode
//GPIO_PULLUP | GPIO_ASYNC = (1 << 0)|(0x3 << 4)
GPIO_SetupPinOptions(69,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D15
GPIO_SetupPinOptions(70,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D14
GPIO_SetupPinOptions(71,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D13
GPIO_SetupPinOptions(72,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D12
GPIO_SetupPinOptions(73,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D11
GPIO_SetupPinOptions(74,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D10
GPIO_SetupPinOptions(75,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D9
GPIO_SetupPinOptions(76,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D8
GPIO_SetupPinOptions(77,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D7
GPIO_SetupPinOptions(78,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D6
GPIO_SetupPinOptions(79,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D5
GPIO_SetupPinOptions(80,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D4
GPIO_SetupPinOptions(81,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D3
GPIO_SetupPinOptions(82,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D2
GPIO_SetupPinOptions(83,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D1
GPIO_SetupPinOptions(85,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_D0
GPIO_SetupPinOptions(88,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_DQM0
GPIO_SetupPinOptions(89,GPIO_INPUT,GPIO_PULLUP | GPIO_ASYNC); //EMIF1_DQM1
}
//---------------------------------------------------------------------------
// @functions: void InitEMIF1Reg(void)
// @description: 配置EMIF1模块相关寄存器
// @Return value:NONE
// @Parameters: NONE
//---------------------------------------------------------------------------
void InitEMIF1Reg(void)
{
//配置EMIF过程描述TMS320F28386手册P1429 Section 12.3.2 和 P1406 Section 12.2.5.5
EALLOW;
//Before configure the EMIF1CLKDIV field, the SDRAM should be placed in self-refresh mode
//by setting the SR bit in the SDRAM configuration register.
//TMS320F28386手册P1429 Section 12.3.2.1.1
//TMS320F28386手册P1404 Section Table 12-8
//
Emif1Regs.SDRAM_CR.bit.SR = 0x01;
//Configure to run EMIF1 on half Rate (EMIF1CLK = CPU1SYSCLK/2),
//PLLSYSCLK = (XTAL_OSC) * (IMULT) /((REFDIV) * (ODIV) * (PLLSYSCLKDIV))
//PLLSYSCLK = 25M*32/(2*2*1)=200M
//0 —— /1 of CPU1.SYSCLK is selected
//1 —— /2 of CPU1.SYSCLK is selected
//TMS320F28386手册P242 Table 3-52 和 Figure 3-50
//
ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x1;
// Once the EM1CLK frequency has been configured, remove the SDRAM from
//self-refresh by clearing the SR bit in SDRAM_CR.
//TMS320F28386手册P1429 Section 12.3.2.1.1
//
Emif1Regs.SDRAM_CR.bit.SR = 0x00;
// Grab EMIF1 For CPU1
//TMS320F28386手册P1465 Table 12-55 和 Figure 12-40
//从bit4~bit31必须写入0x93A5CE7,仅有bit0~bit1选择CPU,所以这个值肯定是0x93A5CE7X,X=0001b表示CPU1 is master
//
Emif1ConfigRegs.EMIF1MSEL.all = MSEL_EMIF1_CPU1;
// Disable Access Protection (CPU_FETCH/CPU_WR/DMA_WR) bit0~bit2
//TMS320F28386手册P1466 Table 12-56 和 Figure 12-41
//
Emif1ConfigRegs.EMIF1ACCPROT0.all = 0x0;
// content of EMIF1ACCPROT0 register can't be changed.bit0
//TMS320F28386手册P1464 Table 12-54 和 Figure 12-39
//
Emif1ConfigRegs.EMIF1COMMIT.all = 0x1;
// Lock the configuration so that EMIF1COMMIT register can't be changed any more.bit0
//TMS320F28386手册P1463 Table 12-53 和 Figure 12-38
//bit0 = 1 表示 Write to ACCPROT and Mselect fields are blocked.
//相当于上上上个寄存器EMIF1MSEL和上上个寄存器EMIF1ACCPROT0锁住了,一步到位
//
Emif1ConfigRegs.EMIF1LOCK.all = 0x1;
}
//---------------------------------------------------------------------------
// @functions: void InitEMIF1SDRAMReg(void)
// @description: 根据实际SDRAM芯片参数,配置EMIF1的SDRAM功能的寄存器
// @Return value:NONE
// @Parameters: NONE
//---------------------------------------------------------------------------
void InitEMIF1SDRAMReg(void)
{
EMIF_SyncConfig sdConfig;
EMIF_SyncTimingParams tParam;
//
//Configure SDRAM control registers
//
EALLOW;
// Need to be programmed based on SDRAM Data-Sheet.
//K4S640432H-TC70 手册PDF的第10页,“OPERATING AC PARAMETER”
//T_RFC = 68ns = 0x6(T_RFC = T_RC)
//T_RP = 20ns = 0x1
//T_RCD = 20ns = 0x1
//T_WR = 2CLK = 20 ns = 0x1
//T_RAS = 49ns = 0x4
//T_RC = 68ns = 0x6
//T_RRD = 14ns = 0x1
//TMS320F28386手册P1431 Table 12-27 和 Figure 12-16
//
Emif1Regs.SDRAM_TR.all = 0x61114610;
// Emif1Regs.SDRAM_TR.all = 0x72225720;
//Txsr = T_RC = 68ns = 0x6
//TMS320F28386手册P1432, Table 12-28 和 Figure 12-17
//
Emif1Regs.SDR_EXT_TMNG.all = 0x6;
// Emif1Regs.SDR_EXT_TMNG.all = 0x7;
//Tref = 64ms for 4096 ROW, RR = 64000*100(Tfrq)/4096 = 1562 (0x061A)
//TMS320F28386手册P1432, Table 12-29 和 Figure 12-18
//
Emif1Regs.SDRAM_RCR.all = 0x061A;
//SR = 0, NM = 1 (16bit), CL = 3, BIT11_9LOCK = 1, IBANK = 2 (4 BANK), PAGESIZE=0 (256 elements per ROW,CA0~CA7)
//TMS320F28386手册P1433, Table 12-30 和 Figure 12-19
//
Emif1Regs.SDRAM_CR.all = 0x4720;
}
在man()函数中,初始化的顺序是
InitEMIF1Gpio(GPIO_MUX_CPU1); //Configure GPIO pins for EMIF1
InitEMIF1Reg(); //Configure registers of EMIF1
InitEMIF1SDRAMReg(); //Configure registers of EMIF1 SDRAM function
CMD中关于SDRAM的配置如下
MEMORY
{
EMIF1_CS0n : origin = 0x80000000, length = 0x400000 /* Samsung SDRAM = 1M x 16Bit x 4 Banks = 64Mbit */
EMIF1_CS2n : origin = 0x00100000, length = 0x00100000
EMIF1_CS0_CS2n : origin = 0x00200000, length = 0x00100000
EMIF1_CS3n : origin = 0x00300000, length = 0x00080000
EMIF1_CS4n : origin = 0x00380000, length = 0x00060000
EMIF2_CS0n : origin = 0x90000000, length = 0x10000000
EMIF2_CS2n : origin = 0x00002000, length = 0x00001000
}
SECTIONS
{
emif_cs0_nonfar : > EMIF1_CS0_CS2n
.farbss : > EMIF1_CS0n
.farconst : > EMIF1_CS0n
.em1_cs0 : > EMIF1_CS0n
.em1_cs2 : > EMIF1_CS2n | EMIF1_CS0_CS2n
.em1_cs3 : > EMIF1_CS3n
.em1_cs4 : > EMIF1_CS4n
.em2_cs0 : > EMIF2_CS0n
.em2_cs2 : > EMIF2_CS2n
}
/*
//===========================================================================
// End of file.
//===========================================================================
*/
并且在程序中,成功初始化了需要的数组
#define Ads1ForSpiaChnNum 16 #define Ads2ForSpibChnNum 16 #define Ads3ForSpicChnNum 16 #define WordsNumPerChn 30000 #define Ads1WordsMemBufSize ((Uint32)Ads1ForSpiaChnNum*WordsNumPerChn) #define Ads2WordsMemBufSize ((Uint32)Ads2ForSpibChnNum*WordsNumPerChn) #define Ads3WordsMemBufSize ((Uint32)Ads3ForSpicChnNum*WordsNumPerChn) __attribute__((far)) volatile Uint16 Ads1SDRAMBuf[Ads1WordsMemBufSize]; __attribute__((far)) volatile Uint16 Ads2SDRAMBuf[Ads2WordsMemBufSize]; __attribute__((far)) volatile Uint16 Ads3SDRAMBuf[Ads3WordsMemBufSize];
然后在main()函数中对这三个数组进行赋值写入操作
for(i = 0; i < Ads1WordsMemBufSize; i++)
{
Ads1SDRAMBuf[i] = 0x0101;
Ads2SDRAMBuf[i] = 0x0202;
Ads3SDRAMBuf[i] = 0x0303;
DELAY_US(1);
}
最后用for循环和memcpy两种读取方法,通过IPC+以太网的传输方式把数据发送到PC上
LenPerTx = 500;
TxTotalLen = Ads1WordsMemBufSize;
for(i=0;i<TxTotalLen/LenPerTx;i++)
{
// memcpy(&IPCTxBuff[0],(Ads1SDRAMBuf+i*LenPerTx),LenPerTx*sizeof(Uint16));
for(j=0;j<LenPerTx;j++)
{
IPCTxBuff[j] = Ads1SDRAMBuf[i*LenPerTx+j];
}
IpcGlobalVar.TxBufLen = LenPerTx; //发送帧的字节长度
IpcTxStart((Uint32)IPCTxBuff,IpcGlobalVar.TxBufLen); //发送处理函数
DELAY_US(3500);
}
LenPerTx = 500;
TxTotalLen = Ads2WordsMemBufSize;
for(i=0;i<TxTotalLen/LenPerTx;i++)
{
memcpy(&IPCTxBuff[0],(Ads2SDRAMBuf+i*LenPerTx),LenPerTx*sizeof(Uint16));
IpcGlobalVar.TxBufLen = LenPerTx; //发送帧的字节长度
IpcTxStart((Uint32)IPCTxBuff,IpcGlobalVar.TxBufLen); //发送处理函数
DELAY_US(3000);
}
上述两种方法得到一样的结果,出现一段一段的数据混乱,如下图所示




麻烦TI的专家帮忙看一下,是不是哪里配置出了问题,导致SDRAM写入读取时部分数据正确,部分数据不正确的情况,十分感谢!
另附上,K4S641632H-TC70的时间参数表

