初级会员

- 积分
- 126
- 金钱
- 126
- 注册时间
- 2014-10-13
- 在线时间
- 0 小时
|
5金钱
实验室做控制平台,STM32做主控芯片,用FSMC与控制芯片的链接是这样的
然后FSMC_CS链接在FSMC_NE4,那也就是选择的NOR Flash BANK1中的子BANK4了??
1. 请问BANK1中的四个子BANK的起始地址分别是什么? 在手册上的FSMC部分怎么没有看见这个?
然后,我理解的工作原理是这样的(恳请指正!):硬件电路连接好了之后,我就需要写控制芯片的底层驱动函数,这些函数的作用就是实现与主控芯片之间进行数据交换,由于FSMC的工作特点,所以我在函数中就是通过这样的赋值语句(*(volatile unsigned short int*)(0x60000000 | X_Add) = val;)直接可以实现一定的数据(val)写在了一定的地址(0x60000000 | X_Add),这时val值就通过D0-D15呈现出来,而地址(0x60000000 | X_Add)就通过A0-A25呈现出来,其中0x60000000指示了NOR Flash BANK1中子BANK1的基地址(子BANK4是否是0x60000000
| 0x0C000000???),而X_Add就使FSMC_A0-FSMC_A4保持住0x0006一段时间,传递到控制芯片的A1-A4,从而A1-A4端的电平状态就映射指示到了控制芯片的内部目标寄存器COMW,然后D0-D15的16位数据就自动写入了COMW。
这里有个问题是2.请问网友的例程一般都是FSMC驱动LCD,所以会把FSMC_A0接在了LCD的RS端,所以最后的地址赋值需要左移一位,而我的A0端直接接在了控制芯片的地址上,这时候我在地址赋值的时候是否就不用再移位,而是直接赋值??
按照上面的原理我就编写了如下的控制芯片驱动函数:
[mw_shl_code=c,true]#include "PCL_Function.h"
uint16 *pBufw0, *pBufw1, *pComw, *pOtpw, *pMSTSW, *pSSTSW;
// 根据各轴的地址分别设置各轴对应的主寄存器地址
void SetAxis(uint32 axis)
{
switch(axis)
{
case AXIS_X:
pComw = (uint16*)((AXIS_X << 3) | (COMW << 1)); // 以下都需要加上BANK的基地址0x60000000 | 0x0C000000
pBufw0 = (uint16*)((AXIS_X << 3) | (BUFW0 << 1));
pBufw1 = (uint16*)((AXIS_X << 3) | (BUFW1 << 1));
pOtpw = (uint16*)((AXIS_X << 3) | (OTPW << 1));
pMSTSW = (uint16*)((AXIS_X << 3) | (MSTSW << 1));
pSSTSW = (uint16*)((AXIS_X << 3) | (SSTSW << 1));
break;
case AXIS_Y:
pComw = (uint16*)((AXIS_Y << 3) | (COMW << 1));
pBufw0 = (uint16*)((AXIS_Y << 3) | (BUFW0 << 1));
pBufw1 = (uint16*)((AXIS_Y << 3) | (BUFW1 << 1));
pOtpw = (uint16*)((AXIS_Y << 3) | (OTPW << 1));
pMSTSW = (uint16*)((AXIS_Y << 3) | (MSTSW << 1));
pSSTSW = (uint16*)((AXIS_Y << 3) | (SSTSW << 1));
break;
case AXIS_Z:
pComw = (uint16*)((AXIS_Z << 3) | (COMW << 1));
pBufw0 = (uint16*)((AXIS_Z << 3) | (BUFW0 << 1));
pBufw1 = (uint16*)((AXIS_Z << 3) | (BUFW1 << 1));
pOtpw = (uint16*)((AXIS_Z << 3) | (OTPW << 1));
pMSTSW = (uint16*)((AXIS_Z << 3) | (MSTSW << 1));
pSSTSW = (uint16*)((AXIS_Z << 3) | (SSTSW << 1));
break;
case AXIS_U:
pComw = (uint16*)((AXIS_U << 3) | (COMW << 1));
pBufw0 = (uint16*)((AXIS_U << 3) | (BUFW0<<1));
pBufw1 = (uint16*)((AXIS_U << 3) | (BUFW1<<1));
pOtpw = (uint16*)((AXIS_U << 3) | (OTPW<<1));
pMSTSW = (uint16*)((AXIS_U << 3) | (MSTSW<<1));
pSSTSW = (uint16*)((AXIS_U << 3) | (SSTSW<<1));
break;
default:
break;
}
}
// 写命令操作
void WriteCommand(uint32 comm, uint32 axisaddr, uint32 axissel)
{
uint32 axiscomm = comm | axissel;
SetAxis(axisaddr);
*pComw = axiscomm;
}
// 写Buffer操作
void WriteBuffer(uint32 axisaddr, uint32 buf0, uint32 buf1)
{
SetAxis(axisaddr);
*pBufw0 = buf0;
*pBufw1 = buf1;
}
// 读Buffer操作
void ReadBuffer(uint32 axisaddr, uint32 *buf0, uint32 *buf1)
{
SetAxis(axisaddr);
*buf0 = *pBufw0;
*buf1 = *pBufw1;
}
// 读MSTSW
void ReadMSTSW(uint32 axisaddr, uint32 *sts)
{
SetAxis(axisaddr);
*sts = *pMSTSW;
}
// 读SSTSW
void ReadSSTSW(uint32 axisaddr, uint32 *sts)
{
SetAxis(axisaddr);
*sts = *pSSTSW;
}
// 写I/O口
void WriteOTPW(uint32 axisaddr, uint32 value)
{
SetAxis(axisaddr);
*pOtpw = value;
}
// 写寄存器
void WriteRegister(uint32 comm, uint32 buf0, uint32 buf1, uint32 axisaddr, uint32 axissel)
{
WriteBuffer(axisaddr, buf0, buf1);
WriteCommand(comm, axisaddr, axissel);
}
// 读寄存器
void ReadRegister(uint32 comm, uint32 *buf0, uint32 *buf1, uint32 axisaddr)
{
WriteCommand(comm, axisaddr, AxisSel_Default);
ReadBuffer(axisaddr, buf0, buf1);
}
[/mw_shl_code]
通过上面的驱动函数,在主程序中我就可以直接调用来读写控制芯片内部的寄存器,从而达到控制的目的....
请问,上面的编写是否可以实现!??搞了一个星期了,就搞出来点儿这个东西,还不知道对不对,恳请原子哥给点儿意见!!
最后的问题就是,3.请问编写完了这个,我是否就可以在主程序中进行FSMC的响应配置了,关于FSMC的配置有什么指导性的技术贴,请原子哥给推荐推荐。
非常感谢.......
|
最佳答案
查看完整内容[请看2#楼]
回复【5楼】MichealLee:
---------------------------------
那就得根据PCL6045的时序,去配置FSMC。
|