Запись и чтение данных

Прежде чем вы начнете

Для многих приложений последовательного порта существует три важных вопроса, которые необходимо рассмотреть при записи или чтении данных:

  • Будет чтение или писать доступ к функциональному блоку к командной строке MATLAB®?

  • Данные должны быть переданы (числовой) двоичный файл или текст?

  • При каких условиях операция чтения или операция записи завершатся?

Для операций записи на эти вопросы отвечают в Записи данных. Для операций чтения на эти вопросы отвечают в Чтении Данных.

Пример - введение в запись и чтение данных

Предположим, что вы хотите возвратить идентификационную информацию для Tektronix® TDS 210 двухканальный осциллограф, соединенный с последовательным портом COM1 на платформе Windows®. Это требует записи *IDN? команда к инструменту с помощью fprintf функция, и читающий назад результат той команды с помощью fscanf функция.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)

Получившаяся идентификационная информация:

out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

Закончите сеанс последовательного порта.

fclose(s)
delete(s)
clear s

Управление доступом к командной строке MATLAB

Вы управляете доступом к командной строке MATLAB путем определения, являются ли операция чтения или операция записи синхронными или асинхронными.

Синхронная операция блокирует доступ к командной строке до чтения, или функция записи завершает выполнение. Асинхронная операция не блокирует доступ к командной строке, и можно дать дополнительные команды, в то время как чтение или пишет, что функция выполняется в фоновом режиме.

Термины, синхронные и асинхронные, часто используются, чтобы описать, как последовательный порт действует на аппаратном уровне. Стандарт RS-232 поддерживает асинхронный протокол связи. Используя этот протокол, каждое устройство использует свои собственные внутренние часы. Передача данных синхронизируется с помощью старт-бита байтов, в то время как один или несколько стоп-битов указывают на конец байта. Для получения дополнительной информации о старт-битах и стоп-битах, смотрите Формат Последовательных данных. Стандарт RS-232 также поддерживает синхронный режим, где все переданные биты синхронизируются с общим сигналом часов.

На аппаратном уровне большинство последовательных портов действует асинхронно. Однако с помощью поведения по умолчанию во многих из чтения и функций записи, можно подражать операции синхронного последовательного порта.

Примечание

Когда используется в этом руководстве, термины, синхронные и асинхронные, относятся к или операции чтения, или операции записи блокируют доступ к командной строке MATLAB. Другими словами, эти условия описывают, как программное обеспечение ведет себя, и не то, как оборудование ведет себя.

Два основных преимущества записи или чтения данных асинхронно:

  • Можно дать другую команду, в то время как запись или читала, функция выполняется.

  • Можно использовать все поддерживаемые свойства коллбэка (см. События и Коллбэки).

Например, потому что последовательные порты имеют отдельное чтение и контакты записи, можно одновременно читать и записать данные. Это проиллюстрировано в следующей схеме.

Запись данных

В этом разделе описываются записывание данные к вашему устройству последовательного порта в трех частях:

Следующая таблица показывает функции, сопоставленные с записыванием данные.

Функции, связанные с Записью данных

FunctionName Описание

fprintf

Запишите текст в устройство

fwrite

Запишите двоичные данные в устройство

stopasync

Остановите асинхронные операции чтения и операции записи

Следующая таблица показывает свойства, сопоставленные с записыванием данные.

Свойства, связанные с Записью данных

PropertyName Описание

BytesToOutput

Количество байтов в настоящее время в буфере вывода

OutputBufferSize

Размер буфера вывода в байтах

Тайм-аут

Время ожидания, чтобы завершить операцию чтения или операцию записи

TransferStatus

Укажите, происходят ли асинхронная операция чтения или операция записи

ValuesSent

Общее количество значений записано в устройство

Буфер вывода и поток данных

