Карты формата SD (Secure Digital) в настоящее время являются одними из наиболее популярных типов карт, используемых для хранения информации, и находят широкое применение в смартфонах, цифровых камерах и других электронных устройствах. Но, возможно вы не знали, что записывать и считывать информацию с этих карт можно с помощью обычного 8-битного микроконтроллера. В этой статье мы исправим этот недостаток и рассмотрим запись информации на SD карту с помощью микроконтроллера PIC. Для этой цели мы будем подключать к микроконтроллеру PIC модуль работы с SD картами.
Ранее на нашем сайте мы уже рассматривали логгер данных на SD карту на основе платы Arduino, но, к сожалению, на микроконтроллере PIC эти процессы выглядят намного сложнее чем в плате Arduino.
Различные типы SD карт
Карты формата SD (Secure Digital) представляют собой устройства хранения информации с энергонезависимой памятью, разработанные SD Associations (SDA) и предназначенные для применения в портативных устройствах. Всего существует 4 основные разновидности данных карт.
SDSC (Secure Digital Standard Capacity, стандартной емкости)
Наиболее распространенный тип SD карт. Карты этого типа обладают максимальной емкостью 2 Гб и используют файловую систему FAT16. Максимальная скорость передачи информации в этих картах составляет 12,5 Мбит/с.
SDHC (Secure Digital High-Capacity, высокой емкости)
Эти карты обладают максимальной емкостью до 32 Гб и используют файловую систему FAT32. В большинстве случаев данные карты используют скорость передачи данных 12,5 или 25 Мбит/с, но они могут поддерживать скорость до 3938 Мбит/с в зависимости от используемого интерфейса шины (UHS-I, UHS-II, UHS-III, SD-Express).
SDXC (Secure Digital eXtended-Capacity, расширенной емкости)
Эти карты обладают максимальной емкостью до 2 Тб и используют файловые системы FAT32 или exFAT. Скорость передачи данных для этих карт по умолчанию составляет 12,5 или 25 Мбит/с, но они могут поддерживать скорость до 3938 Мбит/с в зависимости от используемого интерфейса шины (UHS-I, UHS-II, UHS-III, SD-Express).
SDUC (Secure Digital Ultra-Capacity)
Эти карты обладают максимальной емкостью до 128 Тб и используют только файловую систему exFAT. Скорость передачи данных для этих карт по умолчанию также составляет 12,5 или 25 Мбит/с, но они могут поддерживать скорость до 3938 Мбит/с в зависимости от используемого интерфейса шины (UHS-I, UHS-II, UHS-III, SD-Express).
SDIO (Secure Digital Input Output)
SDIO – это тип интерфейса для карт формата SD. Он может быть использован в качестве интерфейса ввода или вывода данных.
SD карты также классифицируются с соответствии со скоростью записи на них и физическим размерам.
Основные принципы работы с SD картами
В общем случае SD карта имеет 9 контактов, но только 7 из этих контактов используются для взаимодействия с картой по интерфейсу SPI. Внешний вид SD карты формата MicroSD и модуля для работы с SD картами показан на следующем рисунке.
Стандартная SD карта может работать в 3 режимах:
1. SPI Mode Pin Configuration
2. One-bit SD mode Pin Configuration
3. Four-bit SD Mode Pin Configuration
В данном проекте мы будем взаимодействовать с SD картой по интерфейсу SPI, более подробно об использовании данного интерфейса в микроконтроллерах PIC вы можете прочитать в этой статье. Рабочая частота обмена данными с SD картой в нашем проекте будет составлять от 100 до 400 кГц.
Необходимые компоненты
- Микроконтроллер PIC18F46K22 (купить на AliExpress).
- Модуль работы с SD картами (с регулятором напряжения 3.3 В и переключателем логических уровней) (купить на AliExpress).
- Программатор PICkit 3 (купить на AliExpress).
- Кварцевый генератор 20 МГц (купить на AliExpress).
- Конденсаторы 33 пФ (2шт.) (купить на AliExpress).
- Резисторы 4,7 кОм и 100 Ом (купить на AliExpress).
- Резисторы 3,3 кОм (3 шт.) и 2,2 кОм (3 шт.) для понижения уровня напряжения (если будете работать с SD картой напрямую) (купить на AliExpress).
- Светодиод (купить на AliExpress).
- Кнопка.
- Адаптер 12V для питания микроконтроллера PIC и модуля SD карт.
- Макетная плата.
- Соединительные провода.
Реклама: ООО «АЛИБАБА.КОМ (РУ)» ИНН: 7703380158
Схема проекта
Схема логгера на SD карту на основе микроконтроллера PIC представлена на следующем рисунке.
1 |
SD Card input voltage = 5v x (3.3k/ (2.2k+3.3k)) = 3v |
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Объяснение программы для микроконтроллера PIC
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В данном проекте мы будем использовать для работы с модулем SD карт библиотеку Chan’s FatFs Generic FAT File System Module library. Для написания программы для микроконтроллера PIC18F46K22 мы будем использовать Microchip Code Configurator(MCC).
Первым делом в программе подключим используемые библиотеки.
1 2 |
#include "mcc_generated_files/mcc.h" #include "ff.h" |
Далее объявим две переменные fatFs и file, необходимые для работы с SD картой.
1 2 |
FATFS fatFs; /* FatFs work area needed for each volume */ FIL file; /* File object needed for each open file */ |
Затем запрограммируем функцию для мигания светодиода. Периодичность мигания светодиода будет задаваться с помощью Timer0. Число, загружаемое в Timer0, мы подберем таким образом чтобы период мигания светодиода составлял 1 секунду.
1 2 3 |
void blink_led(){ IO_RA1_Toggle(); } |
В основной функции программы main() мы будем вызывать функцию SYSTEM_Initialize() для инициализации периферийных устройств (прерывания, контакты, Timer0, Uart, SPI1). Также в ней мы установим глобальное разрешение прерываний и разрешим прерывания от периферийных устройств.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void main(void) { UINT bw; // Initialize the device SYSTEM_Initialize(); // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts // Use the following macros to: // Enable the Global Interrupts INTERRUPT_GlobalInterruptEnable(); // Disable the Global Interrupts //INTERRUPT_GlobalInterruptDisable(); // Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable(); // Disable the Peripheral Interrupts //INTERRUPT_PeripheralInterruptDisable(); |
После этого мы будем вызывать функцию TMR0_SetInterruptHandler() чтобы задать функцию обработки прерывания от таймера, и затем мы запустим в работу Timer0.
1 2 |
TMR0_SetInterruptHandler(blink_led); TMR0_StartTimer(); |
После выполнения всех этих предварительных инициализаций мы начнем основной процесс работы с SD картой. Сначала нам необходимо будет смонтировать SD карту при помощи вызова функции f_mount() и сохранить возвращаемое ею значение в переменную под названием FRESULT. Проверив содержимое этой переменной мы можем двигаться дальше. Если ее значение равно FR_OK – это будет означать что SD карта успешно смонтирована, в противном случае эта операция не удалась. После успешного монтирования SD карты мы будем вызывать функцию call f_open() для создания файла с именем “test.txt” и затем использовать функцию f_lseek() для перемещения курсора в конец этого файла. После этого мы будем вызывать функцию f_write() для записи информации в созданный нами файл и в конце этого процесса мы будем вызывать функцию f_close() для закрытия файла на SD карте.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
printf("\r\n============= Start Interfacing with SD Card =============\r\n"); FRESULT stat = f_mount(&fatFs, "", 1); if (stat == FR_OK) { /* Mount SD */ printf("SD Card Mount Successful\r\n"); SD_LED_SetHigh(); if (f_open(&file, "Sd_test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE) == FR_OK) { /* Open or create a file */ printf("Create a file successful\r\n"); if ((file.fsize != 0) && (f_lseek(&file, file.fsize) != FR_OK)) goto endSD; /* Jump to the end of the file */ f_write(&file, "Hello Guys!\r\n", 13, &bw); f_write(&file, "This is text message written to SD card. For more information, please visit www.circuitdigest.com\r\n", 99, &bw); endSD: f_close(&file); /* Close the file */ SD_LED_SetLow(); }else{ printf("Create a file unsuccessful\r\n"); SD_LED_SetLow(); } }else{ printf("SD Card Mount UnSuccessful\r\n ------ FRESULT %d ------\r\n"); } printf("\r\n============= Finish Interfacing with SD Card ============= \r\n\r\n\r\n\r\n"); |
Тестирование работы проекта
После того как аппаратная и программная части нашего проекта будут готовы мы протестируем его работу с помощью лога, присутствующего в коде нашей программы. Как вы можете видеть, мы использовали конвертер USB в UART чтобы выводить лог отладки в окно монитора последовательной связи, в качестве которого мы использовали программу PuTTY.
После того как мы увидим сообщение ‘Create a file successful’ мы вытащим нашу SD карту из модуля для работы с SD картами и поместим SD карту в компьютер чтобы проверить успешно ли записался на нее наш файл.
После этого можно открыть файл и проверить его содержимое – так мы проверим успешность нашей операции записи в этот файл.
Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
Исходный код программы
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 |
#include "mcc_generated_files/mcc.h" #include "ff.h" FATFS fatFs; /* FatFs work area needed for each volume */ FIL file; /* File object needed for each open file */ void blink_led(){ IO_RA1_Toggle(); } /* Main application */ void main(void) { UINT bw; // Initialize the device SYSTEM_Initialize(); // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts // Use the following macros to: // Enable the Global Interrupts INTERRUPT_GlobalInterruptEnable(); // Disable the Global Interrupts //INTERRUPT_GlobalInterruptDisable(); // Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable(); // Disable the Peripheral Interrupts //INTERRUPT_PeripheralInterruptDisable(); TMR0_SetInterruptHandler(blink_led); TMR0_StartTimer(); SD_LED_SetLow(); printf("##########################################################\r\n"); printf("SD Interface with PIC18\r\n"); printf("##########################################################\r\n"); printf("System setup Done\r\n"); printf("\r\n============= Start Interfacing with SD Card =============\r\n"); FRESULT stat = f_mount(&fatFs, "", 1); if (stat == FR_OK) { /* Mount SD */ printf("SD Card Mount Successful\r\n"); SD_LED_SetHigh(); if (f_open(&file, "Sd_test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE) == FR_OK) { /* Open or create a file */ printf("Create a file successful\r\n"); if ((file.fsize != 0) && (f_lseek(&file, file.fsize) != FR_OK)) goto endSD; /* Jump to the end of the file */ f_write(&file, "Hello Guys!\r\n", 13, &bw); f_write(&file, "This is text message written to SD card. For more information, please visit www.circuitdigest.com\r\n", 99, &bw); endSD: f_close(&file); /* Close the file */ SD_LED_SetLow(); }else{ printf("Create a file unsuccessful\r\n"); SD_LED_SetLow(); } }else{ printf("SD Card Mount UnSuccessful\r\n ------ FRESULT %d ------\r\n"); } printf("\r\n============= Finish Interfacing with SD Card ============= \r\n\r\n\r\n\r\n"); while (1) { // Add your application code } } /** End of File */ |
4 ответа к “Запись информации на SD карту с помощью микроконтроллера PIC”
Добрый день, можете помочь с описанием схемы этого проекта, не могу разобраться, буду очень благодарен
Добрый вечер. А что конкретно в этой схеме вас интересует? Вроде бы схема достаточно простая и частично описана в статье
хотелось бы поподробнее узнать, каким образом для работы с 2ТБ используется FAT32 на картах SDHC
Ну может быть небольшая опечатка в статье. Но не в этом же основной смысл статьи. ))