Skip to content Skip to navigation

OpenStax-CNX

You are here: Home » Content » General Assembly I/O and Looping: Elec 220- Lab 3

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

General Assembly I/O and Looping: Elec 220- Lab 3

Module by: Matthew Johnson. E-mail the author

Summary: In this lab, students apply what they have learned to implement some basic assembly coding principals to perform basic loop driven tasks with the MSP430.

Note: You are viewing an old version of this document. The latest version is available here.

Intro to the MSP430 and GPIO: Your Tasks

You will have two weeks to complete this lab. It is recommended to complete one task each week.

  1. Coding in MSP430 Assembly, implement a Fibonacci sequence calculator. This should be done with a loop and run infinitely. Step through, explain, and demonstrate the code, using the CCS4 Debugger. Be sure to view the registers while stepping through the program. Note the amount of CPU cycles each of the instructions takes to complete. Part I Detail
  2. Coding in MSP430 assembly, write a simple I/O echo program. Setup the GPIO pins and poll the input switches for any changes. On a change, take the input and display it to the output. Step through this program to observe how it behaves. Part II Detail

Part I Background Information

Main Differences Between MSP430 and LC-3

  • The MSP430 has a larger assembly instruction set than the LC-3

    • MSP430 assembly includes some task specific instructions (Such as inc and dec) to simplify reading the language
    • Some MSP430 assembly instructions are interpreted instructions (Such as pop and push)
      Definition 1: Interpreted Instructions
      An instruction that is decomposed by the assembler into several smaller/ more basic fundamental instructions.
      Example

      pop R3 contains two implicit instructions: mov @SP, R3 and add #0x02, SP

  • Math and logical instructions are similar, but do not have a specific destination.

    • MSP430 instructions come in two flavors, dual operand and single operand. Neither type has an explicit destination register, rather, the last operand serves as the destination too.
    • For Example: add R4, R5 in MSP430 assembly corresponds to add R5, R4, R5 in LC-3
    • Warning:
      Be careful to not overwrite data you wish to keep! If you need to preserve the values in both operand registers, you will need to save one of them first using a mov instruction.
  • MSP430 Supports some byte as well as word instructions

    • Some MSP430 instructions allow you to address and write/read from a specific 8 bit byte in memory instead of the entire 16 bit word. The MSP430 memory has byte level addressability, but word instructions only operate on even numbered memory addresses (implicitly modifying the next odd numbered memory byte too). In many cases, especially when working with memory mapped I/O registers, you may need to operate on one specific byte only. To do so, just add a .b onto the end of the assembly instruction
    • For example: mov.b #0, &P1DIR sets 8 bit length P1DIR register to zero without accidentally modifying the registers around it.
    • Aside:
      MSP430 assembly specifies .w for executing word length instructions as well as .b for bit length instructions. The assembler by default assumes word length, so you the programmer don't have to explicitly write mov.w R5, R14 although you should be conscious that mov R5, R14 means the same thing.
  • The MSP430 has 16 CPU registers

    • The MSP430 has twice as many CPU registers as the LC-3. Like in the LC-3 though, some of the MSP430's registers are reserved for the MSP430 runtime environment. Registers R0-R3 are reserved (Program Counter, Stack Pointer, Status Register, and a Constant Generation Register respectively), leaving registers R4 through R15 available for general purpose use as defined by the programmer.
    • In your assembly programs you have 12 general purpose registers at your disposal, but you also must manage and keep track of the additional options.
  • Indirect, relative, and absolute addressing occurs differently

    • Instead of different indirect and direct load and store instructions (LD, LEA, LDI, etc...), the MSP430 uses one versatile mov instruction with different operand addressing modes.
    • mov can both read and write from memory-- it acts like both a load and store. (mov R4, &0x0200 corresponds to a ST while mov &0x0200, R4 corresponds to a LD)
    • Indirect references occur using different operation syntax.
      • Direct register access: Rn (where n is the number of a general purpose register) Example: R4 refers directly to R4
      • Immediate Values: #x (where X is an immediate numerical value or label) Example: #02h refers to the literal hex number 2
      • Indirect Access From a Register: @Rn (where n is the number of a general purpose register) Example: @R6 refers indirectly to the data stored in the memory location in R6
      • Indirect Offset Access: x(Rn) (where n is the number of a general purpose register and x is either an literal offset or a label) Example: 0(R7) refers to the data stored in the location in memory pointed to by R7
        Note:
        This has the same end result as @R7. By TI code convention though, @Rn cannot be used to specify the destination of an operation, so if you wish to store a result indirectly, you must use the 0(Rn) syntax.
        Tip:
        In this example R7 essentially contained the address while the literal offset was a small number. Offset Access can be very powerful when looked at the other way: where the literal contains a starting location in memory (potentially a label) and the register contains a small offset value incremented to access a series of locations in memory.
    • You can also perform indirect or relative operand addressing with operations other than loads and stores
      Example 1

      add @R4, R5 takes the data stored in the address pointed to by R4 and adds it with R5, storing the result in R5.

    • For more information, see the summary chart Figure 1 or the comprehensive MSP430 users guide section 3.3.0 through 3.3.7
  • The MSP430 has two types of memory

    • The MSP430 has both traditional RAM and non-volatile Flash memory. On a power reset, all values in RAM are cleared, so your program will be stored in Flash. Flash is comparatively slow to write though, so it essentially cannot be written during run-time. Your program must store any temporary values to RAM memory, although it can read any preset constants from flash
    • Important Memory Locations:
      • 0x0200 : The Lowest Address in RAM
      • 0x0280 : The Highest Address in RAM
      • 0xF800 : The Beginning of Flash Memory
      • 0xFFE0 : The Beginning of the Interrupt Vector Table

