Вы находитесь на странице: 1из 238

Version 1.0

RMIT University, Melbourne, Australia

OPEN USB USER GUIDE

An Introduction to Embedded C Programming and OUSB Command line

Authors

Troy Boswell

Peter Radcliffe

Heiko Rudolph

4/20/2010

Table of Contents

Introduction

4

Chapter 1 - OUSB Command Line

5

1. Downloading the OUSB Command Line Interface

5

2. Preparing a Windows PC for the OUSB Command Line Interface

6

3. Preparing a Linux PC for the OUSB Command Line Interface

9

4. Preparing an RMIT Linux Live-DVD for the OUSB Command Line Interface

9

5. Testing the OUSB Development Board Testing the Atmega32 Input/Output (IO) Pins

10

11

Testing the Atmega32 Analogue to Digital Conversion (ADC)

12

Testing the Atmega32 Pulse Width Modulation (PWM)

13

6. Command Line Interface Directives IO Command Line Directives

14

17

PWM Command Line Directives

19

ADC Command Line Directives

21

7. Introduction to Combining Command Line Directives

22

8. Combining Command Line Directives in Batch script files (Windows users)

22

9. Combining Command Line Directives in BASH script files (Linux users)

24

10.

Bash scripts mini projects (Linux Only) LED BOUNCE

28

28

LED READ DIP SWITCH

29

LED READ TRIM PORT

30

LED PWM READ DIP SWITCH

31

LED PWM READ TRIM POT

32

USART

33

11.

Creating C++ programs that interact with the OUSB Command line interface

34

12.

C++ driven OUSB command line mini projects LED_BOUNCE

47

47

LED READ DIP SWITCH

48

LED READ TRIM PORT

49

LED PWM READ DIP SWITCH

50

LED PWM READ TRIM POT

51

USART

52

Chapter 2 Preparing For Embedded C

54

1. Do You Really Need To Complete This Chapter

54

2. What you need and where to get it

55

3. Preparing a Windows PC

55

4. Preparing a Linux PC

55

5. Developing your first Embedded C program in Eclipse

60

6. Loading your first program into Atmega 32 on the OUSB development board

70

Using STK-200

70

Using the an USBasp Programmer

76

Installing USBasp on a 64 bit Windows OS

76

Using the AVR ISP mkII Programmer

84

Installing AVR ISP mkII on 32 bit and 64 bit Windows OS

84

How to Restore The OUSB Firmware

94

Chapter 3 C Programming for the Atmega32

102

1. Introduction to embedded C programming

102

2. Bitwise manipulation

102

Bitwise operators

102

Shifting Bits

104

Bit Manipulation

105

LED Toggle an Atmega32 Code using Bit Manipulation

107

3. State machines in C

108

4. Atmega32 peripherals

112

Interrupts

112

External Interrupts

115

Reset Interrupt

118

IO Ports

119

Watch Dog Timer

121

Timers/Counters

125

Analogue Peripherals

152

USART

158

5. Mini Projects

168

LED BOUNCE

168

LED READ DIP SWITCH

169

LED READ TRIM PORT

170

PWM READ DIP SWITCH

171

PWM READ TRIM POT

172

USART

173

Annex A

Eclipse Installation For Windows

174

Annex B

Eclipse Help For Linux

210

Annex C

OUSB Schematic Diagram

212

Annex D

Atmega32 Registers “iom32.h”

213

ANNEX E Windows XP Setup for STK 200

227

References

237

Introduction

Welcome to the Open USB (OUSB) user manual, this manual is designed to introduce you to the OUSB development board and will demonstrate how to use the development board in either a Windows or Linux environment.

The OUSB project is a current project running at RMIT Melbourne and is designed to provide students with a low cost method of learning real skills in embedded programming and hardware interfacing. It was developed by Dr P J Radcliffe and it is powered by a versatile microcontroller, the Atmega 32. Currently the project has developed the board and a command line program that operates in Linux and Windows. This command line interface allows you to directly access the Atmega 32 through predefined commands, as you progress through this manual we will start out with basic tasks commanded by the command line interface (command line interfaces are covered in chapter 1) to build your basic knowledge and to get you performing measurable tasks immediately. Once you have explored the command line interface it is then time to move onto more advanced topics such as creating C/C++ programs that drive the OUSB command line interface, and finally to the stage where you can create real embedded programs in C and upload them into the Atmega 32 to perform the tasks we performed with the simpler command line interface.

The Atmega 32 has many built-in peripherals and this manual will teach you how to use most of them, including, universal synchronous and asynchronous receiver-transmitter (USART) for serial communications, parallel input/output ports, analogue to digital converters, timers and pulse width modulators.

Upon completion of this manual you will have a real insight into the workings of embedded c programming with an Atmega microcontroller and once you are finished will be in no way limited to just having to use an Atmega 32, but you will be able to apply your knowledge to program an Atmega microcontroller supported by the AVR-GCC standard.

Chapter 1 - OUSB Command Line

Prerequisites

A PC running either a Linux or Windows (XP, Vista, 7) OS and a spare USB port.

An OUSB Development Board with the OUSB firmware loaded (comes preloaded)

Understand basic operations of your operating system (save, create, move and find, files and folders)

Access to the internet

Linux users may also find it advantageous if they know some basic BASH programming

Obtain a standard USB - AB cable

Able to convert 8 bits of data between decimal, binary and hexadecimal.

1. Downloading the OUSB Command Line Interface

The OUSB command line interface is an executable program and can be downloaded from the sources listed below. What you will be downloading is the appropriate zipped folder for your operating system (OS), when extracted contains the command line interface program that we are going to use for the remainder of this chapter.

that we are going to use for the remainder of this chapter. Figure 1. 1 To

Figure 1. 1

To download this executable click the download link below the appropriate file for your OS (there are two versions for each platform, with CO USB and without CO USB) as shown above in figure 1.1, you will be asked whether you wish to open or save this file, select save, and save it to your desktop.

o

Source 1 OUSB Users Manual Google site, file page http://sites.google.com/site/openusbboard/file-cabinet

o

Source 2 OUSB Users Manual Google site, Chapter 1 (bottom of page)

2.

Preparing a Windows PC for the OUSB Command Line Interface

To prepare a Windows PC for the command line interface, it is a relatively simple task of extracting the downloaded zipped folder into the default directory pointed to by your command prompt.

To find this directory lets open command prompt by clicking on start > run and then typing „cmd‟ into the open window. Once you have done this command prompt will open and it is just a matter of interpreting what directory your command prompt uses by default.

NOTE: Windows 7 does not have run you will need to type 'cmd' into the search bar after clicking on start.

From figure 1.2 you can see that the default directory of my Windows XP machine is C drive, the folder Documents and Settings then folder Troy which is written as C:\ Documents and Settings\Troy in command prompt.

as C:\ Documents and Settings\Troy in command prompt. Figure 1. 2 So let us investigate this

Figure 1. 2

So let us investigate this further by opening my computer (just computer for Windows 7) by clicking on start > my computer > C drive > Documents and Settings > Troy. You are now at your command prompts default directory.

Our next step is to extract the ousbexe_os.zip folder that you had previously downloaded into this default directory. The simplest way of executing this is to right click on the ousbexe_os.zip on your desktop and select Extract All… as displayed in figure 1.3.

Figure 1. 3 Once the extraction wizard starts, select Next and you will be prompted

Figure 1. 3

Once the extraction wizard starts, select Next and you will be prompted to select the destination of your extraction. As displayed in figure 1.4 click on Browse and expand Local Disk (C:) until you reach your default directory and click OK. Now that you have selected your default directory as the destination, back in the extraction wizard window click Next to extract the file, after the file is extracted, finally click finish.

window click Next to extract the file, after the file is extracted, finally click finish .

Figure 1. 4

Now that we have downloaded and extracted the ousb.exe file to the default directory, our final step in preparing a Windows PC for the OUSB command line interface is to test the program opens successfully.

Follow the these steps to test the OUSB command line interface

1. open command prompt

2. Type ousb in the command prompt window

3. Press enter

4. You should observer the same output in command prompt as displayed in figure 1.5

5. If you did not get a result similar to that in figure 1.5, redo this section.

a result similar to that in figure 1.5, redo this section. Figure 1. 5 You may

Figure 1. 5

You may now delete the zipped folder containing the ousb.exe file from your desktop if you wish.

3.

Preparing a Linux PC for the OUSB Command Line Interface

Preparing a Linux installation for the OUSB command line is very similar to that of Windows except for the fact that Linux uses a different file structure, so where you store the ousb.exe file is different. For a Linux installation the ousb.exe file should be stored at the directory /usr/local/bin as displayed in figure 1.6, and ensuring the execute permissions are set, you will need root access to complete this.

are set, you will need root access to complete this . Figure 1. 6 Finally we

Figure 1. 6

Finally we need to test that the OUSB command line is working, we do this by opening a terminal, menu > system > terminals>terminal, and type ousb into the terminal screen and press enter, the OUSB options window should be displayed as seen in figure 1.5.

4. Preparing an RMIT Linux Live-DVD for the OUSB Command Line Interface

