Помните учебник 2? Там мигали 3 светодиода. И мы писали led1.setOutput(Pin.LOW)
, чтоб включить светодиод. Однако удобнее создать объект Светодиод (LED) и написать что-то вроде led.setState(Led.State.ON)
Для простого светодиода разница небольшая, но для сложных объектов (вроде ЖКИ) код становится проще, безопаснее и гибче.
Объекты пользователя работают иначе, чем основной класс и слушатели. Код объекта пользователя компилируется и выполняется на компьютере, а не интерпретируется. Значит, он может выбрасывать исключения и использовать другие возможности языка Java. Вот шаблон:
//packages for user objects
import mcujavasource.transformer.instance.*;
import mcujavasource.transformer.userclass.*;
class MyObject extends AbstractInstanceUser
{
private SourceInstance pin;
public MyObject(Pin pin)
{ //only for running on PC
}
public MyObject(InstanceContext context, SourceInstance pin)
{ super(context);
this.pin = pin;
invoke(pin, "setDirection", Pin.OUT);
}
public void method()
{ invoke(pin, "pinMethod", args);
}
}
mcujavasource.transformer.userclass.AbstractInstanceUser
InstanceContext context
добавляется первым аргументом и все аргументы-объекты становятся типа SourceInstance. Первый оператор должен быть super(context);
invoke(SourceInstance si, String methodName, Object... args);
Например, pin.setOutput(Pin.LOW);
становится invoke(pin, "setOutput", Pin.LOW);
в пользовательском объекте.include(String name)
, name - имя файла, которое будет вставлено в оператор #include "name"
Файлы по маске "**/*.c,**/*.cpp,**/*.h,**/*.s,**/*.S,**/*.asm" копируются из папки src в build в проекте NetBeans. Чтобы вызвать функцию, описанную в файле на С, вызвите метод callFunction(String functionName, Object... args)
Программа работает так же, как и в учебнике 2. Результирующий С код (файл main.c) абсолютно одинаковый.
import mcujavasource.mcu.*;
//packages for user objects
import mcujavasource.transformer.instance.*;
import mcujavasource.transformer.userclass.*;
/** Tutorial 7: simple user object.
* It's tutorial 2, rewritten with SimpleLed object.
* Three LEDs flash one after another.
* Default 8-bit timer and its overflow interrupt is used for delay.
* LED's anode is connected to +5V through 330 Ohm resistor,
* cathode - to MCU port.
*/
public class Main extends Microcontroller
{
/** Pin of the first LED, PB1 */
private final Pin led1Pin = getHardware().getPort("B").getPin(1);
/** Pin of the second LED, PB0 */
private final Pin led2Pin = getHardware().getPort("B").getPin(0);
/** Pin of the third LED, PB2 */
private final Pin led3Pin = getHardware().getPort("B").getPin(2);
private SimpleLed led1;
private SimpleLed led2;
private SimpleLed led3;
private Timer timer;
private volatile int currentLed = 0;
public void init()
{ //register initialization on startup
getHardware().setAllPortsDirection(Pin.IN);
getHardware().setAllPortsPullUp(true);
led1 = new SimpleLed(led1Pin);
led2 = new SimpleLed(led2Pin);
led3 = new SimpleLed(led3Pin);
// led1 is initially turned on
led1.setState(SimpleLed.State.ON);
// getting default 8-bit timer
timer = getHardware().getDefaultTimer(8);
timer.setMode(TimerMode.NORMAL);
// no prescaling
timer.setPrescaling(1);
timer.setEnabled(true);
LedSwitcher ledSwitcher = new LedSwitcher();
timer.addTimerListener(ledSwitcher);
timer.setTimerOverflowedFired(true); //this enables interrupt
}
public void start()
{ //main program
getHardware().setInterruptsEnabled(true);
}
private class LedSwitcher implements TimerListener
{
public void timerOverflowed()
{ currentLed++;
if(currentLed >= 3) currentLed = 0;
switch(currentLed)
{ case 0:
led3.setState(SimpleLed.State.OFF); //turn off led3
led1.setState(SimpleLed.State.ON); //turn on led1
break;
case 1:
led1.setState(SimpleLed.State.OFF);
led2.setState(SimpleLed.State.ON);
break;
case 2:
led2.setState(SimpleLed.State.OFF);
led3.setState(SimpleLed.State.ON);
break;
}
}
}
}
class SimpleLed extends AbstractInstanceUser
{
public enum State { ON, OFF };
private SourceInstance pin;
/** Creates a SimpleLed from the given pin.
* Initial state is OFF.
*/
public SimpleLed(Pin pin)
{ //only for running on PC
}
//Pin class turned into SourceInstance, and InstanceContext context added
public SimpleLed(InstanceContext context, SourceInstance pin)
{ super(context);
this.pin = pin;
invoke(pin, "setDirection", Pin.OUT);
invoke(pin, "setOutput", true);
}
public void setState(State state)
{ boolean value = (state == State.OFF);
invoke(pin, "setOutput", value);
}
}