23LC1024四線訪問數據

爲什麼需要四線串行訪問23LC1024?

在“單片機片外RAM,串行的”中減少了對Microchip公司的SPI接口RAM芯片:23LC1024的讀寫測試。但是在STC8G1K08但潘辰的SPI接口驅動下,訪問對其進行一次字節的讀寫操作,大概需要消耗20微妙的的時間,這使得在高速、高精度採集應用中跟不上數據的採集。

爲了提高對其的訪問速度,可以採用以下的方式:

  • 使用其四線串行模式(SQI)的方式進行訪問;
  • 儘量使用序列讀寫方式,而不是每次完成完整的命令+地址+數據的腹瀉方式

下面爲了配合AD7606八通道AD採集模塊測試中數據的採集,首先測試23LC1024在STC8G1K08操作下訪問速度

本文實驗中的工程文件可以在下面資源中下載:

  1. 23LC1024串行四線訪問工程

 

實驗電路設計

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

▲ CS波形,時間爲2.03us

讀出的時間也是2.0us,

LC1024ByteRead(0x0, 0x0, 0xff)

下面是在讀的時候,CLK, SO1的波形。

▲ CLK,SD1的波形

▲ 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。這說明讀取單個字節的時間大約爲(8.572)/10=0.65μs\left( {8.57 - 2} \right)/10 = 0.65\mu s左右。

這個速度與博文“擴展32KRAM的STC8H8K信號採集版”中,通過並口擴展RAM的一次讀寫時間0.532us的速度基本相當了。

通過這個時間可以說明,使用SQI(串行四線制)在連續讀寫的情況下可以達到與並口擴展RAM相當的速度。

即使是單個讀寫所消耗的2us的時間,也比在博文“單片機片外RAM,串行的”中讀取單個字節所消耗19.2us將近快了10倍左右。

▲ 通電進行調試

▲ 通電進行調試

▲ 測量讀寫信號波形

▲ 測量讀寫信號波形

函數程序模塊

相關LC1024讀取的程序模塊如下。

其中致的說明的是,在LC1024的初始化函數中,調用了LC1024Reset命令,就保證了LC1024成功進入SQI模式。

  1. LC1024訪問函數頭文件:
/*
**==============================================================================
** LC1024L4.H:            -- by Dr. ZhuoQing, 2020-05-04
**
**  Description:
**
**==============================================================================
*/
#ifndef __LC1024L4__
#define __LC1024L4__
//------------------------------------------------------------------------------
#ifdef LC1024L4_GLOBALS
   #define LC1024L4_EXT
#else
   #define LC1024L4_EXT extern
#endif // LC1024L4_GLOBALS
//------------------------------------------------------------------------------
//==============================================================================
#define LC1024_CS           1, 5
#define LC1024_CLK          1, 4
#define LC1024_SO0          1, 0
#define LC1024_SO1          1, 1
#define LC1024_SO2          1, 2
#define LC1024_SO3          1, 3

#define LC1024_CLK_PULSE    ON(LC1024_CLK),_nop_(),OFF(LC1024_CLK)
#define LC1024_SO_OUT       (P1M1 &= 0xf0, P1M0|=0xf)
#define LC1024_SO_IN        (P1M1 |= 0xf,  P1M0 &= 0xf0)

//------------------------------------------------------------------------------

void LC1024L4Init(void);


//------------------------------------------------------------------------------
#define LC1024_READ         0x03            // Read data from memory areray beginning at selected address
#define LC1024_WRITE        0x02            // Write data to memory array beginning at selected address
#define LC1024_EDIO         0x3B            // Enter Dual I/O access(Enter SDI bus mode)
#define LC1024_EQIO         0x38            // Enter Quad I/O access
#define LC1024_RSTIO        0xFF            // Reset Dual and Quad I/O access
#define LC1024_RDMR         0x05            // Read Mode register
#define LC1024_WRMR         0x1             // Write Mode register

#define LONG_3(w)           ((unsigned char)(w >> 24))
#define LONG_2(w)           ((unsigned char)(w >> 16))
#define LONG_1(w)           ((unsigned char)(w >> 8))
#define LONG_0(w)           ((unsigned char)w)



//------------------------------------------------------------------------------
void LC1024Reset(void);
void LC1024EQIEnter(void);
void LC1024EQIExit(void);