Example Code Translations

Table 1
LC-3 Assembly LC-3 Pseudocode MSP430 Assembly MSP430 Pseudocode
  • AND R4,R5,R6;
  • R4 <- R5 & R6
  • mov.w R5,R4;
  • and.w R6,R4;
  • R4 <- R5
  • R4 <- R4 & R6
  • BRz R4,Loop;
  • if R4 == 0, branch to label "Loop"
  • tst R4;
  • jz Loop;
  • load the attributes of R4 into the SR
  • jump to label "Loop" if the zero bit is flagged

Helpful Reference Diagrams

Figure 1
MSP430 Addressing Modes
modes chart
Figure 2
MSP430 Architecture Block Diagram
MSP430 Von Neumann Architecture Block Diagram
Figure 3: Important Memory Locations: 0x0200 The Bottom of RAM | 0x0280 The Top of RAM | 0xF800 The Start of Flash Memory
MSP430 Memory Map
MSP430 Memory Map
Figure 4
MSP430 Register Usage Diagram
MSP430 Register Diagram

Other Useful Information

The code composer debugger actually runs on the real MSP430 hardware through a JTAG interface. To debug code, you have to have the launchpad board plugged into the computer.

The debugger controls the CPU's clock (and therefore can monitor it). To see how many clock cycles something takes, go to Target -> Clock -> Enable, and look in the bottom right corner of the screen for a small counter with a clock next to it.

Part I Assignment Detail

Your task is to create a simple MSP430 assembly program using CCS4 and the MSP430 launchPad to calculate a Fibonacci sequence. You do not need to explicitly display the sequence, but rather use the Code Composer register view tools to watch the sequence progress as you step through your program.

Definition 2: The Fibonacci Sequence
The sequence of numbers starting with 0 , 1 in which N= (N-1) + (N-2)

0, 1, 1, 2, 3, 5, 8, 13, 21, 34...

Aside:

The Fibonacci sequence plays an important role in the natural world. It appears in many biological sequences, and is fundamentally linked to the famed "golden ratio." For more "fun" info about Leonardo Fibonacci, see the ever reliable Wikipedia

Part II Background

GPIO

Philosophy

  • The MSP430 uses GPIO pins that are assignable to several functions depending on your specific model. Our version, the MSP430G2231 can have the pins act as digital output, digital input, or ADC input.
  • The pins are organized into ports, with each port usually one byte (8 bits/pins) wide. On larger versions of the processor you can encounter several ports, but in this lab you will only be using P1
  • You can set each pin's function independently (input or output). Since we want to do both, we will divide P1 into half inputs and half outputs as needed.