Preparation of the OUSB Linux Live-DVD is unnecessary as the Linux environment is already set up with the OUSB command line configured. To test the OUSB command line, open a terminal, menu > system > terminals>Konsole - Terminal Program and type ousb into the terminal and press enter; the terminal should output the result as displayed in figure 1.5.

5.

Testing the OUSB Development Board

Now that you have successfully installed the OUSB executable it is now time to connect the OUSB development board to a spare USB port of your PC using an A to B USB cable (links provided in prerequisites). The OUSB development board does not need any specialized drivers; you can just connect the board to your PC. For those running Vista or Windows 7, the operating system may display a warning that you have plugged in an unrecognized device, this is standard for the OUSB development board and there is no need to be concerned about this message. Once you have attached the board to the USB port you should notice that the power LED lights up, the power LED is located next to the 8 dip switches in the corner of the board as indicated in figure 1.7.

8 Dip Switches Power LED Connected to Port C LED’s Connected to Port B Atmega
8 Dip Switches
Power LED
Connected to Port C
LED’s Connected to
Port B
Atmega 32
Reset Button

Figure 1. 7

Now that your board connected and the OUSB executable is correctly installed we can test the board to ensure the OUSB firmware is installed on the Atmega32.

Before conducting the following tests ensure that J10 is shorted and that all of the dip switches are in the on state as indicated by the dip switches packaging, these are both indicated in figure 1.8.

All dip switches on J10
All dip switches on
J10

Figure 1. 8

To perform these tests open command prompt on a Windows platforms or open a terminal on a Linux platforms. Type the following OUSB commands into the terminal screen and compare their results with the expected terminal responses found in figure 1.10, physical results of the commands which can be seen on the OUSB development board that are described under each of the commands.

NOTE: The basic tests that you are about to undertake are not too designed to test the full capability of the OUSB development board but to just perform a few basic operations of the board and to provide you with a base level introduction. I strongly advise that you have a copy of the OUSB schematic available (ANNEX C) while performing these tests so that you can identify the devices connected the Atmega32.

Testing the Atmega32 Input/Output (IO) Pins

IO executes commands on the parallel interfaces of the Atmega32. There are four ports on the Atmega32 and each has the capability of being configured as an IO port, however because the OUSB development board uses PORTD to perform special functions it should not be used for IO applications when using the OUSB command line.

Please note that I am using hexadecimal input values, you the user can input these values in either decimal or binary. I believe you should stick with hexadecimal, as it allows you to think in four bits at a time and proves more efficient when working with 8 bits, which commonly occurs when using a device like the Atmega32 which uses 8 bits to describe register values, pin states and port states.

ousb io PORTB 0xFF

The effect of this command is to set PORTB of the Atmega32 to hex 0xFF, since each port of the Atmega32 has 8 pins, 0xFF represents all 8 pins becoming active, as you may have noticed the 8 LED‟s on the OUSB development board have light up, therefore you can deduce the 8 LED‟s are connected to PORTB of the Atmega32.

ousb io PORTB

This command has no effect on the board itself, but it reads the state of the output pins of PORTB.

ousb io PORTB 0x0F

Now you have set PORTB so that the first four LED‟s will light up and the last four LED‟s will turn off, this is done by making PORTB the hex value of 0x0F and can be proved by converting the value to binary, which is simply 0b 0000 1111.

ousb io PORTB 0xF0

Similar to the previous command, we now set PORTB so that the last four LED‟s will light up and the first four LED‟s will turn off, this is done by making PORTB the hex value of 0xF0 and can be proved by converting the value to binary, which is simply 0b 1111 0000.

ousb io PINC

Now that we know that PORTB is connect to the LED‟s and are set to output, let us explore PORTC. PORTC on the Atmega32 is set for input, therefore to read the input value of the dip switches we use the command ousb io PINC. As you may notice the result of this command is zero, but all of the dip switches are on, this it because not logic in employed, therefore when the switch is on, zero volts is present on PORTC for a particular pin you have set to on, resulting in that pin being off, and vice versa. Therefore turning all switches on results in a decimal value of zero.

Testing the Atmega32 Analogue to Digital Conversion (ADC)

The tests that we perform for the ADC will retrieve the current analogue value of the Light Dependent Resistor (LDR) and the current analogue value of the Trim Pot in digital form, therefore performing an analogue to digital conversion. Both of these components can be found in figure 1.9.

Trim Pot Light Dependent Resistor
Trim Pot
Light Dependent Resistor

Figure 1. 9

ousb adc 6

This command retrieves the digital value of the LDR and displays its result as a 10-bit binary value, or in the range of zero to 1023. Therefore exposing the LDR to light will decrease its value and hiding it from light will increase its value. (Your result may not match the value in figure 1.10)

ousb adc 5

The other ADC that we test is the trim pot, this is simply a 10K ohm variable resistor with 5 volts on one side and ground on the other, the ADC reads the tapped of value of the pot, this value can be adjusted by adjusting the tap position with a screw driver. (Your result may not match the value in figure 1.10)

Testing the Atmega32 Pulse Width Modulation (PWM)

PWM is an operation performed by specific pins of the Atmega32 to output a square wave with a constant or varying duty cycle. Note we will be only testing PWM 1 which is located at pin 4 of the Atmega32, or LED 3 attached to PORTB and will vary the brightness of the LED attached.

ousb pwm-freq 1 1000

The Atmega32 can only achieve certain frequencies that depend on its input clock; therefore this command asks the Atmega32 to set PWM 1 to a frequency near 1000 Hz.

ousb pwm 1 10

We now will start off with a very dim LED at PORTB pin 3 by setting the duty cycle to 10%.

ousb pwm 1 50

The same LED will now become brighter by setting the duty cycle to 50%.

ousb pwm 1 100

Finally we have set the LED to its maximum brightness by setting the duty cycle to 100%.

ousb pwm 1 0

Finally we have set the LED to its minimum brightness to allow the PWM to be turned off.

Figure 1. 10 6. Command Line Interface Directives The figure 1.11 displays the command line

Figure 1. 10

6. Command Line Interface Directives

The figure 1.11 displays the command line directives, there are many more advanced directive that call interrupts and registers, which fall into the final box of the io branch. These will not be discussed in this chapter, but will be introduced in chapter 3 using the C programming language.

ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb

ousb

ousb - Prints help information
ousb - Prints help information
- Prints help information

- Prints help information

ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb - Prints help information
ousb - Prints help information pwm adc - set PWM - reads the adc pin value
ousb - Prints help information pwm adc - set PWM - reads the adc pin value
pwm adc - set PWM - reads the adc pin value ‘Value’ -freq - reads
pwm
adc
- set PWM
- reads the adc pin value
‘Value’
-freq
- reads the digital
- set PWM frequency
value of the
- must be set prior to
selected ADC
using PWM
‘Value’
-
select which PWM
- 1,2, or 3
1=OC0 PB3, pin 4
1=OC1A PD5, pin 19
1=OC1B PD4, pin 18
‘Value’
- desired frequency
- actually frequency
will be closest
available
‘Value’
- select which PWM
-
1,2, or 3
1=OC0 PB3, pin 4
1=OC1A PD5, pin 19
1=OC1B PD4, pin 18
‘Value’
- set duty cycle
io - set io registers DDRx - set io port x as an input or
io
- set io registers
DDRx
-
set io port x as
an input or output
- x is the port
identifier,
a, b, c or d.
‘Value’
- convert decimal to 8
bit binary or hex
-
pin = 0 pin =input
-pin =1 pin =output
PORTx
-
x is the port
identifier,
a, b, c or d.
-When port is
output, acts as a
write command
-
when port is
input, sets input to
pull up mode or
high z mode
‘Value’
- sets the output
port pins
PINx
- read port value
- use when port is
an input
-
x is the port
identifier,
a, b, c or d.
Atmega32
Register values.
Can be found in
data sheet,
Advanced users
only

ousb -multi

- connects multiple

commands for a single

exectution

‘commands’

quit

- ousb is not needed for

individual commands

- terminates on quit.

Figure 1. 11

The remainder of this section will be dedicated to explaining figure 1.11 and demonstrating how it can be used to perform specific commands on the Atmega32.

Before starting we must cover the base options first, the base options determine to what base a value will be returned to the command line, please read the following which is and extract from the Open-USB-IO Reference manual.

Base options: any ousb command that results in an output can have a base option put Immediately after the ousb command-

No option: decimal

-b : print output in binary

-h : print output in hexadecimal

-r : just print the decimal value without other text, useful for script files

Therefore using the base options in your OUSB command line directives you can create useful actions with the Atmega32 which can output to real hardware and return a value in many different formats to software, thus making life simpler when working with the OUSB development board and its command line interface.

Examples of base options:

ousb io PORTB 0x55

This command will return a result in form of the no option format, which is simply the decimal value of hexadecimal 0x55, which is 85 and therefore the result is PORTB = 85.

ousb b io PORTB 0x55

This command will return a result in binary format, which is the binary value of hexadecimal 0x55, which is 0b01010101 and therefore the result is PORTB = 0b01010101.

ousb h io PORTB 0x55

This command will return a result in hexadecimal format, which is simply the input 0x55, therefore the output is PORTB = 0x55.

ousb r io PORTB 0x55

This command will return a result in decimal format without the preceding string, which is the just decimal 85.

