Работаем с labview на примере stm32

Работаем с labview на примере stm32

Сообщение Rogers » 16 окт 2014, 15:02

#include “stm32f4xx.h”
#include “stm32f4xx_gpio.h”
#include “stm32f4xx_rcc.h”
#include “stm32f4xx_usart.h”

char uart2_rx_buf[128];
uint8_t uart2_rx_bit;

void send_to_uart(uint8_t data)
<
while(!(USART2->SR & USART_SR_TC));
USART2->DR=data;
>

//
void send_str(char * string)
<
uint8_t i=0;
while(string[i])
<
send_to_uart(string[i]);
i++;
>
>

//USART2
void usart_init(void)
<
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); //PA3 k TX USART2
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // PA2 k RX USART2

//TX UART
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// RX UART
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);

int my_atoi(char a[]) <
int c, sign, offset, n;

for (c = offset; a[c] != ‘’; c++) <
n = n * 10 + a[c] – ‘0’;
>

return n;
>
typedef enum <
TM_DAC1,
TM_DAC2
> TM_DAC_Channel_t;

/**
* Initialize DAC channel and it’s pin
*
* – Parameters:
* – TM_DAC_Channel_t DACx:
* – TM_DAC1, TM_DAC2
*/
extern void TM_DAC_Init(TM_DAC_Channel_t DACx);

/**
* Set analog value to ADCx
*
* – Parameters:
* – TM_DAC_Channel_t DACx:
* – TM_DAC1, TM_DAC2
* – uint16_t value
* 12Bit unsigned value for 12bit DAC value
*/
extern void TM_DAC_SetValue(TM_DAC_Channel_t DACx, uint16_t value);

void TM_DAC_Init(TM_DAC_Channel_t DACx) <
GPIO_InitTypeDef GPIO_InitDef;
DAC_InitTypeDef DAC_InitDef;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

if (DACx == TM_DAC1) <
GPIO_InitDef.GPIO_Pin = GPIO_Pin_4;
> else <
GPIO_InitDef.GPIO_Pin = GPIO_Pin_5;
>
GPIO_InitDef.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitDef.GPIO_Speed = GPIO_Speed_2MHz;

DAC_InitDef.DAC_Trigger = DAC_Trigger_None;
DAC_InitDef.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitDef.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
if (DACx == TM_DAC1) <
DAC_Init(DAC_Channel_1, &DAC_InitDef);
DAC_Cmd(DAC_Channel_1, ENABLE);
> else <
DAC_Init(DAC_Channel_2, &DAC_InitDef);
DAC_Cmd(DAC_Channel_2, ENABLE);
>
>

void TM_DAC_SetValue(TM_DAC_Channel_t DACx, uint16_t value) <
if (value > 4095) <
value = 4095;
>
if (DACx == TM_DAC1) <
DAC_SetChannel1Data(DAC_Align_12b_R, value);
> else <
DAC_SetChannel2Data(DAC_Align_12b_R, value);
>

int main(void)
<
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOD, &GPIO_InitStructure);

__enable_irq();
NVIC_EnableIRQ(USART2_IRQn);
NVIC_SetPriority(USART2_IRQn, 0);
USART2->CR1 |= USART_CR1_RXNEIE;

void USART2_IRQHandler (void)
<
int device_num = 0;
//char digits[8] = “700”;
char uart_data;
if (USART2->SR & USART_SR_RXNE)
<
USART2->DR = USART2->DR;
uart_data=USART2->DR;

device_num = my_atoi(uart2_rx_buf);
// device_num = my_atoi(digits);

uart2_rx_buf[uart2_rx_bit]=USART2->DR;
uart2_rx_bit++;
USART2->DR=device_num;
SystemInit();

//Initialize DAC channel 1, pin PA4
TM_DAC_Init(TM_DAC1);
//Set 12bit analog value of 600/4096 * 3.3V
TM_DAC_SetValue(TM_DAC1, device_num);

Digitrode

цифровая электроника вычислительная техника встраиваемые системы

Как работать в LabVIEW: пример управления светодиодом по кнопке

Что такое LabVIEW?

LabVIEW является аббревиатурой от Laboratory Virtual Instrumentation Engineering Workbench (рабочее место виртуальной лаборатории для инженеров). Внешний вид и операции элементов LabVIEW напоминают приборы реального мира, такие как кнопки, вольтметры, осциллографы и т. д. и, следовательно, они называются виртуальными инструментами (VI). LabVIEW предлагает подход графического программирования и помогает моделировать устройства реального мира.

Таким образом, для программирования требуется только логика, а сам процесс не зависит от синтаксиса. LabVIEW – инструмент проектирования высокого уровня. Это программирование с интерпретацией, то есть нам не нужно ничего компилировать. После подготовки проекта нужно будет только запустить его.

Чем LabVIEW отличается от других программ проектирования и моделирования схем?

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

Методы программирования могут быть двух типов. Они основаны на текстовом и графическом программировании. C, C ++, Java и т. д. (все текстовые языки программирования) относятся к текстовому программированию (MATLAB – язык промежуточного уровня), тогда как LabVIEW – язык программирования на графической основе.

