Tutorial 5
UART with LEDs and buttons

Program itself

Button timer is used to make a delay to avoid contact bounce. The way is simple: when button has been pressed, program ignores other button presses for 60 ms.

import mcujavasource.mcu.*;
import mcujavasource.mcu.io.*;

/** Tutorial 5: UART with LEDs and buttons.
 * When button is pressed, sends message to UART.
 * Receives control chars from UART.
 * Control chars: {led number (1 or 2)}{state (1=on, 0=off)}
 * Examples: 11 - turn on led1, 20 - turn off led2, 21 - turn on led2
 * Button is connected to GND and MCU INT0 pin (PD2 for ATmega8).
 * LED's anode is connected to +5V through 330 Ohm resistor,
 * cathode - to MCU port.
 * Uart speed = 4800 bps at 1 MHz MCU clock frequency, 38400 bps at 8 MHz.
 * Uart settings: 8 bits character, no parity, one stop bit.
 */
public class Tutorial5 extends Microcontroller
{
  /** Specifies delay.
   * 197 at 1 MHz, 22 at 4 MHz (60 ms).
   * 0 at 8 MHz (32 ms).
   * Note: at 8 MHz it's impossible to get 60 ms, delay will be 32 ms.
   */
  private static final int BUTTON_TIMER_INITIAL_VALUE = 197;
  
  private static final String POWER_ON = "Power on.\r\n";
  private static final String BUTTON_PRESSED = "Button pressed.\r\n";
  private static final String LED_STRING = "LED";
  private static final String WAS_TURNED = " was turned ";
  private static final String ON_STRING = "on.\r\n";
  private static final String OFF_STRING = "off.\r\n";
  
  private UartInputStream uartInput;
  private UartOutputStream uartOutput;
  
  /** 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);
  
  private ExternalInterrupt buttonInterrupt;
  private Timer buttonTimer;
  
  private volatile boolean buttonPressed = false;
  private volatile boolean buttonPressedTransmitted = true;
  
  public void init()
  { //register initialization on startup
    getHardware().setAllPortsDirection(Pin.IN);
    getHardware().setAllPortsPullUp(true);
    led1.setDirection(Pin.OUT);
    // leds are initially turned on
    led1.setOutput(Pin.LOW);
    led2.setDirection(Pin.OUT);
    led2.setOutput(Pin.LOW);
    // button external interrupt
    buttonInterrupt = getHardware().getExternalInterrupt(0);
    buttonInterrupt.setEdge(InterruptEdge.FALLING);
    ButtonListener bl = new ButtonListener();
    buttonInterrupt.addExternalInterruptListener(bl);
    buttonInterrupt.setInterruptRequestFired(true);
    // button timer
    buttonTimer = getHardware().getDefaultTimer(8);
    buttonTimer.setMode(TimerMode.NORMAL);
    buttonTimer.setPrescaling(1024);
    buttonTimer.setEnabled(false);
    ButtonTimerListener btl = new ButtonTimerListener();
    buttonTimer.addTimerListener(btl);
    buttonTimer.setTimerOverflowedFired(true);
    // UART
    Uart uart = getHardware().getDefaultUart();
    uart.init(25, true, 8, Uart.Parity.NONE, false);
    uartInput = uart.getInputStream();
    uartOutput = uart.getOutputStream();
  }
  
  public void start()
  { //main program
    getHardware().setInterruptsEnabled(true);
    uartOutput.write(POWER_ON);
    while(true)
    { if(!buttonPressedTransmitted)
      { uartOutput.write(BUTTON_PRESSED);
        buttonPressedTransmitted = true;
      }
      if(uartInput.available() >= 2)
      { char led = (char) uartInput.read();
        if(led == '1' || led == '2')
        { char state = (char) uartInput.read();
          uartOutput.write(LED_STRING);
          uartOutput.write(led);
          uartOutput.write(WAS_TURNED);
          if(state == '0')
          { if(led == '1')
            { led1.setOutput(Pin.HIGH);
            }
            else
            { led2.setOutput(Pin.HIGH);
            }
            uartOutput.write(OFF_STRING);
          }
          else
          { if(led == '1')
            { led1.setOutput(Pin.LOW);
            }
            else
            { led2.setOutput(Pin.LOW);
            }
            uartOutput.write(ON_STRING);
          }
        }
      }
    }
  }
  
  private class ButtonListener implements ExternalInterruptListener
  {
    public void interruptRequested()
    { if(!buttonPressed)
      { buttonPressed = true;
        buttonPressedTransmitted = false;
        buttonTimer.setValue(BUTTON_TIMER_INITIAL_VALUE);
        // timer delay start
        buttonTimer.setEnabled(true);
      }
    }
    
  }
  
  private class ButtonTimerListener implements TimerListener
  {
    public void timerOverflowed()
    { buttonPressed = false;
      //stopping timer
      buttonTimer.setEnabled(false);
    }
    
  }
  
  
}

Download java source file