To understand how we can modify the conditions of each port, first you must understand the power up conditions of the OUSB development board and what individual pins cannot be accessed as they perform special functions, such as USB communications or RS-232 communications. In addition to the previous the Atmega32 also has limitations, where only certain ports and pins can perform certain functions, this information will be briefly described but detailed information can be found in the Atmega32‟s datasheet.

The power up state information is provided in the table below and describes that PORTA is initially setup for ADC conversions, PORTB is setup for IO output, PORTC is setup for IO sensing or input and PORTD has very limited availability due to its connections to hardware on the OUSB development board and therefore is not recommended to be changed.

board and therefore is not recommended to be changed. IO Command Line Directives If you observe

IO Command Line Directives

If you observe the first branch of figure 1.11 you will notice that only io commands are available. So what is io? io stands for input/output and it is exactly just that, you can set any of the four ports of the Atmega32 so that they are either all input, all outputs or a combination of both, as stated PORTD should not be modified using OUSB commands as it provides special functionality on the OUSB development board. DDRx in the io branch stands for Data Direction Register, and its value for a specific port determines whether that port is an input, an output or a combination.

For example:

To change DDRB so that all pins are inputs rather that an output we would type:

ousb io DDRB 0x00

To change DDRB back so that all pins are outputs rather that an input we would type:

ousb io DDRB 0xFF

To change DDRB so that the first four pins are outputs and the last four pins input we would type:

ousb io DDRB 0xF0

Now that we have seen how to set the io state of a port let us explore further down the tree to PORTx. This command has different functions depending on whether the port is set as an output or input. Let us investigate its implementation when the port is an output.

When a port is set as an output, the PORTx command acts as a write function, writing to the value to a given IO port described in the command. For example:

Set an output port such that the first and last pins are high and the rest are low, you would type:

ousb io PORTB 0x81

Set an output port such that the first pin is high and every second pin after that is high (or every red LED on the OUSB development board) you would type:

ousb io PORTB 0x55

However when the port is set to input the PORTx command performs an entirely different function than the write command described above. Input ports have an additional configuration option where the port can be put in a high impedance state or in a pull up mode. To enable the input port to read applied voltages we must set the input port to the pull up mode. For example:

Set up an input port such that it is in the high impedance state, you would type:

ousb io PORTC 0x00

Set up an input port such that it is in the pull up mode, you would type (this is the setting typically used):

ousb io PORTC 0xFF

The final io command discussed in the chapter is the PINx command, for an io port this command is considered to be the read command, and reads the current state of the pins of a port whether it is configured as an output or input. Since PORTB is configured as an output and PORTC is configured as an input we can use the PINx command to find the current states of both. For example:

Find the current state of PORTB, note this will be 85 because of your last write command to PORTB, hence 85 is decimal for hexadecimal 0x55.

ousb io PINB

Find the current state of PORTC, the result of this command depends entirely on the state of the dip switches, as you will notice, on the OUSB development board the dip switches are labeled 0 to 7, set them to any combination and determine the decimal value of the dip switches, and compare your expected result with actual result.

ousb io PINC

Was your expected result correct? If not, remember on is LOW and off is HIGH.

NOTE: the DDRA command can interfere with ADC operations, so before any executing any ADC operations either reset the board or set DDRA back to all inputs.

PWM Command Line Directives

The PWM is a significant device; it is relatively simple in the fact that it is just a square wave of which you have the ability to change its duty cycle at any point in time by the means of sending a simple command. However the practical uses of the PWM are more complicated and are beyond the scope of this manual, but by filtering the output of the PWM you can capture the time average of the PWM signal; hence create a digital to analogue conversion. This manual demonstrates the PWM by applying the square wave produced to an LED, resulting in a time averaging of the PWM signal through the LED which is physical shown by the light intensity of the LED. If the duty cycle of the PWM is 100% the LED will be bright because the LED is constantly on, however if the duty cycle is reduced to 50%, then the LED will be dulled because for half of the period of the PWM signal applied to the LED will be in an off state.

Before we can use the PWM with the command line we must first set the PWM frequency. Referring back to figure 1.11, in the PWM branch you can see the first command is pwmfreq (no space). This is the command that sets the PWM frequency. This frequency is totally dependent on the PWM used and the clock speed of the Atmega32, because the OUSB development board uses a clock of 12MHz his frequency is partly dependent on 12MHz. The following provides the available PWM frequencies available on the OUSB development board.

PWM 1, located at PORTB 3, pin 4 The available frequencies are very limited and any command line input will round to its nearest available frequency. (Values provided for PWM 1 are approximate and may differ on each board)

PWM

1 , PB3 , pin 4

Lowest Available Freq

47.7 Hz

 

183.1

Hz

 

732.4

Hz

 

5859.4 Hz

Highest Available Freq

46875 Hz

PWM 2, located at PORTD 5, pin 19 The available frequencies for this PWM differ dramatically from PWM 1 proving it more capable. PWM 2 has a frequency range from 183 Hz to 3 MHz, however not every precise frequency is available due the Atmega32 being a digital device, however the device will round to the nearest possible value that it can obtain. Typically very close if not exactly the frequency that you have requested.

PWM 3, located at PORTD 4, pin18 This is exactly the same as PWM 2 and has a frequency range of 183 Hz to 3 MHz.

Examples of setting the PWM frequency:

Setting PWM 1 to 47.7 Hz

ousb pwm-freq 1 47

Setting the frequency of the PWM is all you have to do for the PWM to become active, now set the desired duty cycle of the PWM and you will have a working PWM.

Example of using PWM 1:

Since we have configured PWM 1 to run at 47 Hz we can now turn the LED on at PORTB 3 by setting PWM 1 to 100% duty cycle:

ousb pwm 1 100

We can now dim the light by setting the duty cycle to a value lower than 100%, for effect lets set it to 25%

ousb pwm 1 25

By visual inspecting LED 3 you may be able to visually detect the light flicking; this is due to the duty cycle causing the light to turn on and off every period.

To deactivate the PWM so that it can be used for io operations we need to set the PWM to zero duty cycle.

ousb PWM 1 0

ADC Command Line Directives

ADC command accesses the Analog to Digital capability of the Atmega32 that is available on PORTA. As stated by the name it simply takes an analogue input and converts it to a digital value.

Because the Atmega32 is a digital device it can only read analogue values between 0 volts to 5 volts. Therefore it has a voltage range of 5 volts and is quantized or approximated into 1024 levels, thus making level 1023 approximately 5 volts and level 0 approximately 0 volts.

To determine the voltage resolution or difference between each level we can use the following formula:

NOTE: any input over 5 volts will result in the input being saturated and record as a 5 volt input or 1023.

For the OUSB development board two ADC are connected to provide ADC functionality without having to configure any hardware, making ADC implementation simple. These pre-fitted ADC devices are a trim pot connected to ADC 5 and a Light Dependent Resistor (LDR) fitted to ADC 6. Find them on the schematic diagram (Annex C), you will see that one side is VCC (5v) and the other is 0v, providing a voltage range of 5 volts. This means that these ADC devices have the capability of providing ADC inputs from level 0 to level 1023.

As for the OUSB ADC command line directives they provide read functionality to the user to read the digital value of an analogue input at any point in time.

Examples of ADC 5 and ADC 6:

ADC 5 is connected to the trim pot and is located in the centre of the OUSB development board. The digital value of the trim pot can be adjusted by simply turning the pot; you will notice turning the pot fully clockwise will generate an ADC output of 1023, or 5 volts. While turning the pot fully anti-clockwise will result in the ADC output of 0, or 0 volts.

ousb ADC 5

An LDR is a resistor whose value is proportional to the amount of light it is receiving. Therefore exposing the LDR to a bright light will result in the voltage sensed by the ADC to be low. Obviously exposing the OUSB development board to a dark environment (note LED‟s will effect reading) the voltage sensed by the ADC will increase, resulting in a values close to 1023.

ousb ADC 6

NOTE: the DDRA 0xFF command effects the operation of the ADC, this is either overcome by setting the PORTA pins need for ADC to input mode, or simply reset the board as a reset will set the board up for ADC operations.

7. Introduction to Combining Command Line Directives

The remaining branch in figure 1.11 is a method of executing multiple OUSB command line directives in one command.

-multi The multi command is relatively simple, it is declared and followed by multiple commands that are to be executed and is terminated by the keyword quit.

Example of multi:

ousb multi io PORTB 0x55 io PORTB 0xFF io PORTB 0x00 quit

Results in:

PORTB = 85 PORTB = 255 PORTB = 0

Multiple commands may be effective, but there is simply a better way, and that is by using script files. However script files in windows are rather limited and are called Batch files. Those using Linux are luckier as Linux provides a script file language called BASH script. BASH script will allow you to test conditional statements and perform loops similar to that of the C language.

8. Combining Command Line Directives in Batch script files (Windows users)

Batch files are very simple, by the fact that you simply create a text file full of command with notepad, and save the file with the batch file association .bat. This now tells a Windows PC that this is a file of commands to be executed in the command line.

Since the functionality of batch files is limited this manual will only display one example of how these types of files can be used with the OUSB command line interface.

The example that we will demonstrate teaches you how to combine the tests that we performed early in section 5 of this chapter to create a simple test batch file for the OUSB development board.

First let‟s direct a window to the command lines default directory that we found in section 2. Note: my default directory on my windows XP system is C:\Documents and Setting\ Troy.

Next right click on this window and select New>Text File as shown in figure 1.12 and open it.

Figure 1. 12 Now type the following commands into the new text document: ousb io

Figure 1. 12

Now type the following commands into the new text document:

ousb io PORTB 0xFF

ousb io PORTB

ousb io PORTB 0x0F

ousb io PORTB 0xF0

ousb io PINC

ousb adc 6

ousb adc 5

ousb pwm-freq 1 1000

ousb pwm 1 10

ousb pwm 1 50

ousb pwm 1 100

ousb pwm 1 0

We are now ready to convert this text file into a batch file, to do this we select File>Save As, and save the file as ousbtest.bat.

You should now see an icon similar to one of those displayed in figure 1.13 (left is an XP icon the right is a Windows 7 icon). Now to test the OUSB development board ensure that it is connected by a USB cable to your PC, open command prompt then type „ousbtest‟ into the command prompt window and press enter. You should get the same results as in figure 1.10.

enter. You should get the same results as in figure 1.10. Figure 1. 13 9. Combining

Figure 1. 13

should get the same results as in figure 1.10. Figure 1. 13 9. Combining Command Line

9. Combining Command Line Directives in BASH script files (Linux users)

BASH scripts are a method of combining command line directives in a file that is executable by a terminal. BASH can be a very powerful tool for executing command line statements, because BASH provides loop, conditional statements and variables, which means that you can create a script that will execute commands a lot quicker than actually having to type every individual command. However there is a downside to them, which is that the BASH language doesn‟t provide any significant means of error checking or fault indication, thus making it not an entirely simple language to use.

This section should be treated as an overview on BASH script programming and an introduction of how you can incorporate its use with OUSB command line directives, to create small yet efficient programs.

The following link provides a very basic introduction if you wish to learn some BASH programming before we develop some short and simple BASH scripts. http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html

Before we start our first BASH script we must cover some basics:

The first line must begin with „#!/bin/bash‟.

The OUSB command line must be located in „/usr/local/bin‟.

It is helpful to use „set –u‟ which will ensure variables are not auto declared.

Variables have no data type

Variables are declared by name then assignment operator, „var_name=‟

To use a variable in a statement you must use the $ operator, „$var_name‟

The „echo‟ command outputs to the terminal echo “hello World”.

To start off with let us group the tests that we performed in section 5, so that we can automate our previous tests in a simple executable BASH script.

Go to /home/user/Documents, or any other convenient directory where you have RWX permission on your Linux installation. This manual will demonstrate BASH script files using the directory /home/user/Documents. Right click and create a new text file and name it ousbtest as demonstrated in figure 1.14.

file and name it ousbtest as demonstrated in figure 1.14. Figure 1. 14 You now need

Figure 1. 14

You now need to set permission, right click on the file you just creates and select properties from the drop list, once the properties window appears select the Permissions tab and set the Is Executable box and the click Ok, as shown in figure 1.15.

Permissions tab and set the Is Executable box and the click Ok, as shown in figure

Figure 1. 15

Permissions tab and set the Is Executable box and the click Ok, as shown in figure

25 | P a g e

Before we can start our BASH script you need to open the text file, to do this simply right click on the ousbtest file from the drop list select Open With > KWrite. You are now ready to develop your first BASH script. Next type the following into the text file:

#!/bin/bash ousb io PORTB 0xFF

ousb io PORTB

ousb io PORTB 0x0F

ousb io PORTB 0xF0

ousb io PINC

ousb adc 6

ousb adc 5

ousb pwm-freq 1 1000

ousb pwm 1 10

ousb pwm 1 50

ousb pwm 1 100

ousb pwm 1 0

Now form the directory where your ousbtest file lives, /home/user/Documents, press F4 and bring up a terminal and type ./ousbtest. The reason why we need the „./‟ before our file is to let the terminal know to find the ousbtest file in our current directory.

Your terminal response should look like the result in figure 1.16.

Figure 1. 16 Now that you have created a very simple but effective BASH script,

Figure 1. 16

Now that you have created a very simple but effective BASH script, the next section will provide some more capable example of the use of BASH script programming with the OUSB command line.

10. Bash scripts mini projects (Linux Only)

LED BOUNCE

#!/bin/bash

#----- stop auto declaration of variables. set -u #----- LED Bounce, ctrl-C to stop.

Delay=0.01

# Forever Loop

until

[ 0 != 0 ]

do

 

For loop to control forward bounce for i in 1 2 4 8 16 32 64 128 do

#

ousb io PORTB $i

echo "

LED Output = $i"

sleep $Delay

done

For loop to control backward bounce for i in 64 32 16 8 4 do

#

ousb io PORTB $i

echo "

LED Output = $i"

sleep $Delay

done

done

LED READ DIP SWITCH

#!/bin/bash

set -u

#------ Read the Dip Switches and write to the LEDs. Write=

until

[

0

!= 0

]

do

 

sleep 0.01

 

#

read the dipswitch

Write=$(ousb io pinc)

write the dipswitch value to the LEDs let "Write = Write" ousb io PORTB $Write

#

done

LED READ TRIM PORT

#!/bin/bash

set -u

#------ Read the Trimpot and write to the LEDs. Write=

# Forever Loop

until

[

0

!= 0

]

do

 

sleep 0.01

 

Read the Trimpot value Write=$(ousb adc 5)

#

Write the Trimpot value to the LEDs let "Write = Write/4" ousb io PORTB $Write

#

done

LED PWM READ DIP SWITCH

#!/bin/bash

set -u

#------ Read the Dip Switches and write to the PWM. Write= x=

# Setup PWM 1

ousb io portb 0 ousb pwm-freq 1 45

# Forever Loop

until

[

0

!= 0

]

do

 

sleep 0.01

 

#

Read the Dip Switches

Write=$(ousb io pinc) let "x = Write"

#

Perform a float mathematical operation

to convert the dip switch value to a percentage Write=$(echo "scale=3; ($x / 255)*100" | bc)

#

Write the dip switch value to PWM 1 ousb pwm 1 $Write

#

done

LED PWM READ TRIM POT

#!/bin/bash

set -u

#------ Read the Trimpot and write to PWM. Write= x=

# Setup PWM 1

ousb io portb 0 ousb pwm-freq 1 45

# Forever loop

until

[

0

!= 0

]

do

 

sleep 0.01

 

#

Read the trimpot

Write=$(ousb adc 5) let "x = Write"

#

Perform a float mathematical operation

to convert the dip switch value to a percentage Write=$(echo "scale=3; ($x / 1023)*100" | bc)

#

write the trimpot value to PWM1 ousb pwm 1 $Write

#

done

USART

#!/bin/bash

set -u

#------ Initialize ports and the uart. DDRD=$(ousb -r io DDRD)

let "DDRD = (DDRD & 0xFE) | 2" ousb io DDRD $DDRD

# TX to output, RX to input.

ousb io UBRRL 75 UCSRB=$(ousb -r io UCSRB) let "UCSRB = UCSRB | 0x18" ousb io UCSRB $UCSRB

# baud rate to 9600 baud.

# Enable TX and RX.

#------ Loop to receive, add one, and transmit back.

while

[

0 == 0

]

do

#--- wait for RX of byte.

UCSRA=0

while [ $UCSRA == 0 ] do

UCSRA=$(ousb -r io UCSRA) let "UCSRA = UCSRA & 0x80" done #--- get received byte, incr, and send. UDR=$(ousb -r io UDR) let "UDR = UDR + 1" ousb io UDR $UDR

done

11.Creating C++ programs that interact with the OUSB Command line interface

Congratulations on making it to the final topic in chapter one, this section will focus on how you can create C++ programs that will run on a host desktop and control the OUSB development board to perform useful commands by running an executable program. This method of programming can be highly effective as C++ is a more capable programming language than those previously covered, as the C++ standard ensures that certain tests are carried out during the compilation of executables which makes mistakes easier to find and correct.

I strongly recommend you install the Eclipse IDE as this is the IDE that the manual was created for and all codes have be written specifically for this IDE. The Eclipse C/C++ IDE is available in both Linux and Windows, for Windows users the installation information needed is available in ANNEX A. Unfortunately for Linux users because RMIT provides a LIVE-DVD of PC Linux OS 2009 with Eclipse installed and setup, only some general information is located in ANNEX B to assist existing Linux users. Those Linux users using the RMIT LIVE-DVD as previously stated are lucky enough to have the Eclipse IDE already installed and ready to go, it is located at Menu>More Applications>Development>Development Environments>Eclipse.

Before we get into programming we first need to discuss some fundamental information that will allow your C++ programs to access the command line interface. These fundamental are pipes, system calls, sprint() and fgets().

PIPES

A

pipe is a method of outputting or inputting via a command, rather than the stand methods of outputting

to

a terminal or inputting from the key board. Pipes are referred to as uni-directional, therefore a single

pipe call must be read-only or write-only, never both. The read only operation seems odd at first, because

if you execute a command for the OUSB command line interface, by definition, for read only you would