Буфер вывода является памятью компьютера, выделенной объектом последовательного порта хранить данные, которые должны быть записаны в устройство. При записывании данные к устройству поток данных выполняет эти два шага:

  1. Данные, заданные функцией записи, отправляются в буфер вывода.

  2. Данные в буфере вывода отправляются в устройство.

OutputBufferSize свойство задает максимальное количество байтов, которые можно сохранить в буфере вывода. BytesToOutput свойство указывает на количество байтов в настоящее время в буфере вывода. Значения по умолчанию для этих свойств:

s = serial('COM1');
get(s,{'OutputBufferSize','BytesToOutput'})
ans = 
    [512]    [0]

При попытке записать больше данных, чем может поместиться в буфер вывода, ошибка возвращена, и никакие данные не записаны.

Например, предположите, что вы пишете команде строки *IDN? к осциллографу TDS 210 с помощью fprintf функция. Как показано в следующей схеме, строка сначала записана в буфер вывода как шесть значений.

*IDN? команда состоит из шести значений, потому что терминатор строки автоматически записан. Кроме того, формат данных по умолчанию для fprintf функция указывает, что одно значение соответствует одному байту. Для получения дополнительной информации о байтах и значениях, смотрите Байты По сравнению со Значениями. fprintf и терминатор строки обсужден в записи текстовых Данных.

Как показано в следующей схеме, после того, как строка записана в буфер вывода, это затем записано в устройство через последовательный порт.

Запись текстовых данных

Вы используете fprintf функционируйте, чтобы записать текстовые данные в устройство. Для многих устройств, пишущий текстовые данные означает писать команды строки, которые изменяют настройки устройства, готовят устройство, чтобы возвратить данные или информацию о статусе и так далее.

Например, Display:Contrast команда изменяет контрастность дисплея осциллографа.

s = serial('COM1');
fopen(s)
fprintf(s,'Display:Contrast 45')

По умолчанию, fprintf записывает данные с помощью %s\n формат, потому что много устройств последовательного порта принимают только основанные на тексте команды. Однако можно задать много других форматов, как описано в fprintf страницы с описанием.

Чтобы проверить количество значений, отправленных в устройство, используйте ValuesSent свойство.

s.ValuesSent
ans =
    20

Обратите внимание на то, что ValuesSent значение свойства включает терминатор строки потому что каждое вхождение \n в команде, отправленной в устройство, заменяется Terminator значение свойства.

s.Terminator
ans =
LF

Значение по умолчанию Terminator символ перевода строки. Терминатор строки, требуемый вашим устройством, будет описан в его документации.

Синхронный по сравнению с асинхронными операциями записи.  По умолчанию, fprintf действует синхронно и блокирует командную строку MATLAB, пока выполнение не завершается. Чтобы записать текстовые данные асинхронно в устройство, необходимо задать async как последний входной параметр к fprintf.

fprintf(s,'Display:Contrast 45','async')

Асинхронные операции не блокируют доступ к командной строке MATLAB. Кроме того, в то время как асинхронная операция записи происходит, вы можете:

  • Выполните асинхронную операцию чтения, потому что последовательные порты имеют отдельные контакты для чтения и записи

  • Используйте все поддерживаемые свойства коллбэка

Чтобы определить, какие асинхронные операции происходят, используйте TransferStatus свойство. Если никакие асинхронные операции не происходят, TransferStatus idle.

s.TransferStatus
ans =
idle

Завершение Операции записи с fprintf.  Синхронная или асинхронная операция записи с помощью fprintf завершается когда:

  • Заданные данные записаны.

  • Время задано Timeout передачи свойства.

Остановите асинхронную операцию записи с stopasync функция.

Правила для записи Терминатора.  Terminator значение свойства заменяет все случаи \n в cmd. Поэтому, когда вы используете формат по умолчанию %s\n, все команды, записанные в устройство, заканчиваются этим значением свойства. Обратитесь к своей документации устройства для терминатора строки, требуемого вашим устройством.

Запись двоичных данных