//------------------------------------------------------------------------------
unsigned char LC1024ByteRead(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0);
void LC1024ByteWrite(unsigned char ucAdd2, unsigned char ucAdd1, 
                     unsigned char ucAdd0, unsigned char ucByte);

//------------------------------------------------------------------------------
void LC1024ReadBegin(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0);
void LC1024WriteBegin(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0);
unsigned char LC1024ReadByte(void);
void LC1024WriteByte(unsigned char ucByte);
void LC1024ReadWriteEnd(void);

//------------------------------------------------------------------------------
unsigned char LC1024ReadMode(void);
void LC1024WriteMode(unsigned char ucMode);

//==============================================================================
//             END OF THE FILE : LC1024L4.H
//------------------------------------------------------------------------------
#endif // __LC1024L4__
  1. LC1024的C語言程序。
/*
**==============================================================================
** LC1024L4.C:             -- by Dr. ZhuoQing, 2020-05-04
**
**==============================================================================
*/

//------------------------------------------------------------------------------
#define LC1024L4_GLOBALS        1              // Define the global variables
#include "LC1024L4.H"
#include "C51BASIC.H"
#include "STC8G.H"
#include "INTRINS.H"

//------------------------------------------------------------------------------

void LC1024L4Init(void) {
    PM_PP(LC1024_CS);
    PM_PP(LC1024_CLK);
    
    ON(LC1024_CS);
    OFF(LC1024_CLK);
    
    LC1024_SO_IN;

    LC1024Reset();
    LC1024EQIEnter();
}

//------------------------------------------------------------------------------
void LC1024EQIEnter(void) {
    unsigned char i, 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);
        else OFF(LC1024_SO0);
        
        ucMask >>= 1;
        LC1024_CLK_PULSE;
    }
    
    
    LC1024_SO_IN;
    ON(LC1024_CS);

}

void LC1024EQIExit(void) {
    LC1024_SO_OUT;
    P1 |= 0xf;
    OFF(LC1024_CS);
    LC1024_CLK_PULSE;
    LC1024_CLK_PULSE;
    LC1024_SO_IN;
    ON(LC1024_CS);
    
}

//------------------------------------------------------------------------------
unsigned char LC1024ByteRead(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0) {
    unsigned char ucRet;
    
    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;                       // Dummy byte
    LC1024_CLK_PULSE;    
    
    ON(LC1024_CLK);
    ucRet = (P1 << 4);
    OFF(LC1024_CLK);
    
    ON(LC1024_CLK);
    ucRet |= (P1 & 0xf);
    OFF(LC1024_CLK);

    ON(LC1024_CS);
    return ucRet;
    
}


//------------------------------------------------------------------------------
void LC1024ByteWrite(unsigned char ucAdd2, unsigned char ucAdd1, 
                     unsigned char ucAdd0, unsigned char ucByte) {
    
    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);
}

//------------------------------------------------------------------------------
unsigned char LC1024ReadMode(void) {
    unsigned char ucRet;
    
    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);
    return ucRet;
    

}

//------------------------------------------------------------------------------
void LC1024ReadBegin(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0) {
    
    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;                       // Dummy byte
    LC1024_CLK_PULSE;    
    
    
}

//------------------------------------------------------------------------------
void LC1024WriteBegin(unsigned char ucAdd2, unsigned char ucAdd1, unsigned char ucAdd0) {
    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;
    
}

unsigned char LC1024ReadByte(void) {
    unsigned char ucRet;
    
    ON(LC1024_CLK);
    ucRet = (P1 << 4);
    OFF(LC1024_CLK);
    
    ON(LC1024_CLK);
    ucRet |= (P1 & 0xf);
    OFF(LC1024_CLK);
    
    return ucRet;
}

void LC1024WriteByte(unsigned char ucByte) {
    P1 &= 0xf0;
    P1 |= (ucByte >> 4);
    LC1024_CLK_PULSE;
    P1 &= 0xf0;
    P1 |= (ucByte & 0xf);
    LC1024_CLK_PULSE;

}

//------------------------------------------------------------------------------
void LC1024ReadWriteEnd(void) {
    LC1024_SO_IN;
    ON(LC1024_CS);    
}


//------------------------------------------------------------------------------
void LC1024WriteMode(unsigned char ucMode) {
    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;
}

//------------------------------------------------------------------------------
void LC1024Reset(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;
    
}

//==============================================================================
//                END OF THE FILE : LC1024L4.C
//------------------------------------------------------------------------------

結論

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章