Почему стоит отдать предпочтение LabVIEW?

Тот, кто не имеет никаких базовых знаний о программировании, может использовать LabVIEW. Чтобы заниматься программированием на LabVIEW, нужно обладать практическими знаниями и умением логического мышления. Программисту LabVIEW не нужно знать какой-либо синтаксис программирования или какую-либо структуру программирования, такую как языки программирования C, C ++, Java.

Можно использовать LabVIEW, когда программа слишком велика. Здесь так же просто подключить аппаратные компоненты для вашего проекта. На рисунке ниже показана разница между текстовым и графическим программированием. С левой стороны есть программа Arduino, которая мигает светодиодом с задержкой в 1 секунду, а с правой стороны ее графическая копия была сделана с использованием программного обеспечения LabVIEW. Всякий раз, когда вы нажимаете кнопку ОК, светодиод будет мигать с задержкой в 1 секунду.

Запуск LabVIEW

Сначала загрузите программное обеспечение LabVIEW от National Instruments (http://www.ni.com/ru-ru/shop/labview.html). После запуска этого программного обеспечения открывается окно Getting Started (Начало работы).

Нажмите Ctrl + N, чтобы открыть новый проект. Открыв новый проект, вы увидите лицевую панель и окно блок-схем.

Окно Getting Started исчезает, когда вы открываете новый или существующий проект. Оно появляется снова, когда вы закрываете все лицевые панели и блок-схемы. Вы также можете открыть это окно с лицевой панели или блок-схемы, выбрав View – Getting Started. Нажмите Ctrl + T, чтобы расположить лицевую панель и окно блок-схем рядом, как это показано ниже.

В LabVIEW вы будете создавать пользовательский интерфейс, то есть лицевую панель, с элементами управления и индикаторами. Элементы управления – это не что иное, как вводимые вами данные, такие как ручки, переключатели и т. д. Индикаторы – это не что иное, как создаваемые вами выходы, такие как светодиоды, графики и т. д. Сейчас объясним все на примере, чтобы вы поняли лучше.

Типы данных в LabVIEW

Типы данных – классификация переменных. Ниже приведены типы данных, используемые в LabVIEW, и их цветовое соответствие в окне блок-схем.

  • Floating point (с плавающей запятой) – оранжевый
  • Integer (целые) – синий
  • Boolean (булевы) – зеленый
  • String (строка) – розовый
  • Polymorphic (полиморфные) – черный

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

Пример LabVIEW: включение светодиода при нажатии кнопки

Для начала осуществим добавление элементов управления на лицевую панель. Элементы управления на лицевой панели имитируют механизм ввода на физическом инструменте и подают данные на блок-схему виртуальных инструментов (программы LabVIEW называются VI или Virtual Instruments). Выберите View – Controls Palette (Вид – Палитра элементов управления), чтобы палитра элементов управления или функций постоянно находилась на экране, или щелкните правой кнопкой мыши любое пустое место на лицевой панели или окно блок-схемы, чтобы временно отобразить ее.

Наведите курсор на значки в палитре Modern, чтобы найти нужные элементы управления (Boolean Controls Palette или палитра логических элементов управления). Щелкните на значок Boolean controls, чтобы отобразить палитру логических элементов управления. Щелкните на button control на палитре логических элементов управления Boolean controls, чтобы прикрепить элемент управления, а затем добавьте кнопку на лицевую панель.

Вы будете использовать эту кнопку управления светодиодом.

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

Чтобы запустить виртуальный инструмент, выберете Select Operate – Run/Run Continuously. Или вы можете использовать значки, которые отображены на рисунке выше. Чтобы остановить выполнение, снова нажмите значок run continuously. Во время работы программы светодиод будет светиться при нажатии на кнопку. Если кнопка запуска не работает, значит, в программе LabVIEW произошла ошибка. Чтобы узнать, что это за ошибка, нажмите эту кнопку запуска, вы увидите диалоговое окно с описанием ошибки.

Примеры работ на LabView

Решил создать тему и в ней разместить примеры работ на LabView, которые демонстрируют основные возможности данной среды. Часть этих работ были выполнены мной в период обучения в ВУЗе как лабораторные и курсовые работы.

1. Измерение температуры

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

Лицевая панель виртуального инструмента (VI):

Следует отметить, что изображенный на диаграмме в качестве источника блок “AS Temp” является другим виртуальным инструментом, вставленным в данный уже в качестве модуля.
Лицевая панель и диаграмма модуля “AS Temp” (в архиве с исходниками файл Digital Thermometr.vi):

Читайте также:  Проводка для электроплиты и духового шкафа

Также отмечу, что в учебных целях данные для получения значений температуры берутся не с физического источника (измерительного преобразователя), а по сути, с генератора случайных чисел (встроенного в среду LabView виртуального инструмента DemoVoltageRead.vi).

2. Симуляция логических операций

В данном примере показывается выполнение различных логических операций (AND, OR, NOT, NOT-OR, NOT-AND, XOR, NOT-XOR) над логическими и числовыми операндами. При работе с числовыми – результат выводится в знаковом и беззнаковом представлении в различных системах счисления. Так же рассмотрена операция сдвига.
Лицевая панель:

12.03.2014, 11:40

Есть примеры работ с Local Variable?
Хотелось бы изучить подробнее, но в интернете в основном информация в текстовом виде, а разобраться.

Примеры работ по функциям ПОИСКПОЗ и ИНДЕКС
Вот на этой теме вставляйте свои файлы с примерами по функциям ПОИСКПОЗ и ИНДЕКС

Какие есть примеры работ по предмету “Исследование операций”
Можете подсказать примеры тем, которые не очень сложно реализовать в виде проекта или где можно.

LabView
Hi Ott! Собственно,кто нибудь использует?

24.07.2014, 17:14 [ТС]2

3. Организация примитивной передачи данных по компьютерной сети

Виртуальный инструмент №1 (далее – передатчик (во вложении файл AS_SENDER.VI)) осуществляет передачу заданного пользователем числа по указанному адресу в сети с указанного порта по протоколу UDP. Передача осуществляется непрерывно с периодом устанавливаемым пользователем.

Виртуальный инструмент №2 (далее – приемник (во вложении файл AS_RESEIVER.VI)) должен получать в непрерывном режиме данные с определенного UDP порта, на который отправляет данные передатчик.

Приемник отображает полученные данные (числовое значение) на графике, а также:
• сетевой адрес отправителя;
• UDP порт отправителя;
• количество циклов получения данных.

Лицевая панель серверной части (передатчика):

Ниже перечислены визуальные компоненты лицевой панели и их функции:
Start (Vertical Switch) – Запуск и остановка работы передатчика
Receiver IP (String Control) – Позволяет задать IP-адрес получателя (приемника)
Port (Digital Control) – Позволяет задать порт
Sending Number (Knob) – Позволяет задать передаваемое число
Cycle Time (Knob) – Позволяет изменять скорость циклической передачи данных

Лицевая панель клиентской части (приемника):

Ниже перечислены визуальные компоненты лицевой панели и их функции:
Start (Vertical Switch) – Запуск и остановка работы приемника
Sender IP (String Indicator) – Отображает IP-адрес отправителя (передатчика)
Sender Port (Digital Indicator) – Отображает порт отправителя
Number of Cycles (Digital Indicator) – Отображает число циклов приема данных
Received Data (Waveform Chart) – Отображает на графике полученное с передатчика число.

Диаграмма функционирования передатчика:

На данной схеме присутствуют следующие элементы:
Цикл While Loop – Позволяет организовать циклическую передачу данных
Элемент UDP Open – Инициализирует работу протокола UDP
Элемент UDP Write – Передает данные по UDP протоколу
Элемент UDP Close – Завершает передачу данных, используя UDP протокол
Элемент To Decimal – Преобразует число на входе в строку с десятичными символами
Элемент String To IP – Преобразует строку в IP-адрес

Диаграмма функционирования приемника:

На данной схеме присутствуют следующие элементы:
Цикл While Loop – Позволяет организовать циклический прием данных
Элемент UDP Open – Инициализирует работу протокола UDP
Элемент UDP Read – Используется для получения данных по протоколу UDP
Элемент UDP Close – Завершает передачу данных, используя UDP протокол
Элемент IP To String – Преобразует IP-адрес в строку
Элемент From Decimal – Преобразует строку десятичных символов в строку

Работаем с labview на примере stm32







Техническая информация.

STM32 hardware .
STM32 software .
LabVIEW.
MAX11210.
MAX 607 0.
BreadBoards.

STM32 hardware .

Переход на новую серию микроконтроллеров – STM32F103 .

Конкретный микроконтроллер – STM32F103TBU6 .

STMпроизводитель ST Microelectronics .

03микроконтроллер с конкретным набором периферии, частота до 72 МГц .

Внешний вид и назначение выводов сборки:

STM32 software .

Прошивка загрузчика в микроконтроллер:

    Используем USB to Serial адаптер:
    3 V 3 ( Red ) – 3 V 3 ,
    GND ( Brown ) – GND ,
    RXD ( Orange ) – PA9 ,
    TXD ( Yellow ) – PA10 .

    Переводим микроконтроллер в режим программирования.

    Вводим команду s tm32flash.exe -w generic_boot20_pa1.bin COM XX
    (s tm32flash.exe -w generic_boot20_ hytiny .bin COM XX new revision)
    .

    LabVIEW .

    Минимальная среда разработки – LabVIEW 5.0 .
    + полностью переносимая версия.
    + крайне малые размеры.
    + высочайшая скорость реакции интерфейса.
    + полная работоспособность вплоть до Windows 10 .
    — слабый функционал.
    — отсутствие автовыбора инструментов.
    — ограниченный набор визуального оформления.

    Lvserial – интерфейс между LabVIEW и последовательным портом (автор Martin Henz ) .
    Не нужно устанавливать никакие драйверы (например, NI-VISA ), достаточно одной библиотеки lvserial.dll и стандартного набора виртуальных инструментов для работы с последовательным портом.
    Виртуальные инструменты (ВИ) создавались в LabVIEW 6.1 , версии для LabVIEW 5.0 у автора нет (ответ автора от 15.10.2015: ” No sorry. The oldest avialable lvserial is for LabVIEW 6.1″ ).
    В связи с этим основные ВИ ( “Open”, “Read”, “Write”, “TermChar” ) были переписаны для LabVIEW 5.0 и полностью функциональны.

    В 2015 году компания National Instruments создала новую лицензию для своего программного продукта LabVIEW – Home Bundle.
    Это полнофункциональная версия LabVIEW 2014 для личного некоммерческого использования. Теперь каждый желающий может купить сертификат с серийным номером на лицензионную некоммерческую версию LabVIEW в российском представительстве National Instruments за 75 $ .
    После этого нужно загрузить и активировать программу – и Вы приобретете мощный инструмент для анализа и управления всеми этапами физического эксперимента.

    Интерфейс между MAX11210 и LabVIEW 5.0 .

    Интерфейс между 24-битным АЦП MAX11210 , STM32F103TBU6 и LabVIEW 5.0 .

    MAX11210 .

    MAX11210 – 24-битный одноканальный АЦП с последовательным выходом и низкой потребляемой мощностью. Данное устройство оптимизировано для приложений, требующих широкого динамического диапазона при низкой потребляемой мощности, к которым относятся, например, датчики с рабочим током от 4мА до 20мА для промышленных систем контроля. Дополнительные входные буферы обеспечивают изоляцию входных сигналов от изменяющейся емкости переключающегося тракта преобразования, что дает возможность использовать этот АЦП вместе с высокоимпедансными источниками без ущерба для характеристик динамического диапазона и линейности. Данное устройство имеет встроенный высокоточный генератор, который не требует использования внешних компонентов. При работе на стандартных скоростях встроенный цифровой фильтр обеспечивает подавление более чем на 144dB шумов 50Гц и 60Гц. Управление устройством осуществляется через интерфейс SPI и включает также управление четырьмя входами-выходами общего назначения, предназначенными для подключения внешних схем коммутации.
    MAX11210 имеет программируемый усилитель с коэффициентами усиления 1, 2, 4, 8, или 16.
    MAX11210 выпускается в 16-выводном корпусе QSOP и работает в расширенном температурном диапазоне от -40°С до +85°С.

    24.0-Bit ENOB at 5sps
    20.9-Bit Noise-Free Resolution at 10sps
    19-Bit Noise-Free Resolution at 120sps
    570nVRMS Noise at 10sps, ± 3.6VFS Input
    1ppm INL (typ), 10ppm (max)
    No Missing Codes
    Ultra-Low Power Dissipation
    Operating-Mode Current Drain Sleep-Mode Current Drain Control
    2.7V to 3.6V Analog Supply Voltage Range
    1.7V to 3.6V Digital and I/O Supply Voltage Range
    Fully Differential Signal and Reference Inputs
    High-Impedance Inputs
    Optional Input Buffers on Both Signal and Reference Inputs
    Programmable Internal Clock or External Clock Mode
    > 100dB (min) 50Hz/60Hz Rejection
    SPI, QSPI™, MICROWIRE™-Compatible Serial Interface
    On-Demand Offset and Gain Self-Calibration and System Calibration
    User-Programmable Offset and Gain Registers
    -40°C to +85°C Operating Temperature Range
    ± 2kV ESD Protection
    Lead(Pb)-Free and RoHS-Compliant QSOP Package .

    MAX6070 .

    Что самое важное в аналого-цифровом преобразователе (АЦП)? В дополнении к высокому разрешению, существенной частью измерительной схемы является высококачественный источник опорного напряжения (ИОН).

    MAX6070A – прецизионный ИОН с низким уровнем шума.

    High ± 0.04% Initial Accuracy
    Low 1.5ppm/°C (typ) Temperature Drift
    Low 4.8μVP-P Noise (0.1Hz to 10Hz) at 2.5V
    Low 150μA Supply Current
    10mA Source/Sink Load Current
    Noise Filter Option
    Low 200mV Dropout Voltage
    High 85dB Ripple Rejection
    Small 6-Pin SOT23 Package
    Voltage Output Options: 1.25V, 1.8V, 2.048V, 2.5V, 3.0V, 3.3V, 4.096V, and 5.0V .

    MAX6070AAUT12 1.25V ACPF красные контакты.
    MAX6070AAUT25 2.5V ACPL желтые контакты.
    MAX6070AAUT30 3.0V ACPN черные контакты.
    MAX6070AAUT41 4.096V ACPR синие контакты.

    BreadBoards .

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

    В настоящее время лучшими из тестированных беспаечных макетных плат являются изделия фирмы WISHER ENTERPRISE .

    Основание: алюминиевая пластина толщиной 1,2 мм .
    Материал плат: ABS-пластик.
    Материал разъемов: фосфористая бронза с покрытием никелем.
    Толщина подключаемых проводников: 0,3-0,7 мм.
    Расстояние между отверстиями: 2,54 мм.
    Количество циклов подключения/отключения: 10 тысяч.
    Максимальные напряжение и ток: 48 В, 5 А.

    ADC Accuracy on STM32F1 Board .

    The value you see depends on:
    1. on the voltage at your voltage regulator (it serves as the adc reference voltage)
    2. on the formula you use for the conversion of adc output to float
    3. on the error of the adc converter (see datasheet)
    4. on the adc clock frequency
    5. on the impedance of the voltage source
    6. on the temperature
    7. on the level of noise.

    Читайте также:  Где находится проводка в панельных домах?

    Стенд для измерения магнитного поля – 2017.

    Сейчас мы расскажем Вам, как самостоятельно создать стенд для измерения магнитного поля с минимальными затратами труда и денег.

    Прошивка загрузчика в микроконтроллер:

      Используем USB to Serial адаптер:
      3 V 3 ( Red ) – 3 V 3 ,
      GND ( Brown ) – GND ,
      RXD ( Orange ) – PA9 ,
      TXD ( Yellow ) – PA10 .

      Переводим микроконтроллер в режим программирования.

      STM Урок 9. HAL. Шина I2C. Продолжаем работу с DS3231

      Урок 9

      HAL. Шина I2C. Продолжаем работу с DS3231

      На прошлом занятии мы как следует ознакомились с шиной I2C, а также с микросхемой часов реального времени DS3231, создали и настроили проект в Cube MX и Keil.

      На данном занятии мы продолжим работать с тем же проектом и уже займёмся непосредственно кодом.

      В файл main.h мы также добавим переменную для данных

      В неё мы будем принимать значения сразу всех 7 регистров микросхемы и, предварительно заполнив в ней все ячейки, туда же и отправлять, когда будем устанавливать время в часах.

      Екстерналим ее в i2c.c, также напишем там переменную для строки и напишем там две функции для работы с шиной.

      extern uint8_t aTxBuffer[8];

      void I2C_WriteBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf)

      while(HAL_I2C_Master_Transmit(&hi, (uint16_t)DEV_ADDR,(uint8_t*) &aTxBuffer, (uint16_t)sizebuf, (uint32_t)1000)!= HAL_OK)

      if (HAL_I2C_GetError(&hi) != HAL_I2C_ERROR_AF)

      sprintf(str, “Buffer error”);

      void I2C_ReadBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf)

      while(HAL_I2C_Master_Receive(&hi, (uint16_t)DEV_ADDR, (uint8_t*) &aTxBuffer, (uint16_t)sizebuf, (uint32_t)1000)!= HAL_OK)

      if (HAL_I2C_GetError(&hi) != HAL_I2C_ERROR_AF)

      sprintf(str, “Buffer error”);

      Первая функция будет для передачи данных в шину, а вторая – для приема.

      Входные параметры в первой функции:

      I2C_HandleTypeDef hi – идентификатор шины I2C.

      DEV_ADDR – адрес устройства

      sizebuf – количество байт, которые мы будем передавать.

      Дальше идёт цикл, из которого мы выйдем тогда, когда данные передадутся и мы получим статус HAL_OK.

      Статус нам уже будет возвращать стандартная функция передачи данных в I2C из библиотеки HAL HAL_I2C_Master_Transmit. В данную функцию мы передаём практически те же параметры, некоторые из них только явно преобразованы несколько в другой тип, а также передаём таймаут в милисекундах. Это не значит, что функция будет именно столько времени выполняться. При успешном выполнении мы будем из функции возвращаться мгновенно. А вот если что-то пойдёт не так, то будем ждать именно столько времени, а затем всё равно выйдем, правда с ошибкой.

      Затем мы проверяем передачу на ошибку, и в случае, если она будет, то выведем текст ошибки на дисплей.

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

      Тело функции также аналогично телу предыдущей функции, только библиотечная фунция там уже применена HAL_I2C_Master_Receive.

      Создадим для этих двух функций прототипы в файле i2c.h

      void I2C_WriteBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf);
      void I2C_ReadBuffer(I2C_HandleTypeDef hi, uint8_t DEV_ADDR, uint8_t sizebuf);

      Убираем весь код по дисплею кроме инициализации из главной функции.

      Начинаем работать с шиной в главной функции main()

      Сначала удалим код вывода тестовых строк на экран дисплея. Оставим только вот это

      /* USER CODE BEGIN 2 */
      LCD_ini();
      LCD_Clear();

      /* USER CODE END 2 */

      Дальше уже начнем работать с функциями.

      Пишем код в бесконечный цикл

      while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)

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

      Далее мы передадим адрес устройства и адрес первого регистра микросхемы.

      Пишем дальше в бесконечный цикл

      while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)

      А затем мы уже считаем все 7 регистров в буфер из RTC

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

      uint8_t RTC_ConvertFromDec(uint8_t c)

      uint8_t ch = ((c>>4)*10+(0x0F&c));

      uint8_t RTC_ConvertFromBinDec(uint8_t c)

      uint8_t ch = ((c/10)

      Также пропишем им прототипы в одноименном хедере.

      uint8_t RTC_ConvertFromDec(uint8_t c); //перевод двоично-десятичного числа в десятичное

      uint8_t RTC_ConvertFromBinDec(uint8_t c); //перевод десятичного числа в двоично-десятичное

      /* USER CODE BEGIN 1 */

      /* USER CODE END 1 */

      date = RTC_ConvertFromDec(date); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((date/10)%10) + 0x30);

      LCD_SendChar((char) (date%10) + 0x30);

      month = RTC_ConvertFromDec(month); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((month/10)%10) + 0x30);

      LCD_SendChar((char) (month%10) + 0x30);

      year = RTC_ConvertFromDec(year); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((year/10)%10) + 0x30);

      LCD_SendChar((char) (year%10) + 0x30);

      day = RTC_ConvertFromDec(day); //Преобразуем в десятичный формат

      LCD_SendChar((char) (day%10) + 0x30);

      hour = RTC_ConvertFromDec(hour); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((hour/10)%10) + 0x30);

      LCD_SendChar((char) (hour%10) + 0x30);

      min = RTC_ConvertFromDec(min); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((min/10)%10) + 0x30);

      LCD_SendChar((char) (min%10) + 0x30);

      sec = RTC_ConvertFromDec(sec); //Преобразуем в десятичный формат

      LCD_SendChar((char) ((sec/10)%10) + 0x30);

      LCD_SendChar((char) (sec%10) + 0x30);

      LCD_SendChar((char) ((i/100)%10) + 0x30);

      LCD_SendChar((char) ((i/10)%10) + 0x30);

      LCD_SendChar((char) (i%10) + 0x30);

      LCD_SendChar((char) (((i+500)/100)%10) + 0x30);

      LCD_SendChar((char) (((i+500)/10)%10) + 0x30);

      LCD_SendChar((char) ((i+500)%10) + 0x30);

      LCD_SendChar((char) (((i+750)/100)%10) + 0x30);

      LCD_SendChar((char) (((i+750)/10)%10) + 0x30);

      LCD_SendChar((char) ((i+750)%10) + 0x30);

      /* USER CODE END WHILE */

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

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

      Соберём код и прошьём контроллер. Посмотрим, как у нас всё это работает.

      Отладочную плату, дисплей LCD 20×4 и модуль RTC DS3231 с микросхемой памяти можно приобрести здесь:

      USB H > Пост опубликован в блогах iXBT.com, его автор не имеет отношения к редакции iXBT.com (подробнее »)

      Ряд микроконтроллеров STM32 имеют на борту USB интерфейс для связи с компьютерами. Как правило, удобнее всего использовать предоставляемый компаний ST Microelectronics драйвер класса CDC (Communication Device Class ). Он позволяет использовать на стороне компьютера UART через USB и не требует установки драйверов. Со стороны STM32 при этом требуется только поменять операции вывода данных, остальное делается самостоятельно. Причём скорость такого соединения может быть практически любой, поддерживаемой компьютером.

      Однако ряд разработок, особенно, когда приходишь в другую компанию, где используется HID Class (Human Interface Device), в случае разработки новой версии устройства требуется поддерживать ранее выбранный интерфейс. Что, собственно, и случилось. Примеры проектов от самой ST, которые они дают при загрузке STM32 Cube MX и IDE, как обычно, дали только минимальное понимание, но не раскрыли, что и как надо делать. Я когда-то разбирался с USB, даже писал собственный драйвер, но это было так давно… Остались только общие воспоминания. Посему пришлось искать дополнительную информацию, чтобы получить стартовую точку.

      Первое найденное было видеороликом на youtube в стиле HID за 5 минут 🙂 Автор даёт доступ к своему коду на GitHub. Всё, типа круто, красиво, просто вставляйте к себе и всё будет чудесно. Судя по отзывам под роликом, некоторым этого хватило. Изучив исходники понял, что минимального прозрения не наступило, да и уровень полученной информации мал для того, чтобы решить поставленную задачу. Но закомство с этим материалом было явно полезным. Решение вопроса с использованием кубика (STM32Cube MX) мне лично импонирует больше, чем другие подходы, поскольку позволяет отвлечься от ряда низкоуровневых операций и генерация проекта всегда происходит в одном стиле. Соответственно, изучение этого примера показало, на какие файлы надо обратить внимание, где и что надо поменять или добавить, какие функции использовать для получения и отправки данных именно для нашей выбранной среды программирования.

      Следующий поиск оказался весьма удачным. Хабр — известный сайт, на котором можно найти много полезного по разной электронной тематике. Нашлась там и статья STM32 и USB-HID — это просто. Я не являюсь постоянным клиентом Хабра и не знаю автора этой статьи RaJa, но на мой взгляд это очень хорошая статья, описывающая основные положения работы HID интерфейся. Без её прочтения читать дальше здесь бессмысленно, поскольку далее будут, в основном, комментарии для адаптации кода к среде разработки STM32IDE/STM32CubeMX + Atollic TrueStudio. (Далее STM32IDE). Да и столь популярный в 2014 году и реально очень неплохой проект EmBlocks, увы, умер.

      Первое, что необходимо решить — как тестировать вновь создаваемое устройство. Лет… дцать назад я использовал для этого анализатор и синтезатор трафика USB — очень полезные, но дорогие игрушки 🙂 Сейчас у меня такой возможности нет, да и должен же быть более простой путь. Тем более для простого стандартного интерфейса без написания собственного драйвера. Авторы обоих рассмотренных выше проектов пошли самы простым для них путём — написание простой программы на известных им языках. Но автор статьи на Хабре сделал очень правильный шаг — он написал свой проект, совместимый с программой ST HID Demonstrator (ссылка есть в статье), позволяющей поуправлять нашим устройством, как графически, так и послать свои данные и посмотреть, что пришло от нашего устройства. Фактически программа может использоваться и в дальнейшем для отладки будущей программы на выбранном микроконтроллере.

      Читайте также:  Как правильно провести проводку в частном доме?

      Своё ознакомление с проектом для HID я осуществлял с платой STM32L476 Discovery. Плата, вообще говоря, может быть любой, где USB интерфейс микроконтроллера физически подключён к отдельному разъёму USB. Есть у меня и Nucleo 32 с STM32L4, но там один разъём USB тспользуется и для программирования/отладки, и для связи с хостом, что добавляет интриги в интерфейс и может служить источником дополнительных непоняток. Оно нам надо?

      Итак, комментарии и дополнения к статье по привязке HID к STM32IDE примерно по тем же шагам, как и в хабровской статье.

      Структура проекта

      В STM32IDE структура всех проектов задаётся при генерации проекта из среды назначения функциональности пинов и пользователю о том заботиться не надо. В частности, в кубике (что отдельном STM32Cube MX, что в встроенном в STM32IDE) активируем USB, как Device, и добавляем Middleware USB Custom HID.

      Рис.1 Выбор USB интерфейса Рис.2 Выбор и первичная настройка Middleware Надо заметить, что несмотря на установку размера буфера в 64 байта, эта величина не вносится по #define. Видимо баг текущей версии кубика. Далее покажем, где надо пофиксить. Указанный резмер дескриптора равный 79 — это значение для данного конретного стартового проекта

      Заходим в Clock Configuration. Вполне вероятно, что могут быть проблемы с системными частотами, которые маркируются малиновым цветом.

      Рис. 3 Возможные проблемы по установке частот

      Если так, нажимаем Resolve Clock Issues и, скорее всего, всё будет настроено на максимальные частоты. Главное — USB Clock будет выставлен на 48 МГц. Надо заметить, что в семействе STM32L4 генератор на 48МГц имеет автоподстройку по SOF (Start Of Frame), что позволяет создавать USB устройства без внешнего кварца/генератора. Если, конечно, остальной дизайн допускает использование некварцованных генераторов. Для других семейств не проверял, поскольку для моего текущего проекта был выбран именно L4. Только надо отметить, что при использовании USB есть некоторая минимальная частота работы микроконтроллера. Я делал прикидку для другого проекта, где надо общаться с хостом и при этом потреблять минимум тока. Задачи простые, не требуют большой скорости и я хотел запустить МК на 8МГц. Оказалось, что меньше 14МГц при подключении USB ставить не могу, RCC не позволяет. Пришлось остановиться на следующем круглом значении 16МГц.

      Собственно, настройка аппаратной части USB и выбор файлов, отвечающих за базовую функциональность этого интерфейса на на этом закончены. Вся остальная периферия, находящаяся на выбранной плате настраивается автоматически при её выборе на старте проекта. Сохраняем, генерим проект и переходим к «программированию» в сравнении с описанным на Хабре проектом.

      Это страшное слово Descriptor

      Стандартные массивы данных для передачи информации хосту, с чем он будет иметь дело. Для интереса можно посмотреть дескрипторы устройства и конфигурации. Сейчас их можно оставить такими, как получились, но в дальнейшем они наверняка потребуют редактирования. Впрочем, не исключено, что они будут генериться по тем параметрам, что ставятся в кубике. Что не может не радовать. А вот Report Descriptor стоит изучить получше — это фактически основное, что придётся в дальнейшем править ручками. Не знаю, откуда RaJa взял его дескрипторы, в нашём случае они генерируются кубиком и располагаются в следующих файлах проекта:

      Дескриптор от RajaДескриптор от STФайл в проекте
      RHID_DeviceDescriptorUSBD_FS_DeviceDescusbd_desc.c
      RHID_ConfigDescriptorUSBD_CUSTOM_HID_CfgFSDescusbd_customhid.c
      RHID_ReportDescriptorCUSTOM_HID_ReportDesc_FSusbd_custom_hid_if.c

      Поскольку для простоты сейчас будем работать только с ST HID Demonstrator, то не мудрствуя лукаво я просто скопировал содержимое RHID_ReportDescriptor в соответствующее место моего проекта. Только подставил свои константы на место длины. Надо отметить, что надо точно посчитать количество байтов в этом дескрипторе (в этом проекте 79) и убедиться, что именно это значение стоит в Class Parameters. Не больше и не меньше. Иначе хост не опознает подключённое устройство. Проверено 🙂

      Далее заходим в файл usbd_customhid.h и меняем значения CUSTOM_HID_EPIN_SIZE и CUSTOM_HID_EPOUT_SIZE на 0x40U. Честно говоря, немного напрягает то, что ST не даёт альтернатив смене значения по умолчанию 2 на другое значение и далее в коде с использованием этих констант стоит комментарий, что не более 2х байт. Но, с другой стороны, это было рекомендовано в первом найденном описании и, вообще говоря, установка такого значения выглядит достаточно логично. Иначе в чём отличие CustomHID от обычного? Проблема в том, что при регенерации проекта из кубика, что на этапе первичного кода происходит довольно часто, это значение не сохраняется и его надо восстанавливать ручками. Для этого я себе в main вывел строку warning, чтобы не забывать проверить эти константы. Возможно я ошибаюсь, и в дальнейшем всё окажется проще. Но в такой конфигурации работает 🙂

      Цикл обмена (пишем/читаем)

      Для выдачи данных на хост всё достаточно аналогично описанию на Хабре. Только название функции другое: USBD_CUSTOM_HID_SendReport(). Все остальные реомендации из той статьи подходят по полной программе.

      А вот чтение здесь интереснее, чем на Хабре. И на самом деле несколько проще. Обработка принятого массива происходит в usbd_custom_hid_if.c / static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state).

      В этом тестовом проекте я не заморачивался с обработкой входных параметров и следуя своей обычной практике минимальности времени обработки прерываний, просто копирую полученные данные в заранее определённый массив и устанавливаю флаг готовности данных от USB

      Ну, а собственно «сбор данных» (нажатие кнопок джойстика) и реакция на полученные от хоста данные в этом прото проекте делаю внутри бесконечного цикла в main.c Всё просто 🙂 В этом прото проекте нет разделения реакции на SET_FEATURE и SET_REPORT, с этим надо будет разобраться далее, в реальном проекте. Компилируем, запускаем, подключаем к хосту и там должен появиться новый CustomHID от STMicroelectronics.

      Звпускаем на хосте USB HID Demonstrator. На плате, с которой я запускал этот проект, не имеет органов для работы с Variable Inputs/Outputs, поэтому в разделе Graphic customization были убраны соответствующие назначениями, оставлено 5 кнопок и назначены ID, определённые в проекте: 1, 2 для Output report (входные данные для ST) и 4 для Input Report (выход от ST).

      Рис. 4 Настройка демонстратора

      Моей задачей для этого проекта было управлять парой светодиодов на плате, что стало работать сразу, как эта программа обнаружила подключенную плату, и включать «лампочки» этой платы при нажатии различных кнопок джойстика на плате, а вот здесь сразу не получилось. При указанных настройках все пять лампочек одновременно зажигались при нажатии на центр джойстика. Остальные кнопки не отображались. При этом, если перейти на Input/Otput transfer, то данные были вполне ожидаемы. Т.е. сам интерфейс работает, но отображение в программе на хосте не отвечает моим запросам. Слава богу ST предоставляетс исходники, а в соседнем кубике сидит программист нашей группы, пишущий в том числе и софт для компьютеров. В общем, он подправил одну функцию и сгенерил исполняемую программу. Всё стало работать, как хотелось. Конечно, можно было бы на каждую кнопку создать свой report с уникальным номером, что исходно и предусмотрено. В этом случае было бы достаточно посылать по одному байту для каждой кнопки, но мой проект предусматривает многобайтный отчёт. Исходник подправленной функции и подправленный исполняемый файл можно скачать по ссылке ниже.

      На этом, пожалуй, всё. Если у Вас есть такая же плата 32L476GDISCOVERY, то для начала можно просто скачать мой прото проект, адаптированный для него демонстратор и исходник изменённой функции по этой ссылке. Исходный USB HID Demonstrator скачивается с сайта STM, инсталлируется и его исполняемый файл заменяется моим. Импортируете в STM32IDE мой проект, компилируете и должны получить работающую базу для своих проектов. Если у Вас другая плата, то адаптируете «сбор информации» и включение светодиодов под свою плату.

      Для дальнейшей работы обязательно прочтите указанную статью RaJa с Хабра. Она даст понимание того, что и как должно быть сделано для других проектов с USB HID интерфейсом. А ещё лучше начать с неё 🙂

      И при выборе класса устройства для Вашего проекта надо учитывать следующее: минимальный период опроса HID устройств — 1ms. И если я правильно помню, это скорее пожелание системе от внешнего устройства. В стандартном HID устройстве за один кадр (frame) передаётся только два байта, т.е. скорость обмена не более 2 кбайт/с. В Custom HID на
      Full Speed (12 мбит/с) объём данных отчёта (report) – не более 64 байт, т.е. скорость обмена с Вашим HID не более 64 кбайт/с. Для High Speed (480 мбит/с) — максимальный объём данных 512 байт (512 кбайт/с). Не будь у меня ограничения совместимости с предыдущим софтом, используемым в компании, использовал хотя бы CDC.

      У меня изучение статей и адаптация под мои хотелки заняло три дня. Описание заняло больше 🙂 Надеюсь, что у тех, кто воспользуется этой статьёй, аналогичный процесс займёт не более одного дня. Комментируйте, спрашивайте. Что смогу — отвечу. Что не смогу, вместе поищем решение.

      Рейтинг
      ( Пока оценок нет )
      Загрузка ...
      Adblock
      detector