Getting-Started Guide to Programming the Penguino AVR in C
Writing a C program: Flash the internal LEDs
A tri-colour LED is connected to Port C on pins 6 and 7.
Pin 6 is connected to the green component and pin 7 is connected to red. When both pins are activated, the LED shines yellow-orange (a mix of the red and green light).
The following is a 5-step process to writing, compiling and uploading a program which flashes this internal LED with different colours.
Step 1: Wiring
Take a look at the Hardware Setup Guide on details about wiring up the Penguino AVR. We recommend for this example to connect VUSB to VR and connect +3.3v to VCC and AVCC.
Step 2: Power On
Plug a USB cable into the Penguino AVR and computer. If the wiring is correct, a green power LED in the middle of the Penguino AVR board should light up. Open the Flipper application (you can download it here)and ensure that Penguino AVR is listed on the left-hand menu as a connected device.
Step 3: Writing C Code
C is a low-level programming language and may take some practice to master. If you have not programmed before, we recommend learning some basic programming from a tutorial or course (such as this one).
The C program begins execution in a function called "main" and executes an instruction at a time, in order. Example code for flashing the LED is shown below:
1
2 // include penguino libraries for input and output (io.h) and timing (time.h)
3 // this gives us the statusLed and delay functions
4 #include "penguino/io.h"
5 #include "penguino/time.h"
6
7 // begin the main function
8 int main( void ) {
9
10 // start initialisation sequence
11
12 statusLed_init( ); // initialise the pins on port C to work as LED outputs
13
14 statusLed_red( ); // light up red
15
16 delay_ms( 1000 ); // wait for 1 second (1000 milliseconds)
17
18 statusLed_orange( ); // light up orange
19
20 delay_ms( 1000 ); // wait for 1 second again
21
22 statusLed_green( ); // light up green
23
24 delay_ms( 1000 ); // wait, again...
25
26 statusLed_off( ); // turns led off
27
28 delay_ms( 1000 );
29
30 // this loops forever, alternating red and green for 300 milliseconds each
31 while( 1 ) {
32 statusLed_red( );
33 delay_ms( 300 );
34 statusLed_green( );
35 delay_ms( 300 );
36 }
37
38
39 return 0;
40 }
Copy this code into a plain text editor (or a programming editor) and save it as flashing.c
Step 4: Compiling
We included files from the Penguino library, so you will need these files in order to compile. You will also need AVR-GCC for your desired platform. Required downloads are available here.
On a linux or POSIX set-up:
Run avr-gcc using the following command (assuming the penguino library directory is in the same directory as the source, or in the system's path).
avr-gcc -Wall -Os -DF_CPU=16000000 -mmcu=atmega32 -std=gnu99 -o flashing.elf flashing.c
This tells avr-gcc to compile flashing.c for atmega32 (the AVR chip that powers this Penguino) assuming a clock speed of 16Mhz. The output file is flashing.elf.
We now need to convert this elf executable into a binary format, to upload to the Penguino:
avr-objcopy -j .text -j .data -O binary flashing.elf flashing.bin
You have now created flashing.bin which can be uploaded to the Penguino using Flipper.
Step 5: Uploading
Open flipper, select the Penguino AVR device listed on the left-hand side. Click the Upload button, select flashing.bin and click OK. Your program will be uploaded to the Penguino AVR and start running. You should see the light flashing in accordance with your program. Pressing the reset button on the top of the Penguino re-starts the program.
Another Example
This program reads the value of a potentiometer using an ADC channel. The potentiometer is used as a voltage divider (outer pins connected to Vcc and Gnd, middle pin wired into A0).
1 #include "penguino/io.h"
2
3 #define MAXREADING 1023
4 #define ONE_THIRD_OF_MAXREADING (MAXREADING/3)
5 #define TWO_THIRD_OF_MAXREADING (MAXREADING-ONE_THIRD_OF_MAXREADING)
6
7 int main( void ) {
8 // initalise Status LED
9 statusLed_init( );
10
11 // initialise ADC
12 adc_init( );
13
14 // use port A pin 0 as an analog input
15 adcInput_init( A0 );
16
17 while( 1 ) {
18 // read ADC reading on port A, pin 0
19 uint16_t analogReading = adc_read( A0 );
20
21 if ( analogReading < ONE_THIRD_OF_MAXREADING ) {
22 statusLed_green( );
23 } else if ( analogReading > TWO_THIRD_OF_MAXREADING ) {
24 statusLed_red( );
25 } else {
26 // in the middle
27 statusLed_orange( );
28 }
29 }
30 }
The following is a movie of the above program in action.
![icy [labs]](/moin_static171/common/wikilogo.png)