项目中需要使用STM32和FPGA通信,使用的是地址线和数据线,在FPGA中根据STM32的读写模式A的时序完成写入和读取。之前的PCB设计中只使用了8跟数据线和8根地址线,调试过程中没有发现什么问题,在现在的PCB中使用了8根地址线和16根数据线,数据宽度也改成了16位,刚开始是读取数据不正确,后来发现了问题,STM32在16位数据宽度下有个内外地址映射的问题,只需要把FPGA中的设定的地址乘以2在STM32中访问就可以了,但是在写操作的时候会出现写当前地址的时候把后面的地址写成0的情况,比如说我给FPGA中定义的偏移地址0x01写一个16位数据,按照地址映射,在STM32中我把地址写入0x02,。实际测试发现这个地址上的数据是对的,但是FPGA中0x02地址上的数据也变成了00。
经过一晚上的测试,发现写数据时实际上是进行了多次写入,导致把后面的地址也给写上了,最终导致数据混乱,后来经过学长提醒,决定把访问的地址定义为16位的,原来是32位的,经过测试问题解决。所以这儿也算是长了经验,因为我只用了8根地址线,为了避免可能的问题,地址最好定义成对应的位数。但是还是很纳闷为什么之前八位数据线读写的时候没有这个问题。
下面是改正之后的STM32程序,对应的CPLD/FPGA程序参考我之前的博客
1 /**************************(C) COPYRIGHT emouse 2011*************************** 2 名称:CPLD.c 3 功能:配置fsmc,CPLD读写函数 4 作者:HHUC emouse miss1989@139.com 5 时间:2011.4.28 6 版本:1.0 7 注意:一定要使能RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); 8 *******************************************************************************/ 9 #include "STM32Lib//stm32f10x.h" 10 #include "hal.h" 11 //使用第一块存储区,使用第四块,定义基地址 12 #define Bank1_SRAM4_ADDR ((uint32_t)0x6c000000) 13 /******************************************************************************* 14 名称:CPLD_Init(void) 15 功能:配置FSMC寄存器 16 参数:无 17 时间:2011.1.15 18 版本:1.0 19 注意:实际CPLD只用了8根地址线和8根数据线 20 按照模式A-SRAM/PSRAM(CRAM)OE翻转模式配置读写时序时序图在STM32技术手册P332 21 可以按照实际连接配置地址线数据线 22 实际CPLD中可以更改敏感信号,对STM32的时序要求放宽 23 *******************************************************************************/ 24 void CPLD_Init(void) 25 { 26 27 FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; 28 FSMC_NORSRAMTimingInitTypeDef p; 29 GPIO_InitTypeDef GPIO_InitStructure; 30 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); 31 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | 32 RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF, ENABLE); 33 //数据线引脚初始化,辅助控制器中使用了16根数据线 34 //D 0 1 2 3 13 14 15 35 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 |GPIO_Pin_9 | 36 GPIO_Pin_10| GPIO_Pin_14 | GPIO_Pin_15; 37 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 38 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 39 GPIO_Init(GPIOD, &GPIO_InitStructure); 40 //D4-D12 41 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| 42 GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; 43 GPIO_Init(GPIOE, &GPIO_InitStructure); 44 45 //地址线引脚初始化,调试使用8根地址线 46 //A0-A7 47 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 48 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | 49 GPIO_Pin_14; 50 GPIO_Init(GPIOF, &GPIO_InitStructure); 51 52 //其他控制信号线,调试使用NE4、NOE、NWE 53 //NOE and NWE configuration 54 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5; 55 GPIO_Init(GPIOD, &GPIO_InitStructure); 56 //NE4 configuration 57 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 58 GPIO_Init(GPIOG, &GPIO_InitStructure); 59 60 /*-- FSMC Configuration ------------------------------------------------------*/ 61 p.FSMC_AddressSetupTime = 0; 62 p.FSMC_AddressHoldTime = 0; 63 p.FSMC_DataSetupTime = 1; 64 p.FSMC_BusTurnAroundDuration = 0; 65 p.FSMC_CLKDivision = 0; 66 p.FSMC_DataLatency = 0; 67 p.FSMC_AccessMode = FSMC_AccessMode_A; 68 69 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4; 70 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; 71 FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; 72 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; 73 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; 74 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; 75 FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; 76 FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; 77 FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; 78 FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; 79 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; 80 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; 81 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; 82 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; 83 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; 84 85 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 86 87 // Enable FSMC Bank1_SRAM Bank 88 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); 89 90 //CPLD 复位信号,这里使用普通IO PD7 91 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 92 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //开漏输出 93 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度 94 GPIO_Init(GPIOC, &GPIO_InitStructure); 95 96 GPIO_ResetBits(GPIOD, GPIO_Pin_7); 97 GPIO_SetBits(GPIOD, GPIO_Pin_7); //根据CPLD程序设置低电平复位 98 } 99 /******************************************************************************* 100 名称:CPLD_Write 101 功能:CPLD写时序 102 参数:uint8_t pBuffer-写入的数据 uint32_t WriteAddr-写入的地址 103 时间:2011.1.15 104 版本:1.0 105 注意:在硬件设计中使用了八根地址线和数据线,因此以八位的数据写入 106 *******************************************************************************/ 107 void CPLD_Write(uint16_t pBuffer, uint16_t WriteAddr) 108 { 109 *(uint16_t *) (Bank1_SRAM4_ADDR + WriteAddr) = pBuffer; 110 } 111 /******************************************************************************* 112 名称:uint16_t CPLD_Read(uint32_t ReadAddr) 113 功能:CPLD读 114 参数:uint32_t ReadAddr需要读取的地址,返回读取的值 115 时间:2011.4.26 116 版本:1.0 117 注意:在硬件设计中使用了16根地址线和数据线,因此以16位的数据写入 118 *******************************************************************************/ 119 uint16_t CPLD_Read(uint16_t ReadAddr) 120 { 121 uint16_t pBuffer; 122 pBuffer = *(__IO uint16_t*) (Bank1_SRAM4_ADDR + ReadAddr); 123 return pBuffer; 124 }
本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2011/04/28/2198152.html,如需转载请自行联系原作者