Микропроцессоры и микроконтроллеры

 
 
 
«'Legacy code' often differs from its suggested alternative by actually working and scaling.»
Bjarne Stroustrup
Русский | Українська


Микропроцессоры и микроконтроллеры :: JAVA и STM32 - курс экспресс-программирования с MicroEJ :: JAVA и STM32 - курс экспресс-программирования с MicroEJ. Часть восьмая

JAVA и STM32 - курс экспресс-программирования с MicroEJ. Часть восьмая

public static void main(String[] args) {

        MWT.RenderingContext.add(new PlainTheme());
        Desktop desktop = new Desktop();
        Panel panel = new Panel();
        GridComposite gc = new GridComposite(MWT.VERTICAL, 4);
       
        TitleLabel title = new TitleLabel("ADC/DAC EXAMPLE");
        title.setFontSize(LookExtension.GET_X_BIG_FONT_INDEX);
        gc.add(title);
       
        FlowComposite fcDac = new FlowComposite();
       
        TitleLabel labelDacTitle = new TitleLabel("Dac Value [mV]:");
        fcDac.add(labelDacTitle);
       
        TextField dacValueField = new TextField("--------");
        fcDac.add(dacValueField);
       
        Scale scaleDac = new Scale(0, 300);
        fcDac.add(scaleDac);
       
        gc.add(fcDac);

        FlowComposite fcAdc = new FlowComposite();
       
        TitleLabel labelAdcTitle = new TitleLabel("ADC Value [mV]:");
        fcAdc.add(labelAdcTitle);
       
        TextField adcValueField = new TextField("--------");
        fcAdc.add(adcValueField);
       
        Button buttonAdc = new Button("Get ADC value");       
        fcAdc.add(buttonAdc);

        gc.add(fcAdc);
       
        panel.setWidget(gc);
        panel.show(desktop, true);
        desktop.show();
}

 

Листинг. 1. Генерация GUI в основном методе

В первой инструкции (MWT.RenderingContext.add (new PlainTheme ());) внешний вид приложения устанавливается. Объект PlainTheme содержит инструкции по цвет нарисованных компонентов и используемые шрифты. Он определен в библиотеке, но ничто не мешает вам создать собственную графическую тему.

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

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

Первый виджет добавлен в объект Panel: GridComposite. Это один из виджетов, задачей которого является хранение и позиционирование других объектов. Благодаря этому одна панель может содержать множество элементов, расположенных в разных конфигурациях. GridComposite размещает элементы вертикально или горизонтально в сетке заданного размера, в зависимости от аргументов своего конструктора. Его элементами могут быть как обычные виджеты, видимые пользователю, так и объект TitleLabel, отображающий строку, а также последующие виджеты позиционирования. Благодаря этому вы можете свободно создавать полный графический интерфейс. Таким образом, были подготовлены еще две группы виджетов, которые группируют элементы управления передатчиком внутри объектов FlowComposite, отображая их содержимое рядом в порядке добавления и перемещаясь на новую строку в отсутствие пробела. После создания и добавления всех необходимых элементов весь интерфейс отображается на экране. Эффект можно увидеть на рисунке 5.
Графический интерфейс для управления преобразователями
Рис. 5. Графический интерфейс для управления преобразователями

 

Конструктор объекта scaleDac все еще нуждается в комментарии:

       Scale scaleDac = новая шкала (0, 300);

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

Обработка событий


После заполнения пользовательского интерфейса необходимо подготовить сервис событий, поступающих с него. В представленном приложении есть два компонента, которые могут генерировать события: buttonAdc типа Button и scaleDac типа Scale. Принцип обработки их событий идентичен классу EventGenerator из предыдущего примера. Поэтому необходимо создать новые классы: DACScaleListener и ADCButtonListener, реализующие то же, что и до интерфейса Listener с методами executeAction. На этот раз, однако, вы должны реализовать метод, который принимает два аргумента (executeAction (int value, Object object)) - первый - это значение, а второй объект, который сгенерировал событие. Оба объекта слушателя также могут устанавливать значения текстовых полей, соответственно dacValueField и adcValueField в ответ на событие. Эти объекты передаются в конструкторы слушателей.

Поддержка преобразователя (Java)


Последняя часть Java-приложения - это управление преобразователем. В примере это будет ограничено настройкой и считыванием значения АЦП или установкой значения ЦАП. Для этой задачи будут созданы два дополнительных класса, которые предоставят эти методы другим объектам приложения.

Код, отвечающий за службу периферии, будет добавлен на уровень BSP, однако приложение Java должно иметь возможность вызывать соответствующие функции C. Для этой цели в MicroEJ стал доступен механизм под названием SNI (Simple Native Interface). вызов функции C из приложения Java. Приложение ничего не знает о содержимом этих функций - оно знает только их имена, списки аргументов и типы возвращаемых значений. Все, что вам нужно сделать, это объявить их внутри класса с помощью ключевых слов «статический нативный», как показано в листингах 2 и 3, содержащих коды классов ADC и DAC.

 
public class ADC {
    static native void ADCInit();
    static native int ADCGetValue();

    public void init() {
        ADC.ADCInit();
    }

    public int getValue() {
        return ADC.ADCGetValue();
    }
}

Листинг. 2. Код класса АЦП

 

public class DAC {
    static native void DACInit();
    static native void DACSetValue(int value);

    public void init() {
        DAC.DACInit();
    }

    public void setValue(int value) {
        DAC.DACSetValue(value);
    }
}

Листинг. 3. Код класса ЦАП

Благодаря объектам классов ADC и DAC объекты прослушивателя пользовательского интерфейса могут получать доступ и считывать преобразователи и изменять их значение. Код слушателя показан в листингах 4 и 5.

 
public class ADCButtonListener implements Listener {

    private TextField valueField;
    private ADC adc;
   
    public ADCButtonListener(TextField valueField, ADC adc) {
        this.valueField = valueField;
        this.adc = adc;
    }
   
    @Override
    public void performAction() {
        // TODO Auto-generated method stub
    }

    @Override
    public void performAction(int value) {
        // TODO Auto-generated method stub
    }

    @Override
    public void performAction(int value, Object object) {
        int adc_value = this.adc.getValue();
        this.valueField.setText(Integer.toString(adc_value));
    }
}

Листинг. 4. Код класса ADCButtonListener

public class DACScaleListener implements Listener {

    private TextField valueField;
    private DAC dac;
   
    public DACScaleListener(TextField valueField, DAC dac) {
        this.valueField = valueField;
        this.dac = dac;
    }
   
    @Override
    public void performAction() {
        // TODO Auto-generated method stub
    }

    @Override
    public void performAction(int value) {
        // TODO Auto-generated method stub
    }

    @Override
    public void performAction(int value, Object object) {
        this.valueField.setText(Integer.toString(value*10));
        this.dac.setValue(value*10);
    }
}

Листинг. 5. Код класса DACScaleListener

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