Вот типичная структура программы на Java:
import mcujavasource.mcu.*;
public class MyProgram extends Microcontroller
{
//constants
private static final int MY_NUMBER = 25;
//fields
private final Pin myPin;
private final Timer timer;
private volatile int counter = 0;
public void init()
{ //register initialization on startup
}
public void start()
{ //global enabling interrupts, if needed, main program
}
//methods
private void myMethod()
{ //do something
}
private class MyListener implements TimerListener
{
public void timerOverflowed()
{ //do something, it will be interrupt handler
}
}
}
import mcujavasource.mcu.*;
- все классы МК находятся в пакете mcujavasource.mcu . Есть документация для этого пакета.
public class MyProgram extends Microcontroller
- основной класс - публичный (public), должен расширять Microcontroller (extends Microcontroller). Имя класса не влияет на перевод в С.
private static final int MY_NUMBER = 25;
- константы в Java имеют атрибуты static final. В Java отсутствует #define
, так что такая запись используется вместо #define
.
private final Pin myPin;
- Поля-объекты существуют только в исходнике Java.
public void init()
- всегда инициализируйте регистры в этом методе. Он вызывается после сброса МК или включения питания. Метод сильно оптимизируется во время перевода. Не разрешайте прерывания глобально здесь. Все операторы в этом методе могут быть перемешаны, и это не должно отразиться на работе устройства.
public void start()
- это метод вызывается после init(). Разрешайте прерывания глобально, проводите расчеты переменных, если нужно. Не ставьте в конец пустой бесконечный цикл (for(;;);), он вставляется автоматически при необходимости.
private class MyListener implements TimerListener
- класс слушателя. Всегда реализовывайте метод(ы), определенные интерфейсом (в данной случае TimerListener). За названием метода обращайтесь в документацию.
public void timerOverflowed()
- содержимое этого метода будет в обработчике прерываний.
Программа без прерываний. Два светодиода мигают по очереди. У каждого светодиода анод присоеденен к +5В через резистор 330 Ом, катод - к порту МК.
import mcujavasource.mcu.*;
/** Учебник 1: simple program without interrupts.
* Two LEDs flash one after another.
* LED's anode is connected to +5V through 330 Ohm resistor,
* cathode - to MCU port.
*/
public class Tutorial1 extends Microcontroller
{
/** Pin of the first LED, PB1 */
private final Pin led1 = getHardware().getPort("B").getPin(1);
/** Pin of the second LED, PB0 */
private final Pin led2 = getHardware().getPort("B").getPin(0);
public void init()
{ // setting all pins to input
getHardware().setAllPortsDirection(Pin.IN);
// enabling pull-ups on each pin
getHardware().setAllPortsPullUp(true);
led1.setDirection(Pin.OUT);
// led1 is initially turned on
led1.setOutput(Pin.LOW);
led2.setDirection(Pin.OUT);
led2.setOutput(Pin.HIGH);
}
public void start()
{ Delay delay = getHardware().getDelay();
while(true)
{ led2.setOutput(Pin.HIGH);
led1.setOutput(Pin.LOW);
// pause 1 second
delay.sleep(1000);
led1.setOutput(Pin.HIGH);
led2.setOutput(Pin.LOW);
delay.sleep(1000);
}
}
}
Скачать файл исходного кода программы
Имя файла исходника должно быта таким: имя класса + ".java" (в данном случае Tutorial1.java)
Заметьте, что первый комментарий должен находится перед определением класса, а не перед каким-либо "import".
Поля led1 и led2 имеют атрибут final, то есть им невозможно присвоить значение дважды.
Переменные оборудования - это переменные, представляющие оборудование. В данной программе это led1, led2 и delay.
Не присваивайте переменные оборудования дважды.. Это может вылиться в неопределенные действия с регистрами, и программа будет неправильно работать. Используйте отдельную переменную для кажного порта, вывода, таймера, и т. д.
Есть один способ получить объекты оборудования: через соответствующий метод класса HardwareFactory
. Откройте документацию Javadoc для HardwareFactory
прямо сейчас и просмотрите список методов. Как видите, любое внутреннее устройтсво МК можно получить отсюда. Также можно получить некоторые сущности (как Задержка, Delay). Чтобы получить HardwareFactory, вызвите getHardware()
(этот метод принадлежит классу Microcontroller). Например, чтобы получить порт B, напишите getHardware().getPort("B")
. Найдите в документации все методы, которые использовались в этом примере.
Перейдите к документации на Port
. Найдите метод getPin(int index)
. Чтобы получить Вывод (Pin), сначала нужно получить экземпляр Порта (Port) с помощью getHardware().getPort("portId")
. Если myPort - экземпляр порта, работает код myPin = myPort.getPin(5)
. Потом перейдите к документации на Pin и посмотрите, что можно с ним сделать.
Перейдите к классу Delay
. Его метод sleep
работает точно так же, как и на компьютере.
Самый простой способ.
Установите модуль NetBeans, если Вы этого ещё не сделали.
Есть и русская версия программы NetBeans, но у автора стояла английская, поэтому все команды меню будут на английском.
Начните новый проект (выберите File - New Project, тип проекта - "MCU", шаблон проекта - "MCU Java source application"). Скопируйте вышеприведенный код, замените "class Tutorial1" на "class Main".
Выберите Build - Build main project (F11) для компиляции.
Чтобы изменить настройки перевода (например, МК), внесите изменения в файл "transform.properties".
Чтобы изменить шаблон Makefile, измените "Makefile_mcuarch" ("Makefile_avr" для avr).
Сохраните файл Tutorial1.java с кодировкой UTF-8. Откройте оболочку командной строки и перейдите в папку, где находится файл Tutorial1.java:
cd directoryPath
Скомпилируйте Java класс
javac -classpath . Tutorial1.java
Если нет ошибок компилятора, переходите к следующему шагу. Иначе исправьте ошибки и перекомпилируйте до тех пор, пока не исчезнут ошибки.
Созданный файл Tutorial1.class сейчас не используется. Скопируйте файл Tutorial1.java в папку, где находится McuJavaSourceTransformer.jar и перейдите в ту папку.
java -jar McuJavaSourceTransformer.jar -mcuarch avr -mcu atmega8 -d . -SsourceEncoding=UTF-8 -SresultEncoding=UTF-8 -SclockFrequency=1000000 Tutorial1.java
Проверьте кодировку входного .java файла и результирующего .c файла. Если Вы используете WinAVR под Windows, кодировка resultEncoding, скорее всего, будет windows-1251.
Будет создан файл main.c. Затем сделайте файл сборки Makefile и скомпилируйте, как обычно:
make all
Если компилятор жалуется на непонятные символы в начале файла, поменяйте кодировку resultEncoding.