Bascom AVR

From Wiki

Jump to: navigation, search


Contents

Introduction

Bascom AVR is a simple BASIC-style language compiler for AVR microcontrollers. It supports most of the features of the AVR chips, and uses an easy-to-learn BASIC language syntax.

Bascom AVR is a good option if you don't want to learn the C language, and your AVR programming won't rely on exact timing loops. The GNU C Compiler offers more fine-grained control over chip functions and timing, but is a bit more difficult to learn and program.

Starting

First, install AVRStudio, it provides STK500 support to Bascom. Then, go to mcselec.com and choose downloads. Get the Demo Version, and the PDF manual. If you're running Linux, bascomp.exe will work in Wine. Unzip it, install it, run. While you're on the website, look at the forum, you'll go back there often. The first section of the manual you need to read is "Bascom Language Fundamentals".

Preamble

To start out any program, you should make explicit compiler setup statements. These can be set in Options/Compiler/Chip, but those settings won't be saved alongside your program. Pointer to a guide about stack/frame sizes here

$Regfile = "m16def.dat" 'Look at The Options/Compiler/Chip/Chip dropbox to find chip definition files 
$crystal = 4_000_000  ' Tells the library how much to delay time-accurate routines. Does NOT change chip speed!
$Baud = 4800 ' The speed of the UART
 
'how do we choose these last 3? Deep magic.
$Framesize = 50    ' don't know
$Swstack = 50      ' holds function call arguments, always referenced by Y reg 
$Hwstack = 20

Programming

You should have some familiarity with BASIC. This section concentrates on quirky behavior.

Arrays

DIM foo(10) AS BYTE

Bascom can handle One dimension arrays of up to 255 of any type. You cannot immediately calculate an array index, such as Array(a*2). You must put your fancy index into a tmp variable. You also cannot use an IRAM (like register in C) variable to index into the array.

Strings

DIM text AS STRING * 20

Strings are null-terminated, and allocate one more byte than you ask for. Strings cannot be manipulated willy-nilly as if they were byte arrays. If you want to do regular array manipulations, you must make an alias to the string(DIM textAlias AS BYTE(21) at 123 OVERLAY). They can be concatenated with +, split with MID/LEFT/RIGHT, and there are other adulteration functions.

Assignments

A=B+C 'woohoo!

Assignments can take Dim'd variables, array elements, register names, and ONE operator. There is no order of precedence, as you, once again, are only allowed one operator. For fuller equations, you need to stick results into a tmp variable.
A=B+C*D becomes tmp=C*D: A=B+tmp. Sure, A could be used as the tmp in this simple example.

Another mystery..

Aint=2047
ex 1. AByte=Aint/16 'equals 15!
ex 2. Anotherint=Aint/16 'equals 127

Branches

IF a=1 OR b<>2 AND c<3 THEN
    Something
ELSE 
    opposite thing
ENDIF

The else is optional, of course. No branch statement can do math, it must be done in an assignment.

Loops

FOR a=5 TO 1 STEP -1
    something
NEXT a

Next can have non-commented text after it, Bascom doesn't verify that it lines up with what you think it should.

FUNCTION/SUB

DECLARE FUNCTION doit(BYVAL a AS BYTE, BYREF b AS LONG)
foo = CALL doit(12,z)
FUNCTION doit(BYVAL a AS BYTE, BYREF b AS LONG)
    LOCAL z AS BYTE
    something
    doit=z
END FUNCTION

Subs are just functions without a return value. LOCAL variables cannot be DOUBLE floats or BIT. Local variables are on the stack, so the function is re-entrant. Local is also the only way to make a variable name that only exists inside a function. If you're using assembler in a function, read the manual section "Mixing ASM and BASIC" closely, LOCALs can be tricky there. If a function is in the "line of fire", execution will step right into it. You must GOTO past the function if it's at the top of your file (such as when you put it inside an $INCLUDE).

Assembler

if you accidently put "LD R0,Z+4" instead of "LDD R0,Z+4", Bascom will not complain. It will instead discard the unexpected displacement. It will complain for X, but not Y or Z. Strange.

Bascom gives roundabout ways to reserve registers for ASM use. DIM foo AS IRAM BYTE gives you a (looks like it's) safe register, not sure about safety with library routines. You need to look at the Alt-W compiler results to see the actual number of the register you recieved. X (and probably Z) look safe for a burst of ASM, the compiler makes no persistent assumptions about them.

If you want to see the assembler code generated, open the .OBJ file in AVR Studio.

WAITUS

Just about worth its own section. The manual is out of date on this, it is better than stated. It will put anywhere from one nop up to a full blown delay function call as needed. As such, it will generate almost exactly what you ask for. If you want to dynamically shim out a code block, first profile out, set GIVENCYCLES and TARGETTIME ..

crystal=4_000_000 : $crystal=crystal
const GIVENCYCLES = 45 'how many cycles your code actually takes
const TARGETTIME = 1000/15 'how many us you want to take. This is for 15 times per ms
const OPCODETIME = 1_000_000/crystal 
const STALLTIME = TARGETTIME - GIVENCYCLES * OPCODETIME
..
FOR ..
    blah
    WAITUS STALLTIME
NEXT

EXIT FOR/DO/WHILE/SUB/FUNCTION

Mostly like break in C. You specify which class of structure you are trying to jump out of. It can act strange with nesting, so a "GOTO breakBananaCountLoop" may be cleaner. When should you EXIT SUB or EXIT FUNCTION instead of RETURN?

Debugging

Profiling

The simulator keeps track of clock counts and real time (according to the declared clock speed). You can set 2 breakpoints around a program reigon you want to profile. Play through to the first break, and right click on the lower status-bar. You'll be able to "Clear Cycles" to reset the simulator's stopwatch. Resume the simulation, and when the second break is hit, you'll know exactly how much time that is taking. This is great for tweaking timing-sensitive code, especially with inline assembler.

If you want to see the assembler code that Bascom is generating, open up the .OBJ file in AVRStudio. That gives a great starting point for converting to assembler.

Possible Hangups

Like any programming environment, there are a few rough edges. At least you're not stuck writing Makefiles for C!

  • There's a lingering bug in Bascom's config options where it won't save if you don't have a printer. If you don't have one, you need to install something., Just install a generic text printer.
  • Something about STK500 setup
  • Bascom uses the programmer .exe inside AVR Studio's directory. You may have to change this in config. It generates a .bat file whenever you press F4 to install your AVR code. This .bat program's window usually blinks away quickly when programming fails, and lingers for a second if it's writing successfully. Watch the green programming light turn orange on your STK500 when you press F4.
  • Bascom has context help on F1, however, it is rude and stays above the program when you want to flip back and forth. Keep the PDF you downloaded earlier open instead.
Personal tools