Usage

  • The I/O ports are memory mapped into the top of the MSP430 address space.
  • There are several registers associated with each port. For now, you only need to worry about four (P1IN, P1OUT, P1DIR, and P1REN).
    P1IN
    • The P1IN register is located at address 0x0020 in memory, which you can also refer to using the C symbol &P1IN
    • The register holds the values the MSP430 sees at each pin, regardless of the pin direction setting.
    • To read the register, use a mov.b instruction to avoid accidentally reading adjacent registers
    • Tip:
      If you are looking to test or read just the pins set to input, you will have to mask the P1IN register to zero out the other unwanted/output pins.
    P1OUT
    • The P1OUT register is located at address 0x0021 in memory, which you can also refer to using the C symbol &P1OUT
    • If their direction bits in P1DIR are set to output/ "1", the corresponding pins will output the values set in P1OUT.
    • If a pin's direction bits are set to input in P1DIR and its resistors are enabled in P1REN, P1OUT controls the pin's connection to the pull-up resistor. Setting P1OUT to "1" enables the pull-up, while setting it to "0" leaves the input to float in a high impedance state.
    • To set P1OUT, use a mov.b instruction to set several pins at once. To set individual bits to "1", you can use an or.b instruction with a "1" in the positions you want to set. To clear individual bits/ set them to zero, use an and.b instruction with mostly "1"s except for a "0" for the bits you want to clear.
    P1DIR
    • The P1DIR register is located at address 0x0022 in memory, which you can also refer to using the C symbol &P1DIR
    • The value of the bits in P1DIR determines whether the MSP430 hardware leaves the pin in a high impedance state where it responds to external voltage changes (which you can read at P1IN), or in a low impedance state where the MSP430 drives the output voltage to a certain value determined by P1OUT.
    • To set the bit directions all at once, use a mov.b instruction, but to change individual bits regardless of the others, use an and.b or an or.b
    • Set the corresponding bits to "0" to set pins to input mode, or to "1" to set them to output mode.
    P1REN
    • The P1REN register is located at address 0x0027 in memory, which you can also refer to using the C symbol &P1REN
    • P1REN controls whether the MSP430 Launchpad enables the integrated pull-up resistor for a given pin.
    • The pull-up resistors allow the use of single pole switches. They prevent the input signals from floating randomly while the switches are open by loosely tying the inputs to Vcc. When the switch is closed though, the much stronger connection to ground wins out, pulling the inputs down to GND.
    • Set the corresponding bits to "1" to enable a pin's pull-up resistor, or to "0" to disable it (disabled by default).

Polling

Philosophy

  • A traditional single threaded polling scheme consists of a main loop that runs continuously. Within that loop, the processor periodically checks for changes, and if there are none, continues looping. Once a change is detected, the program moves to a new section of code or calls a new subroutine to deal with the changes.
  • Polling has advantages and disadvantages-- it keeps program execution linear and is very easy to code and implement, but it also is not incredibly responsive. Since polling only checks values at certain points in the main run loop, if the loop is long or changes occur quickly, a polling scheme can miss input data. For now though it will suffice.

Part II Assignment Detail

Your task is to code a simple input to output echo program for the MSP430. Your program should consist of:

  • A setup section that runs once and configures the GPIO pins
  • A main loop that runs infinitely
  • Code inside your loop to read the state of the GPIO input pins and test if it has changed
  • A separate section of code to write the changes to the output pins and then return to the main loop

Tip: Masking:

You should already know the basics of masking from class, but it becomes very important when dealing with I/O. Since different pins do different things in the same port (P1), you the programmer will have to be careful not to accidentally modify the wrong bits even though your instructions will operate on the entire register.

Wrapup

Congratulations on completing lab 3! You have learned a lot about how to write assembly code for the MSP430 so far, and have completed two successful programs. Don't forget what you learned about debugging, MSP430 assembly, GPIO, looping, and polling. It will come in handy later!

Diagrams courtesy of TI document slau144e "MSP430 User's Guide"

Content actions

Download module as:

Add module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks