-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
139 lines (108 loc) · 3.17 KB
/
main.c
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
130
131
132
133
134
135
136
137
138
139
/*
* main.c
*
* Created on: 28-03-2013
* Author: Marcin Kacprzak
*/
#include "ds18b20.h"
#include "led.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//#define KEY PINA0
//#define DEBUG
//------------------------------------------------------------------------------
int8_t nthDigit(int x, uint8_t n) {
while (n--) {
x /= 10;
}
return (x % 10);
}
//------------------------------------------------------------------------------
#ifdef DEBUG
int8_t nthNibble(int x, uint8_t n)
{
while (n--) {
x >>= 4;
}
return (x & 0x0f);
}
#endif
//------------------------------------------------------------------------------
void init_ports() {
DDRA = 0x00; /* Set porta A as input */
PORTA = 0xff; /* Pull up */
DDRB = 0xff; /* Set port B as output */
DDRD = 0xff; /* Set port D as output */
PORTD = 0x00;
}
//------------------------------------------------------------------------------
// initialize timer, interrupt and variable
void init_timer0() {
// Konfiguracja licznika
// Tryb CTC, Preskaler 1024
TCCR0 |= (1 << WGM01) | (1 << CS02) | (1 << CS00);
// Przerwanie OC0
TIMSK |= (1 << OCIE0);
const int counter_frq = F_CPU / 1024u;
// Czestotliwosc odswierzania
OCR0 = (counter_frq / 200u) - 1; // 200 Hz (50 Hz per digit)
}
//------------------------------------------------------------------------------
void set_led_value(int16_t temper) {
static int16_t last_temperature = 0;
if (last_temperature == temper)
return;
last_temperature = temper;
#ifndef DEBUG
int16_t fraction = (temper & 0x0f); // extract first nibble;
fraction = ((fraction * 100) / 16);
temper = (temper >> 4); // drop first (fraction) nibble;
led_set_value(
nthDigit(temper, 1),
nthDigit(temper, 0),
nthDigit(fraction, 1),
nthDigit(fraction, 0)
);
#else
led_set_value(
nthNibble(temper, 3),
nthNibble(temper, 2),
nthNibble(temper, 1),
nthNibble(temper, 0)
);
#endif
}
//------------------------------------------------------------------------------
// this ISR is fired whenever a match occurs
ISR (TIMER0_COMP_vect)
{
led_update();
}
//------------------------------------------------------------------------------
int main(void) {
/* Data from ds18b20 */
unsigned char ds18b20_pad[9];
init_ports();
init_timer0();
sei();
#ifndef DEBUG
led_set_dot_on(2, 1);
#endif
for (;;) {
/* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20
polecenie pomiaru */
if (ds18b20_ConvertT()) {
/* 750ms - czas konwersji */
_delay_ms(750);
/* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad.
Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej
znaczący bajt wartość zmierzonej temperatury */
ds18b20_Read(ds18b20_pad);
int16_t temperature = ((ds18b20_pad[1] << 8) + (ds18b20_pad[0]));
set_led_value(temperature);
}
_delay_ms(750);
}
return 0;
}