library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity stm32_cpld is
port(
cpld_cs:in std_logic;--cpld片選信號(hào),硬件連接:通過(guò)SN74LVC4245與STM32的FSMC總線的 --FSMC_NE1(PD7)連接
rd:in std_logic; --讀控制信號(hào)
wr:in std_logic;--寫(xiě)控制信號(hào)
cpld_rest:in std_logic;--復(fù)位信號(hào)
m_dir1:out std_logic;--控制U6(SN74LVC4245芯片)
m_dir2:out std_logic;--控制U7(SN74LVC4245芯片)
data_out:out std_logic_vector(7 downto 0) --8位數(shù)據(jù)輸出
);
end stm32_cpld;
architecture behav of stm32_cpld is
signal data_buf:std_logic_vector(7 downto 0);
signal data_outctl:std_logic;
begin
m_dir1 <= '0';--控制SN74LVC4245,DIR=0,信號(hào)流向:B->A
m_dir2 <= '1';--控制SN74LVC4245,DIR=1,信號(hào)流向:A->B
data_outctl <= (not cpld_cs) and (not rd) and wr;--判斷讀時(shí)序
data_out <= data_buf when(data_outctl='1') else "00000000";--如果是讀時(shí)序則輸出數(shù)據(jù)到FSMC總線
process(cpld_rest)
begin
if(cpld_rest = '0') then
data_buf <= x"18";--x代表16進(jìn)制數(shù),如果復(fù)位鍵按下,則輸出緩沖的數(shù)據(jù)為0x18
else
data_buf <= x"58";
end if;
end process;
end architecture behav;
//----------------------------------------------------------------
#define LCD_DATA_ADD *((vu16 *)0X60000000) //數(shù)據(jù)讀寫(xiě)地址
#define ReadData() (LCD_DATA_ADD) //數(shù)據(jù)讀取
//----------------------------------------------------------------
void fsmc_init(void);
void delay_ms(unsigned int Counter);
unsigned short readdata=0;//16位
//----------------------------------------------------------------
int main(void)
{
fsmc_init();
while(1)
{
readdata=ReadData();
delay_ms(2000);
}
}
void fsmc_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
//設(shè)置PD口PD 0,1,4,5,7,8,9,10,11,12,14,15為FSMC模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_4 |GPIO_Pin_5|
GPIO_Pin_10 |GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//設(shè)置PE口PE 7,8,9,10,11,12,13,14,15為FSMC模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); //使能FSMC時(shí)鐘
p.FSMC_AddressSetupTime = 1;//地址建立時(shí)間,單位AHB時(shí)鐘周期
p.FSMC_AddressHoldTime = 0; //地址保持時(shí)間,單位AHB時(shí)鐘周期
p.FSMC_DataSetupTime = 2; //數(shù)據(jù)建立時(shí)間,單位AHB時(shí)鐘周期
//一次讀操作之后在總線上的延遲(僅適用于總線復(fù)用模式的NOR閃存操作),
p.FSMC_BusTurnAroundDuration = 0;
p.FSMC_CLKDivision = 0;//CLK時(shí)鐘輸出信號(hào)的周期,以HCLK周期數(shù)表示,本書(shū)不用該時(shí)鐘
//用于同步成組模式的NOR閃存,定義在讀取第一個(gè)數(shù)據(jù)之前等待的存儲(chǔ)器周期數(shù)目
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_B; //訪問(wèn)模式B,
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; //指定的FSMC塊1
//地址和數(shù)據(jù)不復(fù)用
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
//存儲(chǔ)器類(lèi)型為SRAM
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
//數(shù)據(jù)寬度16位
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
//成組訪問(wèn)禁止
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
//等待信號(hào)低有效
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
//決定控制器是否支持把非對(duì)齊的AHB成組操作分割成2次線性操作,僅在存儲(chǔ)器的成組模式下有效
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
//在成組模式時(shí),在等待狀態(tài)之前的一個(gè)時(shí)鐘周期產(chǎn)生NWAIT信號(hào)
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //寫(xiě)操作允許
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //不使用等待信號(hào)
//不使用擴(kuò)展模式
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
//成組操作時(shí),禁止插入等待狀態(tài)
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; //設(shè)置讀時(shí)序配置指針
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;//設(shè)置寫(xiě)時(shí)序配置指針
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //FSMC初始化
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); //使能FSMC讀寫(xiě)操作
}
//==============================================================================
//Subroutine: Delay1ms
//==============================================================================
void delay_ms(unsigned int Counter)
{
unsigned int i;
for(; Counter !=0; Counter--)
{
i = 10301;
while(i--);
}
}
說(shuō)明:stm32初始化FSMC時(shí)設(shè)置了16位數(shù)據(jù)格式,但是我cpld只提供8位數(shù)據(jù)格式,所以接線時(shí)可以將cpld的數(shù)據(jù)線對(duì)應(yīng)接到stm32的fsmc數(shù)據(jù)總線的低8位,因此在stm32處理從fsmc數(shù)據(jù)總線讀取的數(shù)據(jù)時(shí)只需保留低8位,高8位數(shù)據(jù)忽略即可,比如readdata & 0x00ff。FSMC總線的編址也要注意,之前有一篇博客對(duì)此有所闡述。
實(shí)驗(yàn)現(xiàn)象:stm32采用在線調(diào)試,將readdata添加到觀察窗口,查看它的值,可以看到,當(dāng)cpld開(kāi)發(fā)板的復(fù)位鍵未按下時(shí),readata=0x0058,當(dāng)長(zhǎng)按cpld復(fù)位鍵時(shí)readata=0x0018,按鍵彈起之后readata=0x0058。