<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta name="generator" content="pandoc" /> <title></title> <style type="text/css">code{white-space: pre;}</style> <style type="text/css"> div.sourceCode { overflow-x: auto; } table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { margin: 0; padding: 0; vertical-align: baseline; border: none; } table.sourceCode { width: 100%; line-height: 100%; } td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } td.sourceCode { padding-left: 5px; } code > span.kw { color: #007020; font-weight: bold; } /* Keyword */ code > span.dt { color: #902000; } /* DataType */ code > span.dv { color: #40a070; } /* DecVal */ code > span.bn { color: #40a070; } /* BaseN */ code > span.fl { color: #40a070; } /* Float */ code > span.ch { color: #4070a0; } /* Char */ code > span.st { color: #4070a0; } /* String */ code > span.co { color: #60a0b0; font-style: italic; } /* Comment */ code > span.ot { color: #007020; } /* Other */ code > span.al { color: #ff0000; font-weight: bold; } /* Alert */ code > span.fu { color: #06287e; } /* Function */ code > span.er { color: #ff0000; font-weight: bold; } /* Error */ code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ code > span.cn { color: #880000; } /* Constant */ code > span.sc { color: #4070a0; } /* SpecialChar */ code > span.vs { color: #4070a0; } /* VerbatimString */ code > span.ss { color: #bb6688; } /* SpecialString */ code > span.im { } /* Import */ code > span.va { color: #19177c; } /* Variable */ code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ code > span.op { color: #666666; } /* Operator */ code > span.bu { } /* BuiltIn */ code > span.ex { } /* Extension */ code > span.pp { color: #bc7a00; } /* Preprocessor */ code > span.at { color: #7d9029; } /* Attribute */ code > span.do { color: #ba2121; font-style: italic; } /* Documentation */ code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ </style> <link rel="stylesheet" href="styles.css" type="text/css" /> </head> <body> <h1 id="programming-in-c">Programming in C</h1> <h2 id="introduction">Introduction</h2> <p>Programming in C was not that hard for me, I have learned C++ and I have a previous experience with Java. I know the loops like for and while, conditional statement like if, variables like int, classes and libraries. I have also programmed an Arduino before, but I have never programmed in C or an micro controller on a lower level.</p> <p>The problem was not the syntax of C, the problem was to understand the registers and how to use them for a specific function.</p> <p>The micro controller used is ATTiny44.</p> <h2 id="input-and-output">Input and Output</h2> <p>ATTiny44 has 14 pins, 12 of them are for reading inputs and applying outputs. An input or an output can be either digital or analog. Any operation of a computer or a micro controller is simply a 0 or 1 which is 0v or 5v, digital is represented by 0 and 1 whereas the analog is represented as voltage range.</p> <p>The micro controller should know if a specific pin will be used as an input or an output. If it is an input, the DDR register has to be 0 then it should know if it will write or read a specific pin. If the pin is an input and the operation is to write then the 0 is to deactivate pull up resistor and 1 is to activate pull up resistor, if the operation is to read then 0 is means 0v and 1 means 5v. If the pin is output, DDR registers has to be 1 then if it writes 0 means 0v and 1 means write 5v.</p> <p>The process programmatically can be seen in the following code which I have used as the starting point in C programming.</p> <p>Hardware is explained in Electronics documentation</p> <div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span> <span class="co">This code was created by Ahmad Fares on 4th-Dec-2017.</span> <span class="co">The code is used to switch on an LED when a Button is pressed.</span> <span class="co">MIT License</span> <span class="co">*/</span> <span class="ot">#define F_CPU 1000000UL </span><span class="co">//Define the speed 1Mhz</span> <span class="ot">#include <avr/io.h> </span><span class="co">//Include io library</span> <span class="ot">#include <util/delay.h> </span><span class="co">//include delay library</span> <span class="dt">int</span> main (<span class="dt">void</span>) { DDRA = <span class="bn">0b00001000</span>; <span class="co">// set PA3 as output in DDRA.</span> DDRB = <span class="bn">0b00000000</span>; <span class="co">// set PB2 as input in DDRB.</span> PORTB = <span class="bn">0b00000100</span>; <span class="co">// activate pull up resistor.</span> <span class="kw">while</span>(<span class="dv">1</span>) { <span class="kw">if</span>(PINB == <span class="bn">0b00000000</span>){ <span class="co">//Read PB2</span> PORTA = <span class="bn">0b00000000</span>; <span class="co">//Switch on the LED</span> }<span class="kw">else</span>{ PORTA = <span class="bn">0b00001000</span>; <span class="co">//Switch off the LED</span> } } }</code></pre></div> <h4 id="another-way-to-define-inputs-and-outputs">Another way to define inputs and outputs</h4> <p>It seems hard to define inputs and outputs at the way explained above, sometimes I forget a bit, sometimes I need to define only one pin not all of them so another way is to use bitwise method.</p> <p>(register) |= (1 << (bit)) means to write 1 (register) &= ~(1 << (bit)) means to write 0 (register) & (1 << (bit)) to read statues.</p> <p>The following code explains this method:</p> <div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span> <span class="co">This code was created by Ahmad Fares on 4th-Dec-2017.</span> <span class="co">The code is used to switch on an LED when a Button is pressed using bitewise method</span> <span class="co">MIT License</span> <span class="co">*/</span> <span class="ot">#define F_CPU 1000000UL </span><span class="co">//Define the speed 1Mhz</span> <span class="ot">#include <avr/io.h> </span><span class="co">//Include io library</span> <span class="ot">#include <util/delay.h> </span><span class="co">//include delay library</span> <span class="dt">int</span> main (<span class="dt">void</span>) { DDRA |= (<span class="dv">1</span> << PA3); <span class="co">// set PA3 as output in DDRA.</span> DDRB &= ~(<span class="dv">1</span> << PB2); <span class="co">// set PB2 as input in DDRB.</span> PORTB |= (<span class="dv">1</span> << PB2); <span class="co">// activate pull up resistor.</span> <span class="kw">while</span>(<span class="dv">1</span>) { <span class="kw">if</span>(PINB & (<span class="dv">1</span> << PB2)){ <span class="co">//Read PB2</span> PORTA &= ~(<span class="dv">1</span> << PA3); <span class="co">//Switch on the LED</span> }<span class="kw">else</span>{ PORTA |= (<span class="dv">1</span> << PA3);; <span class="co">//Switch off the LED</span> } } } </code></pre></div> <h4 id="macron">Macron</h4> <p>A much simpler way of defining inputs and outputs and writing zeros and ones is macron.</p> <p>Using macron, I have been able to write a code in human understandable language rather than registers.</p> <p>The following code explains the macron method</p> <div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span> <span class="co">This code was created by Ahmad Fares on 4th-Dec-2017.</span> <span class="co">The code is used to switch on an LED when a Button is pressed using Macron</span> <span class="co">MIT License</span> <span class="co">*/</span> <span class="ot">#define F_CPU 1000000UL </span><span class="co">//Define speed</span> <span class="co">//Define Macron</span> <span class="ot">#define setbit(register, bit) (register) |= (1 << (bit))</span> <span class="ot">#define clearbit(register, bit) (register) &= ~(1 << (bit))</span> <span class="ot">#define testbit(register, bit) (register) & (1 << (bit))</span> <span class="ot">#include <avr/io.h></span> <span class="ot">#include <util/delay.h></span> <span class="dt">int</span> main (<span class="dt">void</span>) { setbit(DDRA, PA3); <span class="co">// set PA3 as output in DDRA.</span> clearbit(DDRB, PB2); <span class="co">// set PB2 as input in DDRB.</span> setbit(PORTB, PA3); <span class="co">// activate pull up resistor.</span> <span class="kw">while</span>(<span class="dv">1</span>) { <span class="kw">if</span>(testbit(PINB, PB2)){ <span class="co">//Read button statues</span> setbit(PORTA, PA3); <span class="co">//Switch off LED</span> }<span class="kw">else</span>{ clearbit(PORTA, PA3); <span class="co">// Switch on LED</span> } } }</code></pre></div> <h2 id="interrupts">Interrupts</h2> <p>Interrupts are used to force the microcontroller to pause the code and execute a specific block of code inside ISR function.</p> <p>I have used interrupts to switch on an LED when a button is pressed instead of asking the microcontroller "Is button pressed?" by continuously reading the PB2 statues.</p> <div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span> <span class="co">This program was created by Ahmad Fares on 7th-Dec-2017</span> <span class="co">The purpose of this program is to use interrupt to detect a button statues</span> <span class="co">MIT License</span> <span class="co">*/</span> <span class="ot">#define F_CPU 1000000UL </span><span class="co">//Define speed</span> <span class="co">//Define Macron</span> <span class="ot">#define setbit(register, bit) (register) |= (1 << (bit))</span> <span class="ot">#define clearbit(register, bit) (register) &= ~(1 << (bit))</span> <span class="ot">#define testbit(register, bit) (register) & (1 << (bit))</span> <span class="ot">#include <avr/interrupt.h> </span><span class="co">//include interrupt library</span> <span class="ot">#include <avr/io.h> </span><span class="co">//include io library</span> <span class="co">// interrupt function, PCINT1_vect is the vector for interrupt request</span> ISR(PCINT1_vect) { <span class="kw">if</span> ( PINB & (<span class="dv">1</span><<PB2) ) <span class="co">// test PINA7 if true then</span> setbit(PORTA,PA3); <span class="co">//turn off LED</span> <span class="kw">else</span> clearbit(PORTA,PA3); <span class="co">//Turn on LED</span> } <span class="dt">int</span> main (<span class="dt">void</span>){ sei(); <span class="co">// activate interrupts globally</span> setbit(DDRA, PA3); <span class="co">// set PA3 as output in DDRA.</span> clearbit(DDRB, PB2); <span class="co">// set PB2 as input in DDRB.</span> setbit(PORTB, PB2); <span class="co">// activate pull up resistor.</span> setbit(GIMSK,PCIE1); <span class="co">//Enable pin change interrupt PORTB</span> setbit(PCMSK1, PCINT10); <span class="co">//Enabl pin change interrupt in pin PB2</span> setbit(PINA,PA3); <span class="kw">while</span>(<span class="dv">1</span>){ <span class="co">//Doing nothing until the interrupt occurs</span> } } </code></pre></div> <h2 id="timers">Timers</h2> <p>Timers are registers inside the microcontroller, but run independently and can be used to run a specific code after a certain time. In my case, the ATTiny44 has three 8-bit counter registers: <strong>TCNT0</strong>, <strong>TCNT1L</strong> and <strong>TCNT1H</strong>.</p> <p>Those registers don't actually count time, they count cycles and from these cycles we can count time. There are two operation modes: normal and CTC (clear time on compare match). In the normal mode a specific block of code is executed after the register overflows whereas in the CTC mode which is the most commonly used, a block of code is executed after a certain number of cycles or seconds.</p> <h4 id="how-to-count-1-second">How to count 1 second</h4> <p>ATTiny44 runs at 1Mhz, which means 1 cycle every 1 micro seconds, if a normal mode is chosen so the specific task will be executed every 0.065536 seconds which is very fast, In my case I wanted to toggle the LED state every second so I have chose CTC mode and counted the 1 second as follows:</p> <p>When the register TCNT overflows at normal mode, the number is 65536 which is 2^16 (16 bit since TCNT is two 8-bit register) so a prescalar is used to slow it down. The prescalars available are 1, 8, 64, 256, 1024.</p> <p>First is choose the first prescalar which gives a time higher than the required 1 second.</p> <table> <thead> <tr class="header"> <th align="left"><strong>1</strong></th> <th align="left"><strong>0.065536</strong></th> </tr> </thead> <tbody> <tr class="odd"> <td align="left"><strong>8</strong></td> <td align="left"><strong>0.524288</strong></td> </tr> <tr class="even"> <td align="left"><strong>64</strong></td> <td align="left"><strong>4.194304</strong></td> </tr> </tbody> </table> <p>64 prescalar gives 4.194304 seconds, using the rule of third, I have calculated the number corresponds to 1 second as follows</p> <p>4.194304 --> 65536 1 ---------> X</p> <p>X = 65536/4.194304 = 15625 exact.</p> <h4 id="example">Example</h4> <div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span> <span class="co">This code was created by Ahmad Fares on 10-Dec-2017</span> <span class="co">Timer with timer/counter 1 hardware to toggle LED state every 1 seconds</span> <span class="co">MIT License</span> <span class="co">*/</span> <span class="ot">#define setbit(register, bit) (register) |= (1 << (bit))</span> <span class="ot">#define clearbit(register, bit) (register) &= ~(1 << (bit))</span> <span class="ot">#define testbit(register, bit) (register) & (1 << (bit))</span> <span class="ot">#define togglebit(register,bit) (register) ^= (1<<bit)</span> <span class="ot">#define F_CPU 1000000UL</span> <span class="ot">#include <avr/io.h></span> <span class="ot">#include <util/delay.h></span> <span class="ot">#include <avr/interrupt.h></span> ISR(TIM1_COMPA_vect){ togglebit(PORTA,PA3); } <span class="dt">int</span> main (<span class="dt">void</span>) { DDRA |= (<span class="dv">1</span> << PA3); <span class="co">// set LED pin as output</span> OCR1A = <span class="dv">15625</span>; <span class="co">// at 1/64 prescalar this is exactly 1 second.</span> setbit(TCCR1B, WGM12); sei(); setbit(TIMSK1,OCIE1A); <span class="co">// enable CTC interrupt when TCNT1 = OCR1A</span> setbit(TCCR1B,CS11); setbit(TCCR1B,CS10); <span class="co">//These 2 registers set prescalar to 1/64 and start the counter.</span> <span class="co">// setbit(PORTA,PA3);</span> <span class="kw">while</span>(<span class="dv">1</span>) { } }</code></pre></div> <h2 id="adc">ADC</h2> <h2 id="sample-code.">Sample Code.</h2> <p><strong>In sample code put also problems see notebook</strong></p> <p><strong>Write more about registers in interrupt and other</strong></p> <p><strong>Push LED, Interrupt, delay, withoutPullUp</strong></p> <p><strong>Add video of each code</strong></p> </body> </html>