Вы используете fwrite функционируйте, чтобы записать двоичные данные в устройство. Запись двоичных данных означает писать численные значения. Типовое приложение для записи двоичных данных включает калибровочные данные о записи к инструменту, такому как произвольный генератор формы волны.

Примечание

Некоторые устройства последовательного порта принимают только основанные на тексте команды. Эти команды могут использовать язык SCPI или некоторый другой специфичный для поставщика язык. Поэтому вы можете должны быть использовать fprintf функция для всех операций записи.

По умолчанию, fwrite переводит значения с помощью uchar точность. Однако можно задать много другой точности как описано в страницах с описанием для этой функции.

По умолчанию, fwrite действует синхронно. Чтобы записать двоичные данные асинхронно в устройство, необходимо задать async как последний входной параметр к fwrite. Для получения дополнительной информации о синхронных и асинхронных операциях записи, смотрите текстовые Данные о Записи. Для описания правил, использованных fwrite чтобы завершить операцию записи, обратитесь к ее страницам с описанием.

Распространенные ошибки Поиска и устранения проблем

Используйте эту таблицу, чтобы идентифицировать общий fprintf ошибки.

ОшибкаПроисходит когдаПоиск и устранение проблем

??? Ошибка ==> serial.fwrite в 199 Объектах должна быть соединена с оборудованием с FOPEN.

Вы выполняете операцию записи, и объект последовательного порта не соединяется с устройством.

Используйте fopen установить связь с устройством.

??? Ошибка ==> serial.fwrite в 199 количество записанных байтов должна быть меньше чем или равна OutputBufferSize-BytesToOutput.

Буфер вывода не может содержать все данные, которые будут записаны.

Задайте размер буфера вывода с OutputBufferSize свойство.

??? Ошибка ==> serial.fwrite в 192 FWRITE не может быть названа. Свойство FlowControl установлено в 'оборудование', и контакт Clear to Send (CTS) высок. Это могло указать, что последовательное устройство не может быть включено, не может быть соединено или не использует аппаратное квитирование

  • Вы устанавливаете FlowControl свойство на последовательном объекте к hardware.

  • Устройство или не соединяется или подключенное устройство, не утверждает, что это готово получить данные.

Проверяйте свое состояние удаленного устройства и настройки управления потоками, чтобы видеть, вызывает ли аппаратное управление потоками ошибки MATLAB.

Чтение данных

В этом разделе описываются данные о чтении из вашего устройства последовательного порта в трех частях:

Следующая таблица показывает функции, сопоставленные с чтением данных.

Функции, связанные с чтением данных

FunctionName Описание

fgetl

Прочитайте одну строку текста от устройства и отбросьте терминатор строки

fgets

Прочитайте одну строку текста от устройства и включайте терминатор строки

fread

Считайте двоичные данные из устройства

fscanf

Считайте данные из устройства и отформатируйте как текст

readasync

Считайте данные асинхронно из устройства

stopasync

Остановите асинхронные операции чтения и операции записи

Следующая таблица показывает свойства, сопоставленные с чтением данных.

Свойства, связанные с чтением данных

PropertyName Описание

BytesAvailable

Количество байтов, доступных во входном буфере

InputBufferSize

Размер входного буфера в байтах

ReadAsyncMode

Задайте, является ли асинхронная операция чтения непрерывной или ручной

Тайм-аут

Время ожидания, чтобы завершить операцию чтения или операцию записи

TransferStatus

Укажите, происходят ли асинхронная операция чтения или операция записи

ValuesReceived

Общее количество значений считано из устройства

Входной буфер и поток данных

Входной буфер является памятью компьютера, выделенной объектом последовательного порта хранить данные, которые должны быть считаны из устройства. При чтении данных из устройства поток данных выполняет эти два шага:

  1. Данные, считанные из устройства, хранятся во входном буфере.

  2. Данные во входном буфере возвращены в переменную MATLAB, заданную функцией чтения.

