This shows you the differences between two versions of the page.
| en:examples:storage:sdcard [2012/06/18 15:09] – created raivo.sell | en:examples:storage:sdcard [2026/02/19 11:30] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== SD card ====== | ||
| + | //Required knowledge: | ||
| + | [HW] [[et: | ||
| + | [LIB] [[et: | ||
| + | |||
| + | ===== Theory ===== | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | Secure Digital (SD) is a memory card format developed by the SD Card Association (SDA) for portable devices. Communication can use the card's SD interface or the SPI bus. SPI is a good option for simpler systems. The SD card operating voltage is 3.3 V. | ||
| + | |||
| + | An SD card is basically a large set of memory bits that can be modified, but other devices cannot use the stored data without a file system. The file system enables working with files instead of the raw memory array. One of the main tasks of a file system is to organize logical files on the physical storage device. The storage space is divided into sectors, usually 512 bytes in size. Since it is more efficient to work with larger units, sectors are grouped into clusters. A cluster is a contiguous set of sectors. Larger clusters reduce fragmentation for large files, but increase wasted space for small files because some clusters remain only partially filled. | ||
| + | |||
| + | Portable storage devices and memory cards commonly use the FAT (File Allocation Table) file system, supported by most operating systems. The FAT file allocation table contains an entry for each file's starting cluster, which points to the next cluster for the file, and so on until the end-of-file cluster. In FAT, clusters are addressed in an n-bit address table where n depends on FAT version: 12 (FAT12), 16 (FAT16), or 32 bits (FAT32). In older FAT versions, large disk sizes required large cluster sizes, resulting in inefficient space usage. | ||
| + | |||
| + | SD cards are available in three physical form factors: standard SD, smaller miniSD, and smallest microSD. microSD is common in mobile phones and tablets and is also used in the HomeLab Controller module. In addition to form factor, SD cards are divided into generations: | ||
| + | * Generation I: SD - up to 2 GB | ||
| + | * Generation II: SDHC - up to 32 GB | ||
| + | * Generation III: SDXC - up to 2 TB | ||
| + | |||
| + | < | ||
| + | |||
| + | SD cards are available in different speeds, classified by Speed Class Rating (SCR). | ||
| + | Common speed classes are: | ||
| + | * 2 MB/s | ||
| + | * 4 MB/s | ||
| + | * 6 MB/s | ||
| + | * 10 MB/s | ||
| + | |||
| + | ===== Practice ===== | ||
| + | |||
| + | The HomeLab Controller module has a microSD card slot. The card is connected to the SPI bus, and on the HomeLab II Controller module it shares the SPI bus with the Ethernet controller. | ||
| + | The HomeLab library includes the FatFs file system module, which you can read about at [[http:// | ||
| + | |||
| + | For the file system to work, the function // | ||
| + | |||
| + | The second file system layer is in //ff.c// and //ff.h//. It communicates with the first layer via low-level functions and provides file operations. The file system can be mounted only after the disk is initialized, | ||
| + | |||
| + | After initializing the disk and file system, you can start working with files. To open a file use //f_open// with the desired mode. There are many options, for example // | ||
| + | |||
| + | The next example demonstrates reading and writing a text file. Pressing S1 initializes the card and file system. Pressing S3 creates a directory on the disk and a file inside it, then writes content to the file. S2 displays the file contents on the screen. | ||
| + | \\ | ||
| + | \\ | ||
| + | \\ | ||
| + | <code c> | ||
| + | // HomeLab SD card usage example program | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main (void) | ||
| + | { | ||
| + | // Disk error flag | ||
| + | int f_err_flag = -1; | ||
| + | // File system error flag | ||
| + | int d_err_flag = -1; | ||
| + | char f_err_buf[16]; | ||
| + | char d_err_buf[16]; | ||
| + | |||
| + | int variableName = 0; | ||
| + | |||
| + | static FATFS FATFS_Obj; | ||
| + | FIL fil_obj; | ||
| + | |||
| + | char read_buf[20]; | ||
| + | |||
| + | unsigned char new_value1, old_value1 = 0; | ||
| + | unsigned char new_value2, old_value2 = 0; | ||
| + | unsigned char new_value3, old_value3 = 0; | ||
| + | |||
| + | // Configure LEDs and turn them off | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_yellow); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | // LCD initialization and text | ||
| + | lcd_gfx_init(); | ||
| + | lcd_gfx_goto_char_xy(3, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // Infinite loop | ||
| + | while (1) | ||
| + | { | ||
| + | // Read button values | ||
| + | new_value1 = pin_get_debounced_value(button1); | ||
| + | new_value2 = pin_get_debounced_value(button2); | ||
| + | new_value3 = pin_get_debounced_value(button3); | ||
| + | |||
| + | // S1 pressed. Register only one press. | ||
| + | if((!new_value1) && (old_value1)) | ||
| + | { | ||
| + | // SD card initialization | ||
| + | // On failure, set error flag. | ||
| + | d_err_flag = disk_initialize(0); | ||
| + | sw_delay_ms(2); | ||
| + | |||
| + | // File system initialization | ||
| + | // On failure, set error flag. | ||
| + | f_err_flag = f_mount(0, & | ||
| + | sw_delay_ms(2); | ||
| + | } | ||
| + | |||
| + | // S2 pressed. Register only one press | ||
| + | if((!new_value2) && (old_value2)) | ||
| + | { | ||
| + | // Open file " | ||
| + | f_open(& | ||
| + | |||
| + | // Read first 14 characters from file | ||
| + | f_gets (read_buf, | ||
| + | f_close(& | ||
| + | |||
| + | // Write the first 14 characters to the screen | ||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | lcd_gfx_write_string(read_buf); | ||
| + | |||
| + | } | ||
| + | |||
| + | // S3 pressed. Register only one press | ||
| + | if((!new_value3) && (old_value3)) | ||
| + | { | ||
| + | // Random variable to store in file | ||
| + | variableName = 4; | ||
| + | |||
| + | // Create directory " | ||
| + | f_mkdir(" | ||
| + | |||
| + | // Create text file " | ||
| + | f_open(& | ||
| + | |||
| + | // Open file for writing | ||
| + | f_open(& | ||
| + | |||
| + | // Write to file | ||
| + | f_printf(& | ||
| + | |||
| + | // Close file | ||
| + | f_close(& | ||
| + | } | ||
| + | |||
| + | // Remember previous button values | ||
| + | old_value1 = new_value1; | ||
| + | old_value2 = new_value2; | ||
| + | old_value3 = new_value3; | ||
| + | |||
| + | // If SD card is initialized and OK, green LED on, | ||
| + | // otherwise red LED on | ||
| + | if((f_err_flag == 0) && (d_err_flag == 0)) | ||
| + | { | ||
| + | pin_clear(led_green); | ||
| + | pin_set(led_red); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | pin_set(led_green); | ||
| + | pin_clear(led_red); | ||
| + | } | ||
| + | |||
| + | // Display error flag values: | ||
| + | // -1 not initialized | ||
| + | // 0 no error | ||
| + | // 1 (or higher) error | ||
| + | sprintf(f_err_buf, | ||
| + | sprintf(d_err_buf, | ||
| + | |||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | lcd_gfx_write_string(f_err_buf); | ||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | lcd_gfx_write_string(d_err_buf); | ||
| + | |||
| + | sw_delay_ms(2); | ||
| + | } | ||
| + | } | ||
| + | </ | ||