找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17785|回复: 0
收起左侧

STM32通过FSMC进行数据读写信号时序

[复制链接]
ID:85764 发表于 2015-7-15 16:44 | 显示全部楼层 |阅读模式
      
因为工作项目需求,需要使用STM32与FPGA通信进行联合开发,两者通信,自然首选STM32自带的FSMC通信接口。为了搞清楚FSMC的时序与寻址细节,特使用逻辑分析仪对FSMC的8位、16位、32位数据写操作进行了抓取分析,从而得到了FSMC的时序与寻址细节。时间匆忙,少了很多废话的部分,具体的后面再完善吧,具体意图见本文标题。腰好痛啊,最近身体和大脑一直超负荷运转,是该出去转转,出去运动运动了。
8位操作方式:
对地址65534写8位的数i代码
      *(vu8*)(Bank1_SRAM3_ADDR+65534)=i;
      i++;
   
对地址65534写8位的数i时序波形
对地址65535写8位的数i代码
      *(vu8*)(Bank1_SRAM3_ADDR+65534)=i;
      i++;
   
对地址65535写8位的数i时序波形
STM32通过FSMC写8位数据
C代码中地址为实际要写入的地址字节,若将FSMC 的数据位宽配置为16位,则每次寻址实际都寻址了两个字节,例如,FSMC的地址总线值为0,则实际位于地址0有16位,两个字节,因此需要通过高低字节控制信号来区分,即LB和UB信号(注意:所有控制信号都是低电平有效)。例如当希望对地址0上的高字节进行寻址时,则FSMC总线地址值任然为0,同时LB无效(高电平)UB有效(低电平),即可实现对地址0上的高字节单独寻址。假设C代码中的要写入的地址为C_Addr,则实际FSMC总线上地址线的值与LB、UB值的状态为:
FSMC_ADDR = C_Addr/2
FSMC_LB = C_Addr%2
FSMC_UB =~ (C_Addr%2)
16位操作方式:
对地址65534写16位的数6555代码
      *(vu16*)(Bank1_SRAM3_ADDR+65534)=6555;
   
对地址65534写16位的数6555时序波形

对地址65535写16位的数6555代码
      *(vu16*)(Bank1_SRAM3_ADDR+65535)=6555;
   
对地址65535写16位的数6555时序波形
STM32通过FSMC写16位数据
C代码中地址为实际要写入的地址字节,若将FSMC 的数据位宽配置为16位,则每次寻址实际都寻址了两个字节,例如,FSMC的地址总线值为0,则实际位于地址0有16位,两个字节,因此需要通过高低字节控制信号来区分,即LB和UB信号(注意:所有控制信号都是低电平有效)。例如当希望对地址0上的高字节进行寻址时,则FSMC总线地址值任然为0,同时LB无效(高电平)UB有效(低电平),即可实现对地址0上的高字节单独寻址。假设C代码中的要写入的地址为C_Addr,则实际FSMC总线上地址线的值与LB、UB值的状态为:
如果C_Addr为偶数,则
FSMC_ADDR = C_Addr/2
FSMC_LB = FSMC_UB = 0;
FSMC一次性即可完成16位数据的写入。
如果C_Addr为奇数,则实际FSMC会将数据分成两个8位的数据来进行操作,因此效率会低很多。
先写C_Addr,写入数据字节为待写入数据的高字节
FSMC_ADDR = C_Addr/2
FSMC_LB =1;
FSMC_UB =0;
然后写C_Addr + 1地址,写入数据字节为待写入数据的低字节
FSMC_ADDR = (C_Addr + 1) /2
FSMC_LB =0;
FSMC_UB =1;
32位操作方式:
对地址65534写32位的数1265536(0x134F80)代码
      *(vu32*)(Bank1_SRAM3_ADDR+65534)= 1265536;
   
对地址65534写32位的数0x134F80时序波形
对地址65535写32位的数1265536(0x134F80)代码
      *(vu32*)(Bank1_SRAM3_ADDR+65535)= 1265536;
   
对地址65535写32位的数0x134F80时序波形
对地址65536写32位的数1265536(0x134F80)代码
      *(vu32*)(Bank1_SRAM3_ADDR+65536)= 1265536;
   
对地址65536写32位的数0x134F80时序波形
对地址65537写32位的数1265536(0x134F80)代码
      *(vu32*)(Bank1_SRAM3_ADDR+65537)= 1265536;
   
对地址65537写32位的数0x134F80时序波形
STM32通过FSMC写32数据
C代码中地址为实际要写入的地址字节,若将FSMC 的数据位宽配置为16位,则每次寻址实际都寻址了两个字节,例如,FSMC的地址总线值为0,则实际位于地址0有16位,两个字节,因此需要通过高低字节控制信号来区分,即LB和UB信号(注意:所有控制信号都是低电平有效)。例如当希望对地址0上的高字节进行寻址时,则FSMC总线地址值任然为0,同时LB无效(高电平)UB有效(低电平),即可实现对地址0上的高字节单独寻址。假设C代码中的要写入的起始地址为C_Addr,则实际FSMC总线上地址线的值与LB、UB值的状态为:
如果C_Addr为4的倍数,则FSMC首先在起始地址处写入待写入数据的低字节和次低字节:
FSMC_ADDR = C_Addr/2
FSMC_LB = FSMC_UB = 0;
然后FSMC再在起始地址+2处写入待写入数据的低字节和次低字节:
FSMC_ADDR = (C_Addr+2)/2
FSMC_LB = FSMC_UB = 0;
只需要两次16位数据写入操作即可完成一个32位数据的写入,因此效率较高。
如果C_Addr为奇数,则实际FSMC会将数据分成两个8位的数据和一个16位的数据来进行操作,需要3次写入操作才能完成32位数据的写入(效率较低)。
FSMC首先在起始地址(C_Addr)位置以8位写入方式写入待写入数据的低字节:
FSMC_ADDR = C_Addr/2
FSMC_LB = 1;
FSMC_UB = 0;
然后FSMC再在起始地址+2处(C_Addr + 2)以16位数据方式写入带写入数据的次低字节和次高字节:
FSMC_ADDR = (C_Addr+2)/2
FSMC_LB = FSMC_UB = 0;
最后FSMC再在起始地址+4处(C_Addr + 2)以8位写入方式写入待写入数据的高字节:
FSMC_ADDR = (C_Addr+4)/2
FSMC_LB = 0;
FSMC_UB = 1;
小梅哥FPGA设计思想与验证方法教程系列文档
2015年07月10号于Snow Dream电子工作室




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表