Here's a short write up about using an LCD from SeaBass with the APP-IV kit. The APP-IV contains an LCD library for use with GCC. The library header file contains information about the hook up of the LCD and has several configuration parameters.

For a simple project, I connected 2x16 LCD to an APP-IV (it just happened to be what I had handy -- you could use a smaller or larger one). I wanted a 60 second count down timer. When the processor starts, it displays 60 on the LCD and then counts down each second until it get to zero. Pressing the reset button restarts the timer. Simple, but it does show how to create a real time counter and use the LCD from SeaBass.

The app4lcd.h header has to be configured correctly. It also explains how to connect the LCD:

#define LCD_LINES           2     /*< number of visible lines of the display */
#define LCD_DISP_LENGTH    16     /*< visibles characters per line of the display */
#define LCD_LINE_LENGTH  0x40     /*< internal line length of the display    */
#define LCD_START_LINE1  0x00     /*< DDRAM address of first char of line 1 */
#define LCD_START_LINE2  0x40     /*< DDRAM address of first char of line 2 */
#define LCD_START_LINE3  0x14     /*< DDRAM address of first char of line 3 */
#define LCD_START_LINE4  0x54     /*< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES      0     /*< 0: no wrap, 1: wrap at end of visible line */
/* As set up, the LCD is connected like this:
   DB7 - PD.7
   DB6 - PD.6
   DB5 - PD.5
   DB4 - PD.4
   RS -  PB.2
   E  -  PB.1
   WR -  PB.0
*/

Even if you don't know C, you can poke around in the file and make the changes you want. For most LCDs, the LCD_LINE_LENGTH and LCD_START_LINEx doesn't require changing. Note that some 1x16 displays are really 2x8 displays end to end. For this project, that won't matter since we are just using 2 digits anyway!

That's all of the C code required. One of the APP-IV application notes describes how to make a real time countdown timer in C. Instead of including this in C, I just wrapped it in a SeaBass file. Of course, you could just as easily have kept it in C and used CINCLUDE and #link to include it.

Here's the timer file (timer.bas):

` This code is mostly C so it is isolated
` as a "library"
@@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
volatile uint8_t tick;    // 1 second
volatile uint8_t subtick; // 100mS
int timeron;
//When enabled, this does the 1 second count down
SIGNAL(SIG_OVERFLOW1) {
  TCNT1=49911;   //  reset counter to .1 mS
  // for every 10 sub ticks, we decrement tick, but
  // only if tick is non zero (so once you hit zero
  // there is no more counting)
  if (--subtick==0)
    {
      subtick=10;
      if (tick) --tick;
    }
}
// Start timer running
// ensures you don't get part of the old count
void startsubtimer(void)
{
  sei();
  TCCR1B=3;  // divide by 64
  TCNT1=49911; // this gives us 15624 counts or about .1s
  TIFR&=~(1<<TOV1);
  TIMSK|=(1<<TOIE1);  // start timer
  timeron=1;
}
void starttimer(void)
{
  subtick=10;
  startsubtimer();
}
// Stops the timer
void stoptimer(void)
{
  timeron=0;
  TIMSK&=~(1<<TOIE1);  // stop interrupts
  TCCR1B=0;  // halt timer
}
@@

I could rewrite much of this in SeaBass, but since it is already in C, why not just wrap it with the @@ commands and use it as is. Notice that this code uses interrupts, but that is invisible to the SeaBass program. You simply set tick to the number of seconds to count down and then call starttimer. When tick goes to 0, the time has expired.

Once you have the LCD and timer libraries, the program itself is almost trivial:

cinclude "avr/io.h"
cinclude "app4.h"
cinclude "app4lcd.h"
#link "app4lcd.c"
` delay is required by lcd
#link "app4delay.c" 
include "timer.bas"
sub main()
Dim otick
lcd_init(LCD_DISP_ON_CURSOR_BLINK)
tick=60
starttimer()
do while 1
  if otick<>tick then
        otick=tick
        lcd_clear()
        lcd_putc(otick/10+'0')
        lcd_putc(otick%10+'0')
  end if
loop
end sub

Notice that the SeaBass program doesn't use app4delay.c, but since the LCD code does, you have to use the #link to bring it in at compile time.

The main loop remembers the last second it processed. If the tick value has changed, the program clears the LCD, and then prints the two digits on the LCD. Note that otick/10+'0' provides the ASCII equivalent of the 10's digit of otick and otick%10+'0' provides the 1's digit. The % operator is the remainder from integer division.

Consider the case where otick is equal to 41. Computing 41/10 results in 4 and adding '0' to it (ASCII zero) results in '4' -- the correct ASCII character. On the other hand, 41%10 = 1 (the remainder of 41/10). Adding '0' to 1 results in '1'.

A simple example, but one that uses a great deal of powerful code, including an LCD library and interrupts! It would be easy to make the LCD print a message at the end of the time (for example, "LIFTOFF") by using the lcd_puts function.


Site contents © 1997-2018 by AWC, Houston TX    (281) 334-4341