Threading and Timers in Atmega328p
Delay pauses the whole program, so if one is using delay for 10 seconds everything will pause for those 10 seconds, therefore nothing can be done in those 10 seconds.
Although if we use interrupt, there is a separate hardware known as timer which counts the clock ticks and generate interrupt, after specified number of clock ticks have been counted.
In this project I’m using LCD JHD162A. It has 2 rows and 16 columns.
I build a task scheduler which switches between two threads in an interval of 5.5 seconds.
First task(thread 1) is to increment an integer value displayed on first row of LCD every second.
Second task(thread 2) is decrement an integer value displayed on second row every two seconds.
Both integers start from Zero.
1) t1 is running and increments the integer in the first row every second
2) After 5.5 seconds, t1 stops and t2 starts decrementing the integer in the second row every 2 seconds
3) After 5.5 seconds, stop t2, start t1, go back to 1)
A thread is a lightweight process that is executed independently. But due to hardware limitation let’s assume that a thread is simply a function manipulating one of the integers mentioned above. Since Atmega328P is equipped with only one ALU, either thread1 or thread2 is able to run. They can never run at the same time.
How I am uploading code into arduino:
f = <source_code’s_file_name>
avr-gcc -g -mmcu=atmega328p -Wall -Os $(f).c -o $(f).elf
avr-objcopy -j .text -j .data -O ihex $(f).elf $(f).hex
sudo avrdude -F -V -c arduino -p m328 -P /dev/ttyUSB* -b 57600 -e -U flash:w:$(f).hex
Just type these four commands, in the same order, in your terminal and remember to put the source code’s filename in variable “f”. These command are for Linux users only.
First command stores the filename in variable “f”, second command is used to convert source code to .elf file, third command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, fourth command is used to upload that .hex file.
Intro to Atmega328p and it’s timers:
Atmega328p is equipped ,viz. timer0, timer1, timer2; two are 8-bits and one is 16-bit. Maximum number of clock ticks that a timer can count depends on the size of the register.
Timer 0 and timer 2 use two different 8-bit register, whereas, timer 1 is use a 16-bit register.
An 8-bit register can count upto 2^8 = 256(0 to 255) similarly 16-bit register can count up 2^16 = 65536(0 to 65535). With the available resources I can generate an interrupt at every (65536/clock freq) 65536/1,60,00,000 = 4.0959375ms.
To increase this maximum time, every timer is given a set of pre-scalars, which are in power of 2’s. A prescaler divides the clock freq by that number. In 16-bit timer maximum pre-scalar available is 1024, therefore now I can generate an interrupt
(65536/(clk freq/1024)) 65536*1024/1,60,00,000 = 4.19424 sec
Same goes for 8-bit timer.