circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

April 2005, Issue 177

Simple USB Data Acquisition


EMBEDDED SOFTWARE

Before writing actual LPC2138 application code, the device needs to be set up after it’s powered on. Fortunately, most IDEs will either set this up for you or provide some kind of boot assembly code to handle the task. For this particular project, I used the evaluation version (16-KB code size limitation) of the Keil µVision3 environment. I was pleasantly surprised with its boot-up implementation. The graphical configuration wizard allows you to modify the proper setup registers for your application. This made the boot and start-up process transparent and allowed me to focus on the application itself. 

Let’s look at the LPC2138’s PLL setup as an example. To change the PLL multiplier value on the LPC2138, you must perform a few extra steps after writing the new multiplier and control values to the PLLCFG and PLLCON registers. These steps entail writing 0xAA and then 0x55 to the PLL feed register (PLLFEED). This action loads the PLL control and configuration information from the PLLCON and PLLCFG registers into the shadow registers that actually affect PLL operation. It’s basically a good way to prevent accidental changing of the PLL value. This code implementation is taken care of with the provided boot code in µVision3. Punching in the desired multiplier in the GUI automatically updates the boot code. I learned this the hard way in a different IDE when designing with the LPC2106. The point is that using the graphical configuration tool is an easy and fast way to set up the microcontroller so you can start working on your application. 

Now that the boot up code is taken care of, let’s concentrate on the main application. I chose C language over the native ARM assembly language to write the driver and application code. So, the next step involved writing a C code driver for a timer interrupt, an A/D scan, and the UART. Fortunately, the example C code that came with the µVision3 IDE had examples for all the peripherals. I modified and used them. 

The code for each peripheral was extremely straightforward and easy to understand and integrate. Creating the application code, including the C code for each peripheral, resulted in the code shown in Listing 1. In this code a timer match interrupt occurs from the interval timer, and then the AIN-1 A/D channel is read to sample the analog output voltage from the LM60 temperature sensor. The analog temperature data is then masked because only 10 bits are valid because of the 10-bit A/D resolution. Now the reading is ready to be sent out the serial port via the UART through the printf statement. Listing 1 is all the code you need to read the LM60 temperature sensor every few minutes and send the raw ASCII-converted A/D result out of the serial port.

You must download code to the board and begin debugging at this point. I used the ULINK JTAG debugger, which integrates nicely with the Keil µVision3 IDE. The debugger connects to the MCB2130 debug connector and communicates directly with the ARM7 core inside the LPC2138 via its EmbeddedICE logic (see Photo 1).

The typical debug options are available in µVision3. Single stepping, watch windows, break points, and memory snooping are all possible with the LPC2138. An interesting item in the µVision3 IDE is the ability to interact with LPC2138 peripherals while the program is idle. A separate GUI can be opened for the various LPC2138 peripherals that allows for interaction and control of them. Things like manually scanning the LPC2138’s A/D converter and flipping of one of its GPIO bits are possible. A couple of the windows are shown in Photo 2. This is a good way to get to know some of the peripherals and their associated registers on the LPC2138. Given all these features, I quickly downloaded code to the board, ran it, and debugged it.

(Click here to enlarge)

Photo 2—The debug peripheral windows in the Keil debugger were useful when I was experimenting with the ADC and GPIO port bits. They enabled me to scan the ADC for the analog temperature value prior to connecting up the GUI and to alter the state of the GPIO bits at will. This eliminated the need for writing special test code.