Introduction

This lab is designed to introduce you to the Analog Devices ADuC7020 microcontroller which we will be using for this course. You will often need to refer to the datasheet(pdf) on the Resources page.

Note If you are "bringing your own board," you may do the checkoff requirements on your board instead of the ADuC7020.

Checkoff requirements

  • Print “Hello World” to a serial terminal

  • Solder and blink an LED using a timer

“Extra for experts”

If you found the other exercises relatively straightforward, this is for you! These are extra and will not be due.

  • Modify getchar() to be non-blocking

  • Make an LED fade in/out

Version Control with SVN

It’s good to get into the habit of working with version control. This will pay dividends in the near future. Version control will let you easily save — and if necessary, roll back to — a version of code that works. It also enables multiple team members to work on code and merge changes.

We have Subversion (SVN) repositories set up for each team. You may use your own version control if you desire.

(Many people prefer git, but support on instructional computers is not very good at the moment.)

  1. Download the starter code to begin.

  2. Create a workspace directory (i.e. U:\workspace) and check out your team repository into a sub-directory (i.e. U:\workspace\teamX)

    images/cp1/svn1.jpg

    The repository URL is https://isvn.eecs.berkeley.edu/ee192/teamX (replacing X with your team number).

    images/cp1/svn2.jpg

  3. Now we’ll create some files. Let’s unzip the code into the trunk/ directory, say into trunk/week1-helloworld.

    Note

    A note about the default directories:

    • The main branch of code that everybody is working on is called the trunk.

    • Branches are copies of trunk used for work in progress (i.e. branches/motorcontrol may contain some experimental motor code). That way you can save your work without ruining the main copy in trunk. This code is merged back into trunk eventually.

    • Tags are typically for code that you want to save (i.e. tags/round1finalcode for the version of code that you used for the Round 1 race).

    • You can also completely ignore these guidelines if you choose! There is nothing special about these folder names.

  4. Anyway, since this is not an SVN class let’s just get on with using it.

    First you need to add the new files/folders to tell SVN to track the changes.

    images/cp1/svn3.jpg

    Now you need to commit to save the changes to the remote repository. That’s located on isvn.eecs.berkeley.edu, not on your local computer! Enter a commit message so you can find it later, especially if it’s an important commit (e.g. THIS CODE WORKS!!!1!~).

    images/cp1/svn4.jpg

  5. Now your files are safely tucked away in the EECS SVN servers. That’s all for now!

    • If you want to know more, Paul Hilfinger’s Using Subversion guide is a good start. It will teach you how to un-add changes, merge branches, and fall back to previous versions.

    • The SVN Book is a more comprehensive resource.

Serial communication

“Hello World” is traditionally the most basic of programs. We’ll use this to test that you have your programming environment set up.

Open the Hello project in Keil uVision IDE by double clicking the uVision project file. Compile.

images/cp1/hello1.png

Use ARMWSD (in Programs > ADuC702x) to load the resulting .hex file. (It uses COM1 by default… make sure it’s configured to the correct serial port!)

images/cp1/hello2.jpg

Hold the Serial Download button while pulsing Reset.

When it’s done, open PuTTY to view the output. Select Connection type: Serial and ensure the correct serial port is selected.

images/cp1/hello3.jpg

Reset the processor and you should see something like this:

images/cp1/hello4.jpg

The next task is to make an LED blink at 1Hz, 50% duty cycle. (That means it’s on 50% of the time and off 50% of the time.)

Do not use the built-in LED on pin P4.2 for this exercise. You will need to solder a new LED to one of the other I/O pins. (Choose the value of the current-limiting resistor so that the LED receives about 1.6mA of current. The supply voltage is 3.3V.)

One naive way to blink an LED is to toggle the LED, wait for 500ms, and repeat ad infinitum. This example code uses the built-in LED.

GP4DAT = 0x04000000;                    // P4.2 configured as an output. LED is turned on

while(1) {
    GP4DAT ^= 0x00040000;               // Complement P4.2
    wait(500);
}
Tip Switching individual pins on and off is described in the ADuC7020 datasheet on page 59, General-Purpose I/O.

However, this is extremely wasteful because while the processor is waiting 500ms it isn’t doing anything productive. It’s busy-waiting for 500ms. Surely there’s a better way…

What if we set a timer to interrupt the processor when 500ms is up? Then the processor can do useful work during that 500ms. When the interrupt is triggered, it runs a piece of code called the interrupt handler, before going back to what it was doing previously.

Try using a timer blink your LED at 1Hz, 50% duty cycle.

Tip The datasheet’s description of the timers is on page 74.

[Extra] Non-blocking serial communication

Note The following sections are extra material which will be of interest, but not required for the checkoff.

In serial.c, there are two versions of putchar: putchar_buf and putchar_block. Notice how putchar_block does the same thing as the naive blinking code — it busy-waits while the bytes are sent.

On the other hand, putchar_buf places the characters in a buffer. This buffer is emptied every so often by print_function which is called periodically by the Timer 0 interrupt handler (see below).

void IRQ_Handler(void) __irq {
    if((IRQSTA & RTOS_TIMER_BIT)!=0) {
        /* place code to service the Real Time OS Timer interrupt here */
        systime++;

        if(systasks & RTF) RealTime();
        if(systasks & PRINT) print_function(); // handle background printing      1

        T0CLRI = 0;        // clear interrupt for next time
    }
    // catch other IRQ here
    return;

}
1 Serial port print handler

As a simple exercise, rewrite the getchar() function to be non-blocking. Instead of busy-waiting for a character, have it return -1 if no character has been received. (This should be much simpler than non-blocking putchar().)

Tip Once again, the datasheet will come in handy to understand the operation of the UART Serial Interface (page 61).

[Extra] LED fade effect

You may notice how Apple computers have an LED that fades in and out while it is in sleep mode.

Variable brightness is achieved by driving the LED with a PWM signal. The brightness varies based on the duty cycle % of the PWM. The PWM frequency should be fast enough so that the eye cannot detect the off period, say 100Hz or higher.

Demonstrate a fading LED effect, making an LED fade in and out smoothly. You may choose to generate the PWM signal by modifying your timer code from the blinking LED exercise.

Changelog

  • 1.0 [2012 Jan 20]: Initial version.

  • 1.1 [2012 Jan 30]: Modify LED current to 1.6mA.