IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机FSMC与FPGA通信 -> 正文阅读

[嵌入式]单片机FSMC与FPGA通信

话不多说,直接开讲。
单片机使用的是GD32F450XX 主要功能是用GD32F450的EXMC总线与FPGA通信。初次使用所以网上差了很多资料,其实GD32F450的EXMC与STM32的FSMC相差无几,与FPGA通信我是将FPGA模拟成SRAM进行通信。具体单片机型号是 GD32F450ZIT6。
1,因为官方例程只有SDRAM的初始化所以我贴下SRAM的初始化代码:

void exmc_sram_init()
{
	exmc_norsram_parameter_struct        sdram_init_struct;
    exmc_norsram_timing_parameter_struct  read_write_timing;

    uint32_t command_content = 0, bank_select;
    uint32_t timeout = SDRAM_TIMEOUT;

    /* enable EXMC clock*/
    rcu_periph_clock_enable(RCU_EXMC);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOE);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_GPIOG);
    rcu_periph_clock_enable(RCU_GPIOH);

    /* common GPIO configuration */
	
	/* NL(PB7), pin configuration */ 
    gpio_af_set(GPIOB, GPIO_AF_12, GPIO_PIN_7 );
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

    /* D2(PD0),D3(PD1),CLK(PD3),NOE(PD4),NWE(PD5),NWAIT(PD6),NE0(PD7),D13(PD8),D14(PD9),D15(PD10),D0(PD14),D1(PD15) pin configuration */
    gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4 | 
								   GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |
                                   GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4 | 
														 GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |
														 GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4 | 
																	 GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |
																	 GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);

    /* NBL0(PE0),NBL1(PE1),D4(PE7),D5(PE8),D6(PE9),D7(PE10),D8(PE11),D9(PE12),D10(PE13),D11(PE14),D12(PE15) pin configuration */
    gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_0  | GPIO_PIN_1  | 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_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0  | GPIO_PIN_1  | 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_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0  | GPIO_PIN_1  | 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);

    /* A0(PF0),A1(PF1),A2(PF2),A3(PF3),A4(PF4),A5(PF5),A6(PF12),A7(PF13),A8(PF14),A9(PF15) pin configuration */
    gpio_af_set(GPIOF, GPIO_AF_12, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
								   GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_12 | GPIO_PIN_13 |
								   GPIO_PIN_14 | GPIO_PIN_15);
    gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
                                                         GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_12 | GPIO_PIN_13 |
                                                         GPIO_PIN_14 | GPIO_PIN_15);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_2  | GPIO_PIN_3  |
																	 GPIO_PIN_4  | GPIO_PIN_5  | GPIO_PIN_12 | GPIO_PIN_13 |
																	 GPIO_PIN_14 | GPIO_PIN_15);

    /* A10(PG0),A11(PG1),A12(PG2),A13(PG3), pin configuration */
    gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

	/* configure read/write timing */
    read_write_timing.asyn_address_setuptime = 0x0U;					//地址建立时间(ADDSET)为1个HCLK 1/36M=27ns
    read_write_timing.asyn_address_holdtime = 0x0U;						//地址保持时间(ADDHLD)模式A未用到
    read_write_timing.asyn_data_setuptime = 0x08U;						//数据保持时间(DATAST)为9个HCLK 6*9=54ns  
    read_write_timing.bus_latency = 0xFU;								
    read_write_timing.syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
    read_write_timing.syn_data_latency = EXMC_DATALAT_17_CLK;
    read_write_timing.asyn_access_mode = EXMC_ACCESS_MODE_A;
	
	/* configure the structure with default values */
    sdram_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION0; 		//这里我们使用NE0,也就对应BTCR[0],[1]。
    sdram_init_struct.address_data_mux = DISABLE;				   		//地址和数据复用数据线
    sdram_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;		   		//SRAM   
    sdram_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;		//存储器数据宽度为16bit 
    sdram_init_struct.burst_mode = DISABLE;								//突发访问模式
    sdram_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;			//设置WAIT信号的有效电平
    sdram_init_struct.wrap_burst_mode = DISABLE;						//是否使用回环模式
    sdram_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;			//设置WAIT信号有效时机
    sdram_init_struct.memory_write = ENABLE;							//存储器写使能 
    sdram_init_struct.nwait_signal = DISABLE;							//是否使用WAIT信号
    sdram_init_struct.extended_mode = DISABLE;							//是否使用扩展模式,扩展模式用于访问不同读写操作时序的存储器
    sdram_init_struct.asyn_wait = DISABLE;								/*!< enable or disable the asynchronous wait function */
    sdram_init_struct.write_mode = EXMC_ASYN_WRITE;						/*!< asynchronous write mode */
	sdram_init_struct.read_write_timing = &read_write_timing;
	sdram_init_struct.write_timing = &read_write_timing;
   

	exmc_norsram_init(&sdram_init_struct);
	exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION0);
	delay_1ms(10);
}

2,因为用的是EXMC的异步通信,一开始对这些概念不是很熟悉,所以自己弄了半天,最后查官方用户手册找到了一张时序表:
在这里插入图片描述
读数据函数:

void sdram_readbuffer_16(uint32_t sdram_device,uint16_t* pbuffer, uint32_t readaddr, uint32_t numtowrite)
{
    uint32_t temp_addr;
    __IO uint32_t write_addr_prt = readaddr;    
    
    /* select the base address according to EXMC_Bank */
//    if(sdram_device == EXMC_SDRAM_DEVICE0){
//        temp_addr = SDRAM_DEVICE0_ADDR;
//    }else{
//        temp_addr = SDRAM_DEVICE1_ADDR;
//    }
    temp_addr = SRAM_DEVICE0_ADDR;
    /* while there is data to read */
    for(; numtowrite != 0; numtowrite--){
        /* read a byte from the memory */
        *pbuffer++ = *(uint16_t*) (temp_addr + write_addr_prt);
    
        /* increment the address */
        write_addr_prt += 2;
    }
}

首先单片机不断发送读地址命令,然后用示波器看看这些引脚上有没有对应的时序输出,如果有了的话再去找FPGA工程师或者自己根据这个时序来读数据,读数据的时候依据EXMC_NOE的电平变换将对应地址的数据放到数据引脚上,这样就能获取数据了

总结:
不要把EXMC看的很复杂,根据用户手册配置好之后读写数据非常方便,就跟读单片机内存一样。
而与FPGA通信用到的EXMC更简单,因为FPGA可以自行编程,所以只需要你这边地址,数据,信号线上有数据,那边就能更改时序进行处理!所以困难不可怕,相信自己!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:38:44  更:2021-12-24 18:41:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:58:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码