페이지

글목록

2016년 12월 14일 수요일

[PSOC5] SD Card I/F (SPI 방식)

안녕하세요, 

이 글은 예정에는 없었지만, 카페에 올린줄 알았는데 없어서 글을 쓰게 되었습니다.

PSOC5에서 micro SD-Card 를 사용하는 방법인데, PSOC5은 SDIO 가 없어서 SPI 방식만 지원합니다.
속도는 24Mhz 입니다.
제가 보기에는 현재까지 PSOC5가 MCU 중에서 가장 사용자 친화적으로 잘 만들어 진 것 같은데,
패키지가 다양하지 않고 후속 모델(PSOC6)이 안나오며, PSOC4만 계속 손데고 있어서 매우 불만이 많습니다.
가격은 요새 좀 내려간 듯 한데, STM32F4xx 에는 가성비가 못미치네요.
PSOC5 이대로 죽는겐가? ㅜㅜ

아.. 헛소리를 많이 했군요. 
그럼 다시 PSOC5에서 SPI 방식으로 SD Card 제어하는 방법을 알아보겠습니다.
PSOC Creator 의 TopDesign.cysch 에 emFile SPI Mode[V1.20] 콤포넌트를 배치하고 
emfile 콤포넌트의 Datasheet를 보면 여기서 설명하려는 내용이 영문으로 나와 있습니다.


1. PSOC Creator 내부에 File System 라이브러리가 없기 때문에 먼전 File System 라이브러리를 다운로드 받아야 합니다.
여기(링크)에서 다운로드 받으시면 됩니다.

2. 받은 파일을 압축을 풀어서 적당한 위치에 놓으십시요. (저는 프로젝트 폴더 옆에 놓았습니다)

3. 콤포넌트 창에서 Communication->FileSystem->emFile 을 TopDesign.cysch 으로 끌고 와서 배치합니다.



4. 왼쪽 Workspace Explorer 의 Project 를 우클릭하여 Build Setting 을 클릭합니다.



5. Include Directory 를 추가




6. 라이브러리 이름 추가. 직접 타이핑해 줍니다.
emf32noslfn 를 타이핑 하고, 이 의미는 No OS , Long File Name 의 의미입니다.



7. 다음은 라이브러리가 있는 디렉토리를 추가합니다.



8. 라이브러리 파일을 추가합니다.



9. 회로를 보고 핀을 배치합니다. (PSOC5는 이것이 장점 : 핀을 맘대로 옮길 수 있습니다.)
디버깅용으로 USB Serial 포트도 하나 넣었습니다.




10. micro-SD 카드 회로도는 다음과 같습니다. 신호에 굳이 풀업저항은 필요 없었습니다.
혹시나 해서 테스트 해 봤는데 잘 되네요.



11. SD 카트에서 데이터를 읽어서 뿌려볼라고 하는데, 구글링해서 "영문 텍스트 소설" 검색하니 해리포터 불의잔이 있네요. ^^
다운받아서 SD Card에 넣습니다.




12. 제작한 기판에 SD Card를 끼웁니다. 회사에서 만든 기판은 다음과 같습니다.




이제 프로그램만 짜면 되는데 불의잔을 읽어서 USB Serial로 터미날에 5000 바이트만 뿌려 보겠습니다.
먼저 결과를 올려 보겠습니다.



잘 읽히네요. 불의 잔. ^^

소스코드는 main.c 에만 코드를 추가했고, SD Card 읽기만 테스트 해 봤습니다.
나머지는 현재까지 읽기 이외의 작업이 필요없었던 관계로 회원 여러분이 찾아서 해 보십시요. ^^
프로젝트 압축해서 첨부합니다. 그런데 emfile 라이브러리는 PSOC Creator에서 한번에 압축을 안해 주네요.
아마도 4~8 과정을 회원분들께서 다시 해 주셔야 될 것 같습니다.