InputBufferSize свойство задает максимальное количество байтов, которые можно сохранить во входном буфере. BytesAvailable свойство указывает на количество байтов, в настоящее время доступных, чтобы быть считанным из входного буфера. Значения по умолчанию для этих свойств:

s = serial('COM1');
get(s,{'InputBufferSize','BytesAvailable'})
ans = 
    [512]    [0]

При попытке считать больше данных, чем может поместиться во входной буфер, ошибка возвращена, и никакие данные не считаны.

Например, предположите, что вы используете fscanf функционируйте, чтобы считать основанный на тексте ответ *IDN? команда ранее записана в осциллограф TDS 210. Как показано в следующей схеме, текстовые данные сначала считаны во входной буфер через последовательный порт.

Обратите внимание на то, что для данной операции чтения, вы не можете знать количество байтов, возвращенных устройством. Поэтому вы можете должны быть задать InputBufferSize свойство к достаточно большому значению прежде, чем соединить объект последовательного порта.

Как показано в следующей схеме, после того, как данные хранятся во входном буфере, это затем передается выходной переменной, заданной fscanf.

Чтение текстовых данных

Вы используете fgetlfgets, и fscanf функции, чтобы считать данные из устройства и отформатировать данные как текст.

Например, предположите, что вы хотите возвратить идентификационную информацию для осциллографа. Это требует записи *IDN? команда к инструменту, и затем читающий назад результат той команды.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)
out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

По умолчанию, fscanf данные о чтениях с помощью %c формат, потому что данные, возвращенные многими устройствами последовательного порта, являются базирующимся текстом. Однако можно задать много других форматов как описано в fscanf страницы с описанием.

Чтобы проверить количество значений, считанных из устройства — включая терминатор строки, используйте ValuesReceived свойство.

s.ValuesReceived
ans =
    56

Синхронный По сравнению с Асинхронными Операциями чтения.  Вы задаете, являются ли операции чтения синхронными или асинхронными с ReadAsyncMode свойство. Можно сконфигурировать ReadAsyncMode к continuous или manual.

Если ReadAsyncMode continuous (значение по умолчанию), объект последовательного порта постоянно запрашивает устройство, чтобы определить, доступны ли данные, чтобы быть считанными. Если данные доступны, они асинхронно хранятся во входном буфере. Чтобы передать данные от входного буфера до MATLAB, используйте один из синхронных (блокирование) функции чтения, такие как fgetl или fscanf. Если данные доступны во входном буфере, эти функции возвращаются быстро.

s.ReadAsyncMode = 'continuous';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    56
out = fscanf(s);

Если ReadAsyncMode manual, объект последовательного порта постоянно не запрашивает устройство, чтобы определить, доступны ли данные, чтобы быть считанными. Чтобы считать данные асинхронно, используйте readasync функция. Затем используйте одну из синхронных функций чтения, чтобы передать данные от входного буфера до MATLAB.

s.ReadAsyncMode = 'manual';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    0
readasync(s)
s.BytesAvailable
ans =
    56
out = fscanf(s);

Асинхронные операции не блокируют доступ к командной строке MATLAB. Кроме того, в то время как асинхронная операция чтения происходит, вы можете:

  • Выполните асинхронную операцию записи, потому что последовательные порты имеют отдельные контакты для чтения и записи

  • Используйте все поддерживаемые свойства коллбэка

Чтобы определить, какие асинхронные операции происходят, используйте TransferStatus свойство. Если никакие асинхронные операции не происходят, то TransferStatus idle.

s.TransferStatus
ans =
idle

Правила для Завершения Операции чтения с fscanf.  Операция чтения с fscanf блокирует доступ к командной строке MATLAB до:

  • Терминатор строки задан Terminator свойство читается.

  • Время задано Timeout передачи свойства.

  • Конкретное количество заданных значений читается.

  • Входной буфер заполнен.

Чтение двоичных данных