expect a result to be returned by the function with no action. This is not the case, if you open a pipe, in read-only mode you will actually execute a command and whatever the return result from that command

will then be buffered into your program and no output will be sent to the standard output. If we use this information to describe the write-only pipe, the write-only pipe will write a command and will expect no return value from the OUSB development board, however the board will always respond to a command. So since this response cannot be returned to the write-only pipe, it must be returned to the standard output, or command line, resulting in an unexpected result on the command line. As you can see, read- only or write-only pipes both do the same job, I recommend using write-only pipes for testing and read- only pipes for final development so that only important information is returned to the command line.

How do you create a pipe? All the headers needed to create pipes belong in:

#include <iostream>

Pipes work with FILE pointers; therefore we must declare a FILE pointer first:

FILE *fp;

Now that we have our FILE pointer we can now use it with the popen() function:

fp = popen("command as a string","read or write option");

As you can see, you need to enter your command as a string, therefore “C:\\ousb io PORTB”, as you know this is the command to read the value of the LED port of the Atmega32, but notice how C drive is called, this is telling the program to look in directory C for the ousb.exe. Why have I used C drive (This is a Windows only problem) and not C:\\Documents and Settings\Troy\. The simple answer is because I could not get it to work. I recommend you copy and paste the ousb.exe file to your C: drive for use with C++ code, or you may have difficulty accessing the command line interface (Windows users only). Linux users simply have to enter the desired OUSB command line directive as a string and the operation will execute with no need to address a specific directory location.

Notice the second string is the read-only or write-only option:

Read-only is selected by the string

- “r”

Write-only is selected by the string

- “w”

Note: The read and write string are very particular and are not characters, but a string in double quotation marks.

Directly after the pipe has been used it must be closed, if you do not close your pipes and to many become open due to iterative processes you risk vulnerability and your program could possibly crash. So once you are finished with your pipe ensure you close it.

pclose(fp);

System calls System calls are a much easier method of sending OUSB command line directives to the board; however they are much slower and provide no option to suppress the OUSB returned value.

As you would expect, the method to call them is very simple, a string is used exactly the same way as in the popen() command, where Windows users must assign the path of the ousb.exe file and Linux users need only specify the command. This string is placed in the parameter list of the system() function.

system("command as a string");

system() simply writes the command to a terminal and executes the command as though it were just typed in.

FGETS Fgets is a function that takes the returned value of a stream and stores the value in a character string. For your use, fgets will take the returned value of a read-only popen() operation and store the stream value in a character array.

fgets(char_array, sizeof char_array, fp);

The following implements this using the pipes return value of the command ousb io PORTB 0xFF, where the return value is buffered into a character array which is then outputted to the standard output via the program. REMEMBER Linux users do not use C:\\, it is for windows users only.

#include <iostream> using namespace std;

int main()

{

char char_array[100]; FILE *fp; fp = popen("C:\\ousb io PORTB 0xFF","r"); fgets(char_array, sizeof char_array, fp); pclose(fp);

cout<<char_array<<endl;

return 0;

}

SPRINTF This function is very similar to printf, in that it creates a formatted output, except printf outputs to the standard output and sprintf outputs to a string.

The standard form of sprint is:

sprintf(output, "string + tags", input1, input2);

Where „output‟ is a character array large enough to hold the result of the string at the second parameter and all of the appended inputs, together combine to create one formatted character array.

The second parameter for sprintf is a string that may contain formatting flags. The formatting flags are signified in a string by a preceding percentage symbol. Below is a list of some available formatting options.

Symbol

Formats

%c

Character

%d or %i

Signed decimal integer

%e

Scientific notation with lower case e

%E

Scientific notation with upper case E

integer %e Scientific notation with lower case e %E Scientific notation with upper case E 36

36 | P a g e

%f

floating point

%g

Use the shorter of %e or %f

%G

Use the shorter of %E or %f

%o

Signed octal

%s

String of characters

%u

Unsigned decimal integer

%x

Unsigned hexadecimal integer

%X

Unsigned hexadecimal integer (capital letters)

The final parameters are the inputs that relate to the formatting flags in the second parameter, these input data types need to match the assigned formatting flags previously described. The inputs need to be in the correct order and quantity as you describe in the string of the second parameter.

Below is an example of formating a character array called „output‟ with a string and an integer. This formatted array is then used in a write-only pipe which writes the command ousb io PORTB 255 and will get the result PORTB = 255 returned. Again note Linux users must not add C:\\.

#include <iostream> using namespace std;

int main()

{

char output[100]; char char_input[100] = "C:\\ousb io PORTB "; int val_input = 255;

sprintf(output, "%s%d", char_input, val_input); FILE *fp; fp = popen(output,"w"); pclose(fp);

return 0;

}

Now that you have been introduced to some methods of accessing to the OUSB command line directives via C++ programming, it is now time to introduce you to the Eclipse IDE and how to configure the IDE so that you can create C++ programs. Please take note of the minor differences between the Linux version and the Windows version of Eclipse, they are only minor but all of the following is performed in Windows, however I clearly note the differences by the use of, LINUX USERS.

ALSO NOTE THAT I HAVE RECOGNISED A REOCURRING PROBLEM WITH THE EXECUTABLE BECOMING LOCKED UP, WHICH CAUSES AN ERROR WHERE YOU CANNOT BUILD YOUR PROJECT. IF THIS OCCURS SIMPLY SELECT PROJECT FROM THE TOOLBAR, AND FROM THE DROP LIST SELECT CLEAN TO DELETE ALL FILES AND REBUILD.

1. Open Eclipse

a. Linux, menu> More Applications>Development>Development Environments>eclipse

b. Windows, by the shortcut that has been created on the desktop.

2. You may be presented with a warning in Windows asking if you wish to open this program, if you accept the warning click the appropriate button the proceed.

3. You will then be asked to create a workspace, in Eclipse a workspace is a directory you would like to work from. This workspace will be created if it does not exist, and if you select an existing workspace Eclipse will load any existing projects in that workspace. However for now just select ok, this is displayed in figure 1.17.

LINUX USERS: note that your directory structure for the default workspace is /home/user/workspace.

USERS : note that your directory structure for the default workspace is /home/user/workspace. Figure 1. 17

Figure 1. 17

4.

Your first action in developing your program is to open a new C++ project. This is done by selecting File > New > C++ Project, as shown in the figure below, figure 1.18.

LINUX USERS: note that your welcome page looks different, but the actions are the same.

1.18. LINUX USERS: note that your welcome page looks different, but the actions are the same.

Figure 1. 18

5.

Your next step is to name the new project as LED_Write and select the project as an Executable C++ project as shown in figure 1.19. By selecting the Hello World C++ Project the compiler will automatically insert the standard header and namespace. Once this is done select Next.

header and namespace. Once this is done select Next. Figure 1. 19 6. The next screen

Figure 1. 19

6. The next screen will allow you to add some comments to your code that will be assigned by the IDE. When you are happy with your comments select Next.

7. Finally before the project is created by Eclipse you need to select whether you wish to create Debug and Release versions. Both selected is fine, make your choice and select Finish.

8.

This will differ between users depending on what steps you have been taken, but you may be at the Eclipse welcome window displayed in figure 1.20, if you are simply click on the workbench icon circled in red.

LINUX USERS: note that your welcome page looks different, but the actions are the same.

red. LINUX USERS: note that your welcome page looks different, but the actions are the same.

Figure 1. 20

9. You should now be at the workbench and in the right hand side of the workbench you will see the project explorer tab. In this tab you will see the LED_Write project folder that you have just created, expand the project folder to LED_Write > src > LED_Write.cpp, now double click on LED_Write.cpp to open the source file in the text window of Eclipse, as shown in figure 1.21.

file in the text window of Eclipse, as shown in figure 1.21. Figure 1. 21 10.

Figure 1. 21

10. Note: for Windows users ensure that you have the ousb.exe file located in your C drive, and Linux users remember not to add any reference to the C drive before any OUSB command line directives or you will have errors in compilation.

11. I recommend that you set the following project preferences so that the project will auto save before building each time; I have found that I have to do this every time I open Eclipse as it does not auto save many of your preference options. This can be done by selecting Window > Preferences from the menu bar, then expand General >Workspace, you should then tick the third option down which is Save automatically before build as shown in figure 1.22.

Figure 1. 22 12. Another preference you may be interested in is turning on line

Figure 1. 22

12. Another preference you may be interested in is turning on line numbers, this can be done again by selecting Window > Preferences from the menu bar however the line numbers option is found by expanding General > Editors > Text Editor, form there select the fourth option down as shown in figure 1.23.

Editors > Text Editor, form there select the fourth option down as shown in figure 1.23.

Figure 1. 23

13.

Now that the environment is setup lets create a C++ program that will write to the LED port of the Atmega32, PORTB from user inputs.

14. The following C++ code program was developed as an introduction; feel free to modify it, as it has several problems, mainly in the form of error checking the input. LINUX USERS: note that in #define OUSB that the file path is incorrect, you need to remove the C:\\ when creating your code in Linux.

#include <iostream> using namespace std; #define INPUT_SIZE 4 #define OUTPUT_SIZE 100 #define MAX 255 #define MIN 0 #define OUSB "C:\\ousb io PORTB " int main()