프로젝트 파일 (링크)

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "project.h"
#include <stdio.h>
#include <FS.h>
#define BUFFER_LEN  64u
struct tagFILE
{
    uint8 accmd;
    uint32 sz;
    FS_FILE* fp;
    char tFileName[64];
};
static struct tagFILE   tFILE;
char8 *parity[] = { "None""Odd""Even""Mark""Space" };
char8 *stop[] = { "1""1.5""2" };
void ready_USB_UART_tx(void);
int main(void)
{
    uint8_t buffer[5000];
    uint16_t i;
    char usb_tx[BUFFER_LEN];
    
    
    FS_Init();
    FS_Mount(0);
    FS_FAT_SupportLFN();
    
    CyGlobalIntEnable; /* Enable global interrupts. */
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    
    CyDelay(500);
    
    FS_DIR*     pDir;
    USBUART_1_Start(0u, USBUART_1_3V_OPERATION);
    ready_USB_UART_tx();
    pDir = FS_OpenDir("");
    sprintf(tFILE.tFileName,"Harry_potter_Goblet_of_Fire.txt");
    tFILE.fp = FS_FOpen(tFILE.tFileName, "rb");
    tFILE.sz = FS_GetFileSize (tFILE.fp);
    sprintf(usb_tx,"File size : %5lu\n\r",tFILE.sz);
    while(USBUART_1_CDCIsReady() == 0u);    /* Wait till component is ready to send more data to the PC */ 
    USBUART_1_PutString(usb_tx);       /* Send data back to PC */
    
    FS_FSeek(tFILE.fp,0,0);
    FS_Read(tFILE.fp, buffer, 5000);
    for (i=0;i<5000;i++)
    {
        while(USBUART_1_CDCIsReady() == 0u);    /* Wait till component is ready to send more data to the PC */ 
        USBUART_1_PutChar(buffer[i]);       /* Send data back to PC */
    }
    //proc_USB_UART();
    for(;;)
    {
        /* Place your application code here. */
    }
}
void ready_USB_UART_tx(void)
{
    uint16 count;
    uint8 state,led_st=0,cnt_USB_UART_con=0;;
    uint8 buffer[BUFFER_LEN];
    char tx_buffer[BUFFER_LEN];
   /* Main Loop: */
    for(;;)
    {
        if(USBUART_1_IsConfigurationChanged() != 0u) /* Host could send double SET_INTERFACE request */
        {
            if(USBUART_1_GetConfiguration() != 0u)   /* Init IN endpoints when device configured */
            {
               /* Enumeration is done, enable OUT endpoint for receive data from Host */
                USBUART_1_CDC_Init();
            }
        }         
        if(USBUART_1_GetConfiguration() != 0u)    /* Service USB CDC when device configured */
        {
            if(USBUART_1_DataIsReady() != 0u)               /* Check for input data from PC */
            {   
                count = USBUART_1_GetAll(buffer);           /* Read received data and re-enable OUT endpoint */
                if(count != 0u)
                {
                    while(USBUART_1_CDCIsReady() == 0u);    /* Wait till component is ready to send more data to the PC */ 
                    USBUART_1_PutData(buffer, count);       /* Send data back to PC */
                    /* If the last sent packet is exactly maximum packet size, 
                    *  it shall be followed by a zero-length packet to assure the
                    *  end of segment is properly identified by the terminal.
                    */
                    if(count == BUFFER_LEN)
                    {
                        while(USBUART_1_CDCIsReady() == 0u); /* Wait till component is ready to send more data to the PC */ 
                        USBUART_1_PutData(NULL, 0u);         /* Send zero-length packet to PC */
                    }
                }
            }  
            
            state = USBUART_1_IsLineChanged();              /* Check for Line settings changed */
            if(state != 0u)
            {  
                if(state & USBUART_1_LINE_CODING_CHANGED)   /* Show new settings */
                {
                    sprintf(tx_buffer,"BR:%4ld,DB:%d\n\r",USBUART_1_GetDTERate(),(uint16)USBUART_1_GetDataBits());
                    sprintf(tx_buffer,"SB:%s,Parity:%s\n\r", stop[(uint16)USBUART_1_GetCharFormat()], \
                                                         parity[(uint16)USBUART_1_GetParityType()]);
                }
                if(state & USBUART_1_LINE_CONTROL_CHANGED)  /* Show new settings */
                {   
                    state = USBUART_1_GetLineControl();
                    sprintf(tx_buffer,"DTR:%s,RTS:%s\n\r",  (state & USBUART_1_LINE_CONTROL_DTR) ? "ON" : "OFF", \
                                                        (state & USBUART_1_LINE_CONTROL_RTS) ? "ON" : "OFF");
                    cnt_USB_UART_con++;
                    
                    if (cnt_USB_UART_con > 1)
                        break;
                }
            }
        }
    }   
}
cs

댓글 없음:

댓글 쓰기