Вы используете fread функционируйте, чтобы считать двоичные данные из устройства. Чтение двоичных данных означает, что вы возвращаете численные значения к MATLAB.

Например, предположите, что вы хотите возвратить курсор и настройки отображения для осциллографа. Это требует записи CURSOR? и DISPLAY? команды к инструменту, и затем читающий назад результаты тех команд.

s = serial('COM1');
fopen(s)
fprintf(s,'CURSOR?')
fprintf(s,'DISPLAY?')

Поскольку значение по умолчанию для ReadAsyncMode свойством является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от устройства. Чтобы проверить количество чтения значений, используйте BytesAvailable свойство.

s.BytesAvailable
ans =
    69

Чтобы возвратить данные в MATLAB, используйте любую из синхронных функций чтения. Однако, если вы используете fgetlfgets, или fscanf, необходимо выпустить функцию дважды, потому что существует два терминатора строки, сохраненные во входном буфере. Чтобы возвратить все данные в MATLAB в одном вызове функции, используйте fread.

out = fread(s,69);

По умолчанию, fread возвращает численные значения в массивах двойной точности. Однако можно задать много другой точности как описано в fread страницы с описанием. Чтобы преобразовать числовые данные в текст, используйте char MATLAB функция.

val = char(out)'
val =
HBARS;CH1;SECONDS;-1.0E-3;1.0E-3;VOLTS;-6.56E-1;6.24E-1
YT;DOTS;0;45

Для получения дополнительной информации о синхронных и асинхронных операциях чтения, смотрите текстовые Данные о Чтении. Для описания правил, использованных fread чтобы завершить операцию чтения, обратитесь к ее страницам с описанием.

Пример - пишущие и считывающие текстовые данные

Этот пример иллюстрирует, как связаться с инструментом последовательного порта путем записи и чтения текстовых данных.

Инструмент является Tektronix TDS 210 двухканальный осциллограф, соединенный с портом COM1. Поэтому многие следующие команды характерны для этого инструмента. Синусоида вводится в канал 2 из осциллографа, и ваше задание должно измерить напряжение от пика к пику входного сигнала.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Свяжите с устройством — Подключение s к осциллографу. Поскольку значение по умолчанию для ReadAsyncMode свойством является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  3. Запишите и считайте данные — Запись *IDN? команда к инструменту с помощью fprintf, и затем считайте назад результат команды с помощью fscanf.

    fprintf(s,'*IDN?')
    idn = fscanf(s)
    idn =
    TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

    Необходимо определить источник измерения. Возможные источники измерения включают канал 1 и канал 2 из осциллографа.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH1

    Осциллограф сконфигурирован, чтобы возвратить измерение в канал 1. Поскольку входной сигнал соединяется с каналом 2, необходимо сконфигурировать инструмент, чтобы возвратить измерение в этот канал.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE CH2')
    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH2

    Сконфигурируйте осциллограф, чтобы возвратить напряжение от пика к пику, и затем запросить значение этого измерения.

    fprintf(s,'MEASUREMENT:MEAS1:TYPE PK2PK')
    fprintf(s,'MEASUREMENT:MEAS1:VALUE?')

    Передайте данные от входного буфера до MATLAB с помощью fscanf.

    ptop = fscanf(s,'%g')
    ptop =
    2.0199999809E0
  4. Разъединитесь и вымойтесь — Когда вам больше не будет нужен s отключите его от инструмента и удалите его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Пример - Парсинг Входных данных Используя textscan

Этот пример иллюстрирует, как использовать textscan функционируйте, чтобы проанализировать и отформатировать данные, которые вы считываете из устройства. textscan особенно полезно, когда это необходимо, чтобы проанализировать строку в одну или несколько переменных, где каждая переменная имеет свой собственный заданный формат.

