페이지

글목록

2017년 2월 15일 수요일

[ESP8266] SPI 통신 테스트 (ARDUINO IDE)

SPI 통신 테스트를 하려고 보니까, 
함수가 크게 2가지로 나눠서 볼 수 있는데, 특히 transferBytes(uint8_t * out, uint8_t * in, uint32_t size)함수는 
설명을 읽어 보아도 잘 모르겠어서 직접 테스트를 해 보게 되었습니다.

먼저 2가지라고 말씀 드린 함수는 대표적으로 다음과 같습니다.
PC의 다음 위치의 SPI.CPP 파일에 정의되어 있습니다.
C:\Users\trion\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\SPI
1. void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size)
2. void SPIClass::writeBytes(uint8_t * data, uint32_t size)

관련된 비슷하거나 파생된 함수는 몇가지 더 있습니다만, 이 2가지 함수가 많은 데이터를 보내면서
테스트하기에 적합해서 2가지 함수로 테스트를 진행했습니다.

하드웨어 구성은 예전에 테스트하다가 중단하고 그냥 놔둔 Serial Nand Flash IC(W25N01GxxIG)를 사용해서
ESP-8266의 HSPI 포트에 연결했습니다. 얼마 전까지 SD-Card 를 연결했던 포트죠.


[ESP-8266 개발 키트에서 사용한 SPI 포트들] 


NAND 랑 연결을 하고 테스트를 크게 2가지로 진행했습니다.
1. 10 바이트 전송.
  - writeBytes() 함수와 transferBytes() 함수의 차이점은 읽기가 되는지 안되는지의 차이 입니다.
    transferBytes() 함수로도 쓰기 기능만 사용할 수 있고 writeBytes() 함수가 약간 더 빠름니다.
  - 쉽게 말하면, writeBytes() 함수는 Write 전용, transferBytes() 함수는 Full Duplex 통신이라고 볼 수 있다.
  - 다음의 그림은 writeBytes() 함수와 읽기/쓰기 겸용(Full Duplex)으로 사용한 transferBytes() 함수의 전송속도 차이를 보여주는 신호 파형이다.



 2. 100 바이트 전송.
다음은 이 2개의 함수에서 대용량 바이트를 전송할 경우의 특성을 살펴 보았다.
여러 바이트를 전송할 경우에, ESP IC는 기본으로 다른 칩에서의 DMA 기능처럼 SCLK가 끊어짐 없이 출력되었다.
하지만 64-Byte 마다 약간의 딜레이가 있다. 
이 딜레이는  transferBytes() 함수에서 읽기 기능을 사용했을 경우 크게 늘어난다. 
읽기 기능을 사용하지 않으면 두 함수의 64 Byte 간의 딜레이의 차이는 별로 없다.
[transferBytes() 함수의 특성]



 [writeBytes() 함수의 특성]



다음은 아두이노 IDE 툴에서 사용한 프로그램 소스 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <Arduino.h>
#include "SPI.h"
#include "HardwareSerial.h"
#define nSPI_CS   4
void setup() {
  int i;
  uint8_t in_buf[100],out_buf[100];
  char ser_tx_buf[100];
  
  delay(1000);
  
  Serial.begin(115200);
  // put your setup code here, to run once:
  digitalWrite(nSPI_CS, HIGH);
  pinMode(nSPI_CS, OUTPUT);
  pinMode(SCK, SPECIAL);  ///< GPIO14
  pinMode(MISO, SPECIAL); ///< GPIO12
  pinMode(MOSI, SPECIAL); ///< GPIO13
  SPI1C = 0;
  SPI.setFrequency(20000000); ///< 20MHz
  SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
  SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO);
  SPI1C1 = 0;
  for (i=0;i<10;i++)
  {
    out_buf[i] = i;
  }
    out_buf[0= 0x9F;
    out_buf[1= 0;
    out_buf[2= 0;
    out_buf[3= 0;
    out_buf[4= 0;
    
  digitalWrite(nSPI_CS, LOW);
  // 10 Byte Transfer
  //SPI.transferBytes(out_buf,in_buf,10);
  //SPI.writeBytes(out_buf,10);
  // 100 Byte transfer
  //SPI.transferBytes(out_buf,in_buf,100);
  //SPI.transferBytes(NULL,NULL,100);
  //SPI.transferBytes(out_buf,NULL,100);
  //SPI.transferBytes(NULL,in_buf,100);
  SPI.writeBytes(out_buf,100);
  digitalWrite(nSPI_CS, HIGH);
  sprintf(ser_tx_buf,"\n\nSPI Test Program in:%02X,%02X,%02X,%02X,%02X\n\r",in_buf[0],in_buf[1],in_buf[2],in_buf[3],in_buf[4]);
  Serial.print(ser_tx_buf);
}
void loop() {
  // put your main code here, to run repeatedly:
}
cs

댓글 없음:

댓글 쓰기