uncategorized

Week 08- Embedded programming.

This week is dedicated for playing around with controllers, processors etc- things which can be programmed to do stuff, things which are like mini computers. The most common microcontroller in our FabLab is the ATTiny series. We also have Atmega 328P, Atmega 32U4 and ARM STM32F103C8T6. They are all AVR microcontroller’s, except the last one, and we will be programming the board we made in Week 4- Electronic production.

As we recall, in that week we made an echo
-hello
board with ATTiny44 microcontroller which can be programmed using the Fab ISP. The board we modified had an additional LED and a button/press switch attached. So we can program the board to do some basic tasks like blinking the LED and recording a switch press etc.

Notes

Programming

I programmed the AVR in two different ways.

  1. Using Arduino IDE.
  2. Using AVR-C.

Arduino IDE

Most of the people reading this documentation should be knowing what is Arduino or even to work with one. This Link will welcome you to the world of Arduino and DIY projects using it.

As I am using Arch Linux I used AUR to install the arduino IDE. So I have the latest version (1.6.8) of the same.
I followed these steps of adding the ATTiny chips into the Board list in the IDE which come under the Tools drop-down menu. Next i had to figure out the pin to which the LED is connected. It is nice to have the Data Sheet handy. It will come to your help many a time. For the present usage we just need the following diagram to get the PIN number for coding.

ATTiny44

With the help of both the pin-out image and the data sheet I wrote the following piece of code for blinking the LED continuously for with a time interval of 1 second.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* This program make the LED blink with a one second intervel.
*/


void setup() {
// put your setup code here, to run once:

pinMode (8, OUTPUT); // assign pin 8 in output mode

}

void loop() {
// put your main code here, to run repeatedly:

digitalWrite(8, HIGH); // turn the LED on
delay(1000); // wait for a second
digitalWrite(8, LOW); // turn the LED off
delay(1000); // wait for a second

}

After this I wrote a program to turn the LED ON and OFF with the switch connected to pin 7.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  /*
* Switch plus an LED
*
* This program turns ON the LED when the switch is pressed
* and turns off when it is released.
*
*/


void setup() {
// put your setup code here, to run once:

pinMode (8, OUTPUT); // assign pin 8 in output mode
pinMode (7, INPUT); // assign pin 7 as input pin
digitalWrite (7, HIGH); // made the pin 7's default value as HIGH
}

void loop() {
// put your main code here, to run repeatedly:

if (digitalRead(7) == LOW){

digitalWrite(8, HIGH); // turn the LED on when button is pressed

}
else {

digitalWrite(8, LOW); // turn the LED off when button released

}
}

AVR - C

Blinking

I tried to have an IDE for working with AVR - C as I am used to one. So decided to try Code::Block. But after spending an unsuccessful half an hour trying to get the compilers, debuggers etc right I got fed up. So I uninstalled the program and decided to go with the text editor Vi, which I have just started using or Atom, which I think is more realistic as it has syntax highlighting and all.

This way of programming will definitely need the help of datasheet as we need to get data like the number of ports, pin numbers, internal architectures, information on registers etc. So keep it by your side.

The first attempt was to write the code for blinking the LED. After a few hours spent on internet reading and watching tutorials in youtube, the following is what I came up with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
*This program is written for blinking an LED PB2 of ATTiny44
*/

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{


DDRB = 0b00000100; // turns the pin PB2 as active


while(1) // infinite loop
{
//set high and low value to pins of PORT B. Here PB2 is high.
PORTB = 0b00000100; // you can also use the hex value "0x04"
// cause a delay of 1 sec
_delay_ms(1000);
// set PB2 to low
PORTB = 0b00000000; // you can also use the hex value 0x00
//cause a delay of 1 sec
_delay_ms(1000);
}
}

Add a button

Then I added a control of switching the LED ON and OFF according to push of a button.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
*This program is written for switching ON the LED when a button is pressed.
*/


#include <avr/io.h>
#include <util/delay.h>

int main(void)
{


DDRB = 0b0100; // turns the pin PB2 as active/output, note their are only 4 bits in PORTB
DDRA = 0b10000000; // turns the pin PA7 as active/output, note their are only 8 bits in PORTA
PORTB = 0b0000; // sets all the pins LOW
PORTA = 0b10000100; // set A2 & A7 high or pulls up the pin

while(1) // infinite loop
{
if(!(PINA & 0b00000100)) //checks input register if PA2 is pulled down(happens when the button is pressed)
{
PORTB |= 0b0100; //turns the LED at PB2 on
PORTA &= 0b01111111; //turns the LED at PA7 off
}
else
{
PORTB &= 0b1011; //turns the LED at PB2 off
PORTA |= 0b10000100; //turns the LED at PA7 on
}
}
}

Things to know here are the logical AND and OR operations, Also out the registers of the PORT A&B and PIN registers. Here are the direction registers, input registers and the data registers of port A&B .

Interrupt programming

Next i aimed at understanding interrupts in AVR programming. Atmega has different size timers/counters in it which can be made used to make different applications like stopping/pausing in between processing to run a different code, make PWM waves etc. Here i will be using the counter and interrupts to blink two LEDs alternatively with a time interval of 1s. Lets sbegin by usign timers and registers to create interrupt driven processes in ATTiny 44.

Their is provision for 8bit and 16bit timer/counters in tiny44. Timer/Counter0 is a general purpose 8-bit Timer/Counter module, with two independent Output Compare Units, and with PWM support. It allows accurate program execution timing (event management) and wave generation. The 16-bit Timer/Counter unit allows accurate program execution timing (event management), wave generation, and signal timing measurement. I used the 8 bit counter.

Working

There are different ways for configuring the counter. The basic thing to know are, an 8-bit counter can count from 0-255 and if the prescaler is set to 1 the value changes in every clockcycle. Once it reaches 255, in the next clock the counting register wlll be flushed and reseted and a bit in the SREG will be changed indicating the overflow. We can have an interrupt that way or tere is an option for haveing an 8-bit number stored and being compared to timer value and then call an interrupt when they become equal. I chose the second method for my program. Some of the importanat registers to be noted are

An over view of interrupt vectors in 44
TCCR0A
**CTC - Clear Timer on Compare Match** selection settings

I prescaled the clock source to clk/1024 to have maximum time out of one full count.

Prescaler settings

The code i wrote for blinking the led alternatively using interrupts is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <avr/io.h>
#include <avr/interrupt.h>

int timer = 0;

int main(void)
{


DDRB = 0b0100; // turns the pin PB2 as active/output, note their are only 4 bits in PORTB
DDRA = 0b10000000; // turns the pin PA7 as active/output, note their are only 8 bits in PORTA
PORTA = 0b10000000;

TCCR0A = (1 << WGM01); // CTC bit set
OCR0A = 195; // no: of clicks to happen for getting 0.01s, this is the value the timer is compared to.
TIMSK0 = (1 << OCIE0A);
sei();

TCCR0B = (1 << CS02) | (1 << CS00); // start a clk/1024 prescaler

while(1) {

}


}

ISR(TIM0_COMPA_vect ){
timer++;
if (timer > 100)
{
PORTB ^= (1 << PORTB2); // toggle led
PORTA ^= (1 << PORTA7); // toggle led
timer = 0; //reset count down
}
}

things to learn

  • using timers for making PWM signals
  • understanding the ADC functionalities of the microcontroller

This weeks design files

Share