Инструмент является Tektronix TDS 210 двухканальный осциллограф, соединенный с последовательным портом COM1.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Свяжите с устройством — Подключение s к осциллографу. Поскольку значение по умолчанию для ReadAsyncMode свойством является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  3. Запишите и считайте данные — Запись RS232? команда к инструменту с помощью fprintf, и затем считайте назад результат команды с помощью fscanf. RS232? запрашивает настройки RS-232 и возвращает скорость в бодах, установку программного управления потоком, установку аппаратного управления потоками, тип контроля четности и терминатор строки.

    fprintf(s,'RS232?')
    data = fscanf(s)
    data =
    9600;0;0;NONE;LF

    Используйте textscan функционируйте, чтобы проанализировать и отформатировать data переменная в пять новых переменных.

    C = textscan(a, '%d%d%d%s%s','delimiter',';'); 
    
    [br, sfc, hfc, par, tm] = deal(C{:});
    
    br =
            9600
    sfc =
         0
    hfc =
         0
    par = 
        'NONE'
    tm = 
        'LF'
  4. Разъединитесь и вымойтесь — Когда вам больше не будет нужен s, необходимо отключить его от инструмента и удалить его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Пример - считывающий двоичные данные

В этом примере показано, как вы, чтобы загрузить отображение на экране осциллографа TDS 210 на MATLAB. Данные об отображении на экране передаются и сохранили использование на диск растрового формата Windows. Эти данные обеспечивают постоянную запись вашей работы и являются простым способом зарегистрировать важный сигнал и параметры осциллографа.

Поскольку переданный объем данных, как ожидают, будет довольно большим, он асинхронно возвращен во входной буфер, как только это доступно от инструмента. Это позволяет вам выполнять другие задачи, в то время как передача прогрессирует. Кроме того, осциллограф сконфигурирован к его самой высокой скорости в бодах 19 200.

  1. Создайте объект последовательного порта — Создают объект последовательного порта s сопоставленный с последовательным портом COM1.

    s = serial('COM1');
  2. Сконфигурируйте значения свойств — Конфигурируют входной буфер, чтобы принять довольно большое количество байтов и сконфигурировать скорость в бодах к самому высокому значению, поддержанному осциллографом.

    s.InputBufferSize = 50000;
    s.BaudRate = 19200;
  3. Свяжите с устройством — Подключение s к осциллографу. Поскольку значение по умолчанию для ReadAsyncMode свойством является continuous, данные асинхронно возвращены во входной буфер, как только это доступно от инструмента.

    fopen(s)
  4. Запишите и считайте данные — Конфигурируют осциллограф, чтобы передать отображение на экране как битовый массив.

    fprintf(s,'HARDCOPY:PORT RS232')
    fprintf(s,'HARDCOPY:FORMAT BMP')
    fprintf(s,'HARDCOPY START')

    Ожидайте, пока все данные не отправляются во входной буфер, и затем передайте данные рабочему пространству MATLAB как 8-битные целые числа без знака.

    out = fread(s,s.BytesAvailable,'uint8');
  5. Разъединитесь и вымойтесь — Когда вам больше не будет нужен s, отключите его от инструмента и удалите его из памяти и из рабочего пространства MATLAB.

    fclose(s)
    delete(s)
    clear s

Просмотр растровых данных

Чтобы просмотреть растровые данные, выполните эти шаги:

  1. Откройте дисковый файл.

  2. Запишите данные в дисковый файл.

  3. Закройте дисковый файл.

  4. Считайте данные в MATLAB с помощью imread функция.

  5. Масштабируйте и отобразите данные с помощью imagesc функция.

Обратите внимание на то, что версии файлового ввода-вывода fopenfwrite, и fclose функции используются.

fid = fopen('test1.bmp','w');
fwrite(fid,out,'uint8');
fclose(fid)
a = imread('test1.bmp','bmp');
imagesc(a)

Поскольку осциллограф возвращает данные об отображении на экране с помощью только двух цветов, соответствующая палитра выбрана.

mymap = [0 0 0; 1 1 1];
colormap(mymap)

Следующая схема показывает изображение полученного растрового изображения.