{

 

FILE *fp; char input[INPUT_SIZE]; char output[OUTPUT_SIZE]; int test;

while(1)

{

cout<<"Input a value between zero and 255, q to quit:"<<endl; cin>>input;

if(input[0]== 'q')

{

cout<<"Bye"<<endl; return 0;

}

test = atoi(input); if(test < MIN || test > MAX)

{

cout<<"Input Error"<<endl; continue;

}

sprintf(output, "%s%s", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

return 0;

}

What does this program do? To start off with we set numerous constants using #define statements, which defines the sizes of the input character array, the output character array, test parameters and lastly the string to be used with sprint() to create our OUSB command line directive to be used in a pipe. The operation of this program resides in a forever loop and outputs a user input to the program to the OUSB development board‟s LED‟s.

15. Once you have typed the code into the text window of the IDE, you are ready to build your program. To do this, you need to highlight the LED_Write folder in the project explorer tab, and then click on the Hammer icon to build your program. Finally any errors will be flagged in the problems tab below the text editor window. This all can be seen in figure 1.24.

flagged in the problems tab below the text editor window. This all can be seen in

Figure 1. 24

16. The final step in creating your program is to test it; this can be done directly from the IDE by clicking on the Run icon, which is signified by the play symbol on a green circle. Once the Run button has been pressed the IDE will respond by changing the tab below the text editor to the Console tab. In this console tab will display exactly what would be seen in any terminal window if you were to run you program in a terminal. You can now place the cursor in the Console tab and type in your desired user input between zero and 255, and see it displayed on the LED‟s of the OUSB development board.

between zero and 255, and see it displayed on the LED ‟s of the OUSB development

Figure 1. 25

12.C++ driven OUSB command line mini projects

LED_BOUNCE

#include <iostream> #include <unistd.h>

using namespace std;

// Hash Define Constants #define OUSB "C:\\ousb io PORTB " #define DELAY 500 #define OUTPUT_SIZE 100

// Global Variable char output[OUTPUT_SIZE];

// PORT B Write Function // This function writes the integer value input // to the LEDs of the OUSB Board void PORTB_WRITE(int input)

{

FILE *fp; sprintf(output, "%s%d", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

int main()

{

int i = 0;

// Initialise the counter

while(1)

// Forever Loop

{

// Bounce the LEDs forwards for(i = 1; i <= 128; i=i*2)

{

 

PORTB_WRITE(i);

usleep(DELAY);

}

// Bounce the LEDs backwards for( i = 64; i > 1; i -= i/2)

{

 

PORTB_WRITE(i);

usleep(DELAY);

}

}

return 0;

}

LED READ DIP SWITCH

#include <iostream> using namespace std;

// Hash Define Constants #define OUSB "C:\\ousb io PORTB " #define OUTPUT_SIZE 100

// Global Variable char output[OUTPUT_SIZE];

// PORT B Write Function // This function writes the integer value // to output to the LEDs of the OUSB Board void PORTB_WRITE(int input)

{

FILE *fp; sprintf(output, "%s%d", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

// PORT C Read Function // This function reads the integer value input // on the dipswitches of the OUSB Board int PORTC_READ()

{

FILE *fp; int value; char PORTC_VAL[4]; fp = popen("C:\\ousb -r io pinc","r"); fgets(PORTC_VAL, sizeof PORTC_VAL, fp);

value = atoi(PORTC_VAL);

pclose(fp);

return value;

}

int main()

{

// Buffer, transfers read data to write data int data;

while(1)

// Forever Loop

{

data = PORTC_READ(); PORTB_WRITE(data);

}

return 0;

}

LED READ TRIM PORT

#include <iostream> using namespace std;

// Hash Define Constants #define OUSB "C:\\ousb io PORTB " #define OUTPUT_SIZE 100

// Global Variable char output[OUTPUT_SIZE];

// PORT B Write Function // This function writes the integer value // to output to the LEDs of the OUSB Board void PORTB_WRITE(int input)

{

FILE *fp; sprintf(output, "%s%d", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

// Read ADC 5 Function // This function reads the 10 bit value // of ADC 5 which is connected to the Trimpot double TRIMPOT_READ()

{

FILE *fp; int value; char TRIMPOT_VAL[5]; fp = popen("C:\\ousb -r adc 5","r"); fgets(TRIMPOT_VAL, sizeof TRIMPOT_VAL, fp);

value = atoi(TRIMPOT_VAL);

pclose(fp);

return value*0.2493;

// convert 10 bits to 8 bits

}

int main()

{

// Buffer, transfers read data to write data int data;

while(1)

// Forever Loop

{

data = (int)TRIMPOT_READ(); PORTB_WRITE(data);

}

return 0;

}

LED PWM READ DIP SWITCH

#include <iostream> using namespace std;

// Hash Define Constants #define OUSB "C:\\ousb PWM 1 " #define OUTPUT_SIZE 100

// Global Variable char output[OUTPUT_SIZE];

// Write PWM Function // This function writes a percentage of the // dipswitches turned on to the PWM void PWM_WRITE(int input)

{

FILE *fp; sprintf(output, "%s%d", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

// PORT C Read Function // This function reads the integer value input // on the dipswitches of the OUSB Board int PORTC_READ()

{

FILE *fp; int value; char PORTC_VAL[4]; fp = popen("C:\\ousb -r io pinc","r"); fgets(PORTC_VAL, sizeof PORTC_VAL, fp);

value = atoi(PORTC_VAL);

pclose(fp); return value*0.39; // Reduce 8 bit value to a percentage of 8 bits

}

int main()

{

// Buffer, transfers read data to write data int data;

// Initialise the PWM system("ousb pwm-freq 1 1000");

while(1)

// Forever Loop

{

data = PORTC_READ(); PWM_WRITE(data);

}

return 0;

}

LED PWM READ TRIM POT

#include <iostream> using namespace std;

// Hash Define Constants #define OUSB "C:\\ousb PWM 1 " #define OUTPUT_SIZE 100

// Global Variable char output[OUTPUT_SIZE];

// Write PWM Function // This function writes a percentage of the // Trimpot to the PWM void PWM_WRITE(int input)

{

FILE *fp; sprintf(output, "%s%d", OUSB , input); fp = popen(output,"w"); pclose(fp);

}

// Read ADC 5 Function // This function reads the 10 bit value // of ADC 5 which is connected to the Trimpot double TRIMPOT_READ()

{

FILE *fp; int value; char TRIMPOT_VAL[5]; fp = popen("C:\\ousb -r adc 5","r"); fgets(TRIMPOT_VAL, sizeof TRIMPOT_VAL, fp);

value = atoi(TRIMPOT_VAL);

pclose(fp);

return (value*0.2493)*0.3922;

}

int main()

{

// Buffer, transfers read data to write data int data; // Initialise the PWM system("C:\\ousb pwm-freq 1 50");

while(1)

// Forever Loop

{

data = (int)TRIMPOT_READ(); PWM_WRITE(data);

}

return 0;

}

USART

#include <iostream> using namespace std;

// Hash Define Constants #define OUTPUT_SIZE 100

// Global Variables int UCSRA; int TX_DATA; int RX_DATA; char UCSRA_char[5]; char RX_char[5]; char output[OUTPUT_SIZE]; FILE *fp;

// Initialise USART void init()

{

 

int value; char DDRD[5]; char UCSRB[5];

// Activate Transmit and Receive fp = popen("C:\\ousb -r io DDRD","r"); fgets(DDRD, sizeof DDRD, fp); value = atoi(DDRD); value = (value & 0xFE) | 2; pclose(fp);

sprintf(output, "%s%d", "C:\\ousb io DDRD " , value); fp = popen(output,"w"); pclose(fp);

fp = popen("C:\\ousb -r io UCSRB","r"); fgets(UCSRB, sizeof UCSRB, fp); value = atoi(UCSRB); value |= 0x18 ; pclose(fp);

sprintf(output, "%s%d", "C:\\ousb io UCSRB " , value); fp = popen(output,"w"); pclose(fp);

// Set the Baud rate to 9600, note 8-N-1 is set by default sprintf(output, "%s%d", "C:\\ousb io UBRRL " , 75); fp = popen(output,"w"); pclose(fp);

}

int main()

{

while(1)

// Forever Loop

{

UCSRA = 0;

// Initialise the UCSRA buffer

// Wait for received data while(UCSRA == 0)

{

fp = popen("C:\\ousb -r io UCSRA","r"); fgets(UCSRA_char, sizeof UCSRA_char, fp); UCSRA = atoi(UCSRA_char); UCSRA &= 0x80; pclose(fp);

}

// Receive the incoming data fp = popen("C:\\ousb -r io UDR","r"); fgets(RX_char, sizeof RX_char, fp); RX_DATA = atoi(RX_char); pclose(fp);

// Add one to the received value to // increment to the next ascii value TX_DATA = RX_DATA + 1;

// Transmit the modified received data sprintf(output, "%s%d", "C:\\ousb io UDR " , TX_DATA); fp = popen(output,"w"); pclose(fp);

}

return 0;

}

Chapter 2 Preparing For Embedded C

Prerequisites

A PC running either a Linux or Windows (XP, Vista, 7) OS and a spare USB port.

An OUSB Development Board with the OUSB firmware loaded (comes preloaded)

Understand basic operations of your operating system (save, create, move and find, files and folders)

If you wish to learn how to upload your code to the Atmega32 independent of the OUSB command line, you will need either an STK 200 cable, USBasp programmer or AVRISP mkII programmer.

Access to the internet

1. Do You Really Need To Complete This Chapter

This chapter is designed for those who wish to learn how to program an Atmel chip with their own unique program. This will not be using the OUSB Firmware, this section will introduce you how to develop your own standalone firmware, compile it and upload it to the Atmel chip, in this case it is the Atmega32 onboard your OUSB Development Board. The method shown could be applied to any Atmel chip supported by the AVR-GCC project.

Details on the supports chips can be found at the following link:

PLEASE BE AWARE THIS IS NOT THE CO-USB FEATURE OF THE OUSB FIRMWARE. This manual will not be covering the CO-USB feature as it is explained in detail by Dr PJ Radcliffe in the Open-USB-IO Reference manual which can be found at:

So it is now time to decide how you wish to create your programs for your Atmega32, do you wish to use the CO-USB feature, if so use the link above and familarise yourself with CO-USB, then you can move on to chapter 3 which will introduce you to embedded programming for the Atmega32.

If you wish to learn how to make standalone programs without relying on the OUSB firmware then read on, we will be removing the OUSB firmware, but we will also cover how to restore the firmware as well.

2.

What you need and where to get it

This manual will utilize the Eclipse IDE for embedded programming. The Eclipse IDE is open source software that is very versatile and is available in either Windows or Linux versions; both versions use the AVR-GCC complier. It should be noted that Eclipse has different installation requirements for Windows and Linux, but once the installation is complete, navigation and use of the IDE in either operating systems is relatively similar. Finally Eclipse is a self contained program; that is it does not require installation as it runs directly from the downloaded folder and stores its data to a folder called workspace.

3. Preparing a Windows PC

If you are running a Windows platform you need to install the Eclipse C/C++ IDE in accordance with Annex A. Please ensure you install the software correctly and in the order shown as it is important so that the IDE can recognize all needed software components.

4. Preparing a Linux PC

Linux install is not fully supported in this manual, this is because RMIT uses a LIVE -DVD which is setup with Eclipse installed, if you are not a strong Linux user, it is highly recommended you use the LIVE -DVD or install Linux PC OS 2009 from the LIVE -DVD, as this will save you a considerable amount of setup time.

If you are an existing Linux user and wish to install Eclipse by yourself Annex B provides useful websites and screen shots from the Eclipse help menu to instruct you on what you need to do.

All Linux Users Please Read the Following about Adding AVR-GCC Libraries to Your Project

The Linux version recommended to use has a problem when creating and AVR-GCC project. There is a work around but it means you need to remember the following procedure when creating such a project. The problem is that the AVR -GCC libraries do not get included into the project automatically as you may be used to, so we need to add them. The following procedure is a step through that you will have to apply later in this chapter, for the time being read to following to understand what you need to do so that the needed libraries get added to your project. This procedure assumes you are using the LIVE-DVD or an installation from. Once you have created a new AVR-GCC project you will notice that you will only have a folder created with no source files or libraries. For this example I have created the AVR -GCC project LED_Bounce. We will highlight the project folder in the project explorer tab as seen in figure 2.1.

We will highlight the project folder in the project explorer tab as seen in figure 2.1.

Figure 2. 1

Next select Project>Properties, from the properties window expand C/C++ Build > Settings, once at Build setting select AVR Assembler > General from the list as shown in figure 2.2 and click the include paths, Add icon.

shown in figure 2.2 and click the include paths, Add icon . Figure 2. 2 You

Figure 2. 2

You will then be asked to enter the directory path, this can be found via the file system, click file system, File system (in the places column) >usr>local>avr>avr>include and then click Ok. An even simpler method is to type /usr/local/avr/avr/include as the directory this is shown in figure 2.3 and then click Ok.

/usr/local/avr/avr/include as the directory this is shown in figure 2.3 and then click Ok . Figure

Figure 2. 3

/usr/local/avr/avr/include as the directory this is shown in figure 2.3 and then click Ok . Figure

57 | P a g e

The path should now be visible in the include path window as shown in figure 2.4, now click Apply then Ok.

now be visible in the include path window as shown in figure 2.4, now click Apply

Figure 2. 4

You should now be able to expand the LED_Bounce project folder in the Project Explorer tab and see the Includes visible as seen in figure 2.5.

tab and see the Includes visible as seen in figure 2.5. Figure 2. 5 The remainder

Figure 2. 5

The remainder for developing the LED_Bounce project is covered in the next section.

5.

Developing your first Embedded C program in Eclipse

This section will take you through the development of your first Embedded C program, as you progress through this section you will notice differences between embedded programming and standard desktop programming. You will use different standard library, the need to set registers and your program will be design to never terminate as there is no operating system to fall back on.

For the development of this program we will now go through step by step the configuration of an Eclipse AVR-GCC project much like we did before starting C++ programming. Again I will denote the differences between the Linux version and Windows version of Eclipse by LINUX USERS, as once again the following was written from actions on a Windows machine.

1. Open Eclipse

a. Linux, menu>More Applications>Development>Development Environments>eclipse

b. Windows, by the shortcut that has been creates on the desktop.

2. You may be presented with a warning in Windows asking if you wish to open this program, if you accept the warning click the appropriate button the proceed.

3. You will then be asked to create a workspace, in Eclipse a workspace is simply to a directory you would like to work from. This workspace will be created if it doesn‟t exist, and if you select and existing workspace Eclipse will load any existing projects in that workspace. However for now just select ok, as seen in figure 2.6.

LINUX USERS: note that your directory structure for the default workspace is /home/user/workspace.

USERS : note that your directory structure for the default workspace is /home/user/workspace. Figure 2. 6

Figure 2. 6

4.

Our first action in developing our program is to open a new C project. This is done by selecting File>New>C Project, as shown in figure 2.7.

File>New>C Project, as shown in figure 2.7 . Figure 2. 7 5. Our next step is

Figure 2. 7

5. Our next step is to name our new project as LED_Bounce and the select our project as an AVR Cross Target Application as shown in figure 2.8. By selecting the Empty Project the compiler will automatically insert the standard header and namespace. Once this is done select Next.

LINUX USERS: note that for your list you can only chose the AVR Cross Target Application and not the Empty Project template, this is what I believe is cause the Linux AVR -GCC include issues

NOTE: All users must be aware that when naming an AVR -GCC project the name must not contain any spaces or you will not be able to compile your project.

Figure 2. 8 6. The next screen will allow you to select whether you wish

Figure 2. 8

6. The next screen will allow you to select whether you wish to create Debug and Release versions. For AVR -GCC programs you must select both, make your choice and select Next.

7. The final selection that needs to be made is the AVR Target Hardware, by observing the OUSB schematic diagram you will notice that you are using an Atmega32 and it is running at 12 MHz (pin 12 and 13). Add these values into the selection boxes as shown in figure 2.9 and select Finish.

Figure 2. 9 8. This will differ between users depending on what steps you have

Figure 2. 9

8. This will differ between users depending on what steps you have taken, but you may be at the Eclipse welcome window as displayed in figure 2.10, if you are simply click on the workbench icon circled in red.

LINUX USERS: note that your welcome page looks different, but the actions are the same.

red. LINUX USERS: note that your welcome page looks different, but the actions are the same.

Figure 2. 10

9. I recommend that you set the project preferences so that the project will auto save before building each time; I have found that I have to do this every time I open Eclipse as it does not auto save many of your preference options. This can be done by selecting Window > Preferences from the menu bar, then expand General >Workspace, you should then tick the third option down which is Save automatically before build as shown in figure 2.11. In AVR-GCC projects if you do not save before your first build you will receive an error because no code exists to be compiled, as no code is auto created for you.

exists to be compiled, as no code is auto created for you. Figure 2. 11 10.

Figure 2. 11

10. Any other preference you may be interested in is turning on line numbers, this can be done by selecting Window > Preferences from the menu bar however the line numbers option is found by expanding General > Editors > Text Editor, from there select the fourth option down as shown in figure 2.12.

Editors > Text Editor, from there select the fourth option down as shown in figure 2.12.

Figure 2. 12

Editors > Text Editor, from there select the fourth option down as shown in figure 2.12.

64 | P a g e

11. In your workbench on the right hand side you will see the project explorer tab. Because the AVR -GCC part of the IDE is not as automated as the C++ executable projects you need to add your source file and for Linux users only, add the AVR-GCC libraries now.

12. Your first step is to highlight the project folder LED_Bounce in the project explorer tab; next you right click on our project folder and select New > Source File as seen in figure 2.13. The New Source File windows will now appear, type main.c for the name of the new source file as shown in figure 2.14 and select Finish.

type main.c for the name of the new source file as shown in figure 2.14 and

Figure 2. 13

Figure 2. 14 13. LINUX USERS: This next step is for Linux users only and

Figure 2. 14

13. LINUX USERS: This next step is for Linux users only and just recaps what was previously demonstrated to ensure that the AVR -GCC libraries are added correctly.

To add AVR -GCC libraries select Project>Properties, from the properties window expand C/C++ Build > Settings, once at build setting select AVR Assembler > General from the list, and click the include paths, Add icon.

You will then be asked to enter the directory path, type /usr/local/avr/avr/include as the directory and click Ok.

The path should now be visible in the include path window, click Apply then Ok.

You should now be able to expand the LED_Bounce project folder in the Project Explorer tab and see the Includes visible in the tab.

14. Now write the following program into the text editor of the IDE.

The following program is called bouncing LED‟s, as you may predict from the name the program makes the LED‟s bounce from one end to the other repetitively. Read the comments to obtain an understanding of the programs structure.

// AVR gcc standard library, provide iom32.h which know the basic commands for // the Atmega32 SEE ANNEX D. #include<avr/io.h>

// provides the header for _delay_ms() #include<util/delay.h>

// constant used to define the delay, in milli seconds #define delay 75

int main()

{

int i =0;

// Sets the Data Direction Register for PORTB so that all are outputs

DDRB = 0xFF;

// 1111 1111

// Sets the LSB of PORTB high. PORTB = 0x01;

/* we create our program in a forever loop so that the program will never exit, as exiting will cause the Atmega32 to hang until it is reset. Embedded programming is not like standard programming, it does not have an operating system to fall back on.

*/

while(1)

{

// for loops control our LED movements // start at 1 and move up in multiples of two, till we reach 128

for(i = 1 ; i<=128; i=i*2)

{

// Set PORTB to the New value of i PORTB = i; /* cause a delay so we can visually see the LED’s movement */ _delay_ms(delay);

}

// start at 64 and move down by divisions of two, till we reach 1 for(i=64 ; i>1; i -= i/2)

{

// Set PORTB to the New value of i PORTB = i; /* cause a delay so we can visually see the LED’s movement */ _delay_ms(delay);

}

}

}

return 0;

15. Now that the program is written into the IDE it is now time to build the program, select the LED_Bounce folder in the Project Explorer tab and click on the hammer icon to build. This time when you build the program you will notice a warning occurs but there are no errors in the Problems tab as shown in figure 2.16. Warnings give suggestions that you may not have done something correctly; the warning in figure 2.16 is fine. If you remember back to when we created this project, we created it with debug and release options selected. Let us now change our build to release by single clicking on the drop arrow of the build hammer, you will notice the option to select Debug or Release, select Release and re-build your program as shown in figure 2.15.

or Release, select Release and re-build your program as shown in figure 2.15. Figure 2. 15

Figure 2. 15

or Release, select Release and re-build your program as shown in figure 2.15. Figure 2. 15

Figure 2. 16

16. You will now notice that the warning has disappeared in the release build, that‟s not all that is different either, if you expand the Debug and Release folders in the Project Explorer tab you will see that the Release folder contains more objects, to add to that only the release folder holds the LED_Bounce.hex file which is the binary file that contains the program to be uploaded to the Atmega32 this can be seen in figure 2.17. So note that Debug can be useful for creating your programs but only Release can actually build the hex file needed.

be useful for creating your programs but only Release can actually build the hex file needed.

Figure 2. 17

17. Now that we have created and built our program we now have to upload this firmware to the

Atmega32.

6. Loading your first program into Atmega 32 on the OUSB development board

The section describes how to upload a microprocessor executable or hex file to the Atmega32 onboard the OUSB development board via the Eclipse IDE. However it should be noted that you will delete the OUSB firmware which on the Atmega32 but at the end of this section we will upload the firmware back onto the chip. There are three methods that will be demonstrated and you only need to configure one method, they are:

STK-200 cable

USB programmers

o

USBasp programmers

o

AVRISP mkII programmer

Be aware that this is different to loading a program via the CO-USB feature of the OUSB development board. This method is beneficial to learn as the following steps can be used to program any AVR (Atmel microcontroller) that is supported by the AVR -GCC standard, which may be useful if you wish to create projects without the OUSB development board or if you develop a specialized program where you need to use PORTD.

Using STK-200

Before commencing this section you will need a PC with a parallel port (DB 25 printer port).

STK 200 only works for Windows XP or earlier OS (Not Vista or Windows 7)

Windows XP users must setup parallel port IO as detailed in ANNEX E.

Linux users do not need to setup parallel IO as it is a standard feature of Linux OS.

You must create an STK 200 cable, schematic can be found at http://pjradcliffe.wordpress.com/open-usb-io/resources/

Parts for the STK 200 cable can be sourced from Jaycar or Futurlec online.

Before beginning the rest of this section the manual will assume that you have configured your parallel IO (Windows XP users), that you have correctly created your STK 200 cable and you have just built your code in release mode using the Eclipse IDE.

Once again you need to highlight your project folder in the Project Explorer tab, and then from the menu bar select project > properties, shown below in figure 2.18.

tab, and then from the menu bar select project > properties, shown below in figure 2.18.

Figure 2. 18

From the properties window expand AVR > AVRDude, and in the Programmer tab select New as displayed in figure 2.19.

AVR > AVRDude , and in the Programmer tab select New as displayed in figure 2.19.

Figure 2. 19

For your programmers configuration select STK 200 from the list and name this configuration as STK 200 as displayed in figure 2.20. Once you are satisfied with the configuration select Ok.

STK 200 as displayed in figure 2.20. Once you are satisfied with the configuration select Ok.

Figure 2. 20

Back in the properties windows ensure that the configuration that you have just created is selected, and then click Apply followed by Ok, shown below in figure 2.21.

just created is selected, and then click Apply followed by Ok, shown below in figure 2.21.

Figure 2. 21

Finally connect your STK 200 programming cable to the parallel port of your PC and the programming or ISP port of the OUSB development board, J7. Once you are connected press the AVR icon as shown in the figure 2.22 and observe the return message in the Console tab as it will inform you of any problems.

in the Console tab as it will inform you of any problems. Figure 2. 22 Note:

Figure 2. 22

Note: STK 200 cable holds the OUSB development board in a constant RESET state when the cable in plugged in, your code will only to begin to execute once the STK 200 cable is removed.

Using the an USBasp Programmer

This section requires a PC with a USB port.

A USBasp programmer that meets the specifications at the link http://www.fischl.de/usbasp/

If you wish to buy an USBasp AVR programmer you can purchase them from eBay for approximately $20.

You will need to install the driver for your USBasp, 32 bit systems should use the driver that comes with the programmer, or the one found at the above link, you may also use the 64 bit method except save the .inf file in the x86 folder.

If you are using a Windows 64 bit OS you will not be able to use the drivers mentioned above for the USBasp, as those drivers are unsigned.

LIVE-DVD users do not need the install any drivers as the required LibUSB driver is already installed; all you need to do is plug in your programmer.

Other Linux user will need to ensure LibUSB is installed, typically this is a part of the software installed for AVR-GCC, so if this environment is setup trying using your programmer first before installing LibUSB.

Installing USBasp on a 64 bit Windows OS

To install the USBasp on a 64 bit Windows OS you will need to download the zipped folder LibUSB- 64bit from the following link to the eclipse folder on your desktop:

I recommend you stick to the version on the OUSB site as I know it works and the procedures in the manual are for this version.

However if you have a reasonable level of competency you should have no problems with any of the LibUSB versions after win32 - 1.2.1.0 from the project site.

Before we start to install the driver you will need to plug your USBasp programmer into a spare USB port of your PC.

Once you have downloaded the zipped folder using the extraction wizard, extract the LibUSB-64bit folder. Open the extracted folder to the directory libusb-win32-bin-1.2.1.0 > bin >x86 and run the program inf-wizard as shown in the figure below.

> bin >x86 and run the program inf-wizard as shown in the figure below . Figure

Figure 2. 23

Inf-wizard will start, click Next.

Inf-wizard will start, click Next . Figure 2. 24 Select the USBasp programmer from the list

Figure 2. 24

Select the USBasp programmer from the list of USB devices and select Next.

Next . Figure 2. 24 Select the USBasp programmer from the list of USB devices and

Figure 2. 25

These are the device settings I used, verify and click Next.

These are the device settings I used, verify and click Next. Figure 2. 26 You now

Figure 2. 26

You now have to save the Information file (.inf) in the directory libusb-win32-bin-1.2.1.0 > bin >amd64, and click Save. (32 bit users save theirs in libusb-win32-bin-1.2.1.0 > bin >x86)

You will now be prompted to install the driver, simply click Install Now

> bin >x86 ) You will now be prompted to install the driver, simply click Install

Figure 2. 27

You may be prompted by various warning from your operating system that Windows cannot verify the publisher of the driver, if you accept the risks click Allow or Install this driver software anyway.

risks click Allow or Install this driver software anyway. The driver will now install. Figure 2.

The driver will now install.

Figure 2. 28

software anyway. The driver will now install. Figure 2. 28 Figure 2. 29 Once the driver

Figure 2. 29

Once the driver has been successfully installed click Ok.

Once the driver has been successfully installed click Ok. Figure 2. 30 Once you have purchased

Figure 2. 30

Once you have purchased your USBasp programmer and installed its driver you are ready to program the Atmega32 on the OUSB development board.

To setup your AVRISP mkII in Eclipse you need to highlight your project folder in the Project Explorer tab, and then from the menu bar select project > properties,