为什么需要四线串行访问23LC1024?
在“ 单片机片外RAM,串行的[1]”中减少了对Microchip公司的SPI接口RAM芯片:23LC1024的读写测试。但是在STC8G1K08但潘辰的SPI接口驱动下,访问对其进行一次字节的读写操作,大概需要消耗20微妙的的时间,这使得在高速、高精度采集应用中跟不上数据的采集。
为了提高对其的访问速度,可以采用以下的方式:
- 使用其四线串行模式(SQI)的方式进行访问;
- 尽量使用序列读写方式,而不是每次完成完整的命令 地址 数据的腹泻方式
下面为了配合 AD7606八通道AD采集模块测试[2]中数据的采集,首先测试23LC1024在STC8G1K08操作下访问速度
本文实验中的工程文件可以在下面资源中下载:
- 23LC1024串行四线访问工程[3]
实验电路设计
AD工程文件目录:
“
AD\Test\2020\TestAD7606STC\TestAD7606STC8G.SchDoc
1. 原理图
电路板设计中采用了STC8G1K08 TSOP20封装的芯片。核心板上集成了23LC1024串行接口的RAM,对于AD7606的接口是通过ADI10芯接口连接。
▲ 原理图
2. PCB
设计电路PCB版图,适宜使用单面PCB板制作实验电路。
▲ 快速制版后的实验电路板
3. 硬件调试
软件开发所在的目录:
“
C51\STC\Test\2020\testAD76068G1K\TestAD76068G.uvproj
置STC8G1K08的硬件选项配置如下:
▲ 单片机硬件选项配置
主要性能测试1. 测试单个字节读写的时间
测试标准写入函数在执行过程中,LC1024的CS的波形:
“
LC1024ByteWrite(0, 0, 0xff, 0xf)
写入时间为2us,CS的波形如下图所示:
▲ CS波形,时间为2.03us
读出的时间也是2.0us,
“
LC1024ByteRead(0x0, 0x0, 0xff)
下面是在读的时候,CLK, SO1的波形。
▲ CLK,SD1的波形
2. 连续字节读写
使用连续字节读写的方式读取多组字节。下面是读取连续10个字节。所需要的时间为8.57us。
LC1024ReadBegin(0x0,0x0,0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024WriteByte(0x0);
LC1024ReadWriteEnd();▲ 连续读取十个字节所需要的时间
如果仅仅执行读取起始和结束的语句:
LC1024ReadBegin(0x0,0x0,0x0);
LC1024ReadWriteEnd();
所小号的时间为2us。这说明读取单个字节的时间大约为左右。
这个速度与博文“ 扩展32KRAM的STC8H8K信号采集版[4]”中,通过并口扩展RAM的一次读写时间0.532us的速度基本相当了。
通过这个时间可以说明,使用SQI(串行四线制)在连续读写的情况下可以达到与并口扩展RAM相当的速度。
即使是单个读写所消耗的2us的时间,也比在博文“ 单片机片外RAM,串行的[5]”中读取单个字节所消耗19.2us将近快了10倍左右。
函数程序模块
相关LC1024读取的程序模块如下。
其中致的说明的是,在LC1024的初始化函数中,调用了LC1024Reset命令,就保证了LC1024成功进入SQI模式。
- LC1024访问函数头文件:
/*
*****************************************
**LC1024L4.H:--byDr.ZhuoQing,2020-05-04
**
**Description:
**
*****************************************
*/
#ifndef__LC1024L4__
#define__LC1024L4__
//------------------------------------------------------------------------------
#ifdefLC1024L4_GLOBALS
#defineLC1024L4_EXT
#else
#defineLC1024L4_EXTextern
#endif//LC1024L4_GLOBALS
//------------------------------------------------------------------------------
//***************************************
#defineLC1024_CS1,5
#defineLC1024_CLK1,4
#defineLC1024_SO01,0
#defineLC1024_SO11,1
#defineLC1024_SO21,2
#defineLC1024_SO31,3#defineLC1024_CLK_PULSEON(LC1024_CLK),_nop_(),OFF(LC1024_CLK)
#defineLC1024_SO_OUT(P1M1&=0xf0,P1M0|=0xf)
#defineLC1024_SO_IN(P1M1|=0xf,P1M0&=0xf0)//------------------------------------------------------------------------------
voidLC1024L4Init(void);
//------------------------------------------------------------------------------
#defineLC1024_READ0x03//Readdatafrommemoryareraybeginningatselectedaddress
#defineLC1024_WRITE0x02//Writedatatomemoryarraybeginningatselectedaddress
#defineLC1024_EDIO0x3B//EnterDualI/Oaccess(EnterSDIbusmode)
#defineLC1024_EQIO0x38//EnterQuadI/Oaccess
#defineLC1024_RSTIO0xFF//ResetDualandQuadI/Oaccess
#defineLC1024_RDMR0x05//ReadModeregister
#defineLC1024_WRMR0x1//WriteModeregister#defineLONG_3(w)((unsignedchar)(w>>24))
#defineLONG_2(w)((unsignedchar)(w>>16))
#defineLONG_1(w)((unsignedchar)(w>>8))
#defineLONG_0(w)((unsignedchar)w)//------------------------------------------------------------------------------
voidLC1024Reset(void);
voidLC1024EQIEnter(void);
voidLC1024EQIExit(void);//------------------------------------------------------------------------------
unsignedcharLC1024ByteRead(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0);
voidLC1024ByteWrite(unsignedcharucAdd2,unsignedcharucAdd1,
unsignedcharucAdd0,unsignedcharucByte);//------------------------------------------------------------------------------
voidLC1024ReadBegin(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0);
voidLC1024WriteBegin(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0);
unsignedcharLC1024ReadByte(void);
voidLC1024WriteByte(unsignedcharucByte);
voidLC1024ReadWriteEnd(void);//------------------------------------------------------------------------------
unsignedcharLC1024ReadMode(void);
voidLC1024WriteMode(unsignedcharucMode);//***************************************
//ENDOFTHEFILE:LC1024L4.H
//------------------------------------------------------------------------------
#endif//__LC1024L4__
- LC1024的C语言程序。
/*
*****************************************
**LC1024L4.C:--byDr.ZhuoQing,2020-05-04
**
*****************************************
*///------------------------------------------------------------------------------
#defineLC1024L4_GLOBALS1//Definetheglobalvariables
#include"LC1024L4.H"
#include"C51BASIC.H"
#include"STC8G.H"
#include"INTRINS.H"//------------------------------------------------------------------------------
voidLC1024L4Init(void){
PM_PP(LC1024_CS);
PM_PP(LC1024_CLK);ON(LC1024_CS);
OFF(LC1024_CLK);LC1024_SO_IN;
LC1024Reset();
LC1024EQIEnter();
}//------------------------------------------------------------------------------
voidLC1024EQIEnter(void){
unsignedchari,ucMask,ucByte;
ucByte=LC1024_EQIO;
ucMask=0x80;LC1024_SO_IN;
PM_PP(LC1024_SO0);OFF(LC1024_CS);
for(i=0;i<8;i ){
if(ucByte&ucMask)ON(LC1024_SO0);
elseOFF(LC1024_SO0);ucMask>>=1;
LC1024_CLK_PULSE;
}LC1024_SO_IN;
ON(LC1024_CS);}
voidLC1024EQIExit(void){
LC1024_SO_OUT;
P1|=0xf;
OFF(LC1024_CS);
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_SO_IN;
ON(LC1024_CS);}
//------------------------------------------------------------------------------
unsignedcharLC1024ByteRead(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0){
unsignedcharucRet;LC1024_SO_OUT;
OFF(LC1024_CS);P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x3;
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd2>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd2&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd1>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd1&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd0>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd0&0xf);
LC1024_CLK_PULSE;LC1024_SO_IN;
LC1024_CLK_PULSE;//Dummybyte
LC1024_CLK_PULSE;ON(LC1024_CLK);
ucRet=(P1<<4);
OFF(LC1024_CLK);ON(LC1024_CLK);
ucRet|=(P1&0xf);
OFF(LC1024_CLK);ON(LC1024_CS);
returnucRet;}
//------------------------------------------------------------------------------
voidLC1024ByteWrite(unsignedcharucAdd2,unsignedcharucAdd1,
unsignedcharucAdd0,unsignedcharucByte){LC1024_SO_OUT;
OFF(LC1024_CS);P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x2;
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd2>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd2&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd1>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd1&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd0>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd0&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucByte>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucByte&0xf);
LC1024_CLK_PULSE;LC1024_SO_IN;
ON(LC1024_CS);
}//------------------------------------------------------------------------------
unsignedcharLC1024ReadMode(void){
unsignedcharucRet;OFF(LC1024_CS);
LC1024_SO_OUT;P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x5;
LC1024_CLK_PULSE;LC1024_SO_IN;
ON(LC1024_CLK);
ucRet=(P1<<4);
OFF(LC1024_CLK);
ON(LC1024_CLK);
ucRet|=(P1&0xf);
OFF(LC1024_CLK);ON(LC1024_CS);
returnucRet;}
//------------------------------------------------------------------------------
voidLC1024ReadBegin(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0){LC1024_SO_OUT;
OFF(LC1024_CS);P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x3;
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd2>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd2&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd1>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd1&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd0>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd0&0xf);
LC1024_CLK_PULSE;LC1024_SO_IN;
LC1024_CLK_PULSE;//Dummybyte
LC1024_CLK_PULSE;}
//------------------------------------------------------------------------------
voidLC1024WriteBegin(unsignedcharucAdd2,unsignedcharucAdd1,unsignedcharucAdd0){
LC1024_SO_OUT;
OFF(LC1024_CS);P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x2;
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd2>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd2&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd1>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd1&0xf);
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucAdd0>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucAdd0&0xf);
LC1024_CLK_PULSE;}
unsignedcharLC1024ReadByte(void){
unsignedcharucRet;ON(LC1024_CLK);
ucRet=(P1<<4);
OFF(LC1024_CLK);ON(LC1024_CLK);
ucRet|=(P1&0xf);
OFF(LC1024_CLK);returnucRet;
}voidLC1024WriteByte(unsignedcharucByte){
P1&=0xf0;
P1|=(ucByte>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucByte&0xf);
LC1024_CLK_PULSE;}
//------------------------------------------------------------------------------
voidLC1024ReadWriteEnd(void){
LC1024_SO_IN;
ON(LC1024_CS);
}//------------------------------------------------------------------------------
voidLC1024WriteMode(unsignedcharucMode){
LC1024_SO_OUT;
OFF(LC1024_CS);P1&=0xf0;
LC1024_CLK_PULSE;
P1|=0x5;
LC1024_CLK_PULSE;P1&=0xf0;
P1|=(ucMode>>4);
LC1024_CLK_PULSE;
P1&=0xf0;
P1|=(ucMode&0xf);
LC1024_CLK_PULSE;ON(LC1024_CS);
LC1024_SO_IN;
}//------------------------------------------------------------------------------
voidLC1024Reset(void){
LC1024_SO_OUT;
P1|=0xf;OFF(LC1024_CS);
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;
LC1024_CLK_PULSE;ON(LC1024_CS);
LC1024_SO_IN;}
//***************************************
//ENDOFTHEFILE:LC1024L4.C
//------------------------------------------------------------------------------结论参考资料
[1] 单片机片外RAM,串行的: https://zhuoqing.blog.csdn.net/article/details/105891541
[2] AD7606八通道AD采集模块测试: https://zhuoqing.blog.csdn.net/article/details/105908384
[3] 23LC1024串行四线访问工程: https://download.csdn.net/download/zhuoqingjoking97298/12388449
[4] 扩展32KRAM的STC8H8K信号采集版: https://zhuoqing.blog.csdn.net/article/details/105798094
,