Newer
Older
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<!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>
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>
<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>0.524288</strong></td>
</tr>
<tr class="even">
<td align="left"><strong>64</strong></td>
<td align="left"><strong>4.194304</strong></td>
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
</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>