1 | /******************************************************************************
|
2 | *
|
3 | * AVR Code example to read a TSIC-206 / TSIC-306 digital temperatur probe
|
4 | *
|
5 | * Based on C++ Samplecode in
|
6 | * "Tech Notes - ZACwireTM Digital Output, Rev. 2.3, October 17, 2006"
|
7 | *
|
8 | * Tested with ATMega8, avr-gcc (GCC) 4.3.0 and a TSIC-206
|
9 | *
|
10 | * see also discussion at http://www.mikrocontroller.net/topic/82087
|
11 | *
|
12 | ******************************************************************************/
|
13 |
|
14 | #define F_CPU 8000000UL // Clock of target system
|
15 | #include <avr/io.h>
|
16 | #include <util/delay.h>
|
17 |
|
18 |
|
19 | /******************************************************************************
|
20 | * Hardware Connection of the TSIC-Sensor
|
21 | ******************************************************************************/
|
22 |
|
23 | #define TSIC_PORT PORTD // Port to use
|
24 | #define TSIC_PIN PIND
|
25 | #define TSIC_PORT_DDR DDRD
|
26 | #define TSCI_POWER_PIN PD6 // Where TSIC-Sensors VCC is connected
|
27 | #define TSIC_SIGNAL_PIN PD7 // Where TSIC-Sensors "Signal"-Pin is con.
|
28 |
|
29 |
|
30 | /******************************************************************************
|
31 | * FUNCTION MACROS
|
32 | ******************************************************************************/
|
33 |
|
34 | // Define TSCI_POWER_PIN as output, TSIC_SIGNAL_PIN as input
|
35 | #define TSIC_INIT() { TSIC_PORT_DDR |= (1<<TSCI_POWER_PIN); \
|
36 | TSIC_PORT_DDR &= ~(1<<TSIC_SIGNAL_PIN); }
|
37 |
|
38 | // Power up the TSIC-Sensor
|
39 | #define TSIC_ON() TSIC_PORT |= (1<<TSCI_POWER_PIN)
|
40 |
|
41 | // Power down the TSIC-Sensor
|
42 | #define TSIC_OFF() TSIC_PORT &= ~(1<<TSCI_POWER_PIN)
|
43 |
|
44 | //#define TSIC_SIGNAL (TSIC_PORT & (1<<TSIC_SIGNAL_PIN))
|
45 |
|
46 | // Low/High Signal of the TSIC-Sensor, e.g. "if(TSIC_SIGNAL_HIGH)..."
|
47 | #define TSIC_SIGNAL_HIGH TSIC_PIN & ( 1 << TSIC_SIGNAL_PIN )
|
48 | #define TSIC_SIGNAL_LOW !( TSIC_PIN & ( 1 << TSIC_SIGNAL_PIN ))
|
49 |
|
50 |
|
51 | /******************************************************************************
|
52 | * Function : getTSicTemp(*temp_value16);
|
53 | * Description : reads from the TSic its output value
|
54 | * Parameters : pointer for return value
|
55 | * Returns : 1: reading sucessfull, 0: parity error
|
56 | ******************************************************************************/
|
57 | uint8_t getTSicTemp (uint16_t *temp_value16) {
|
58 |
|
59 | uint16_t temp_value1 = 0;
|
60 | uint16_t temp_value2 = 0;
|
61 | uint8_t i;
|
62 | uint16_t Temperature;
|
63 | uint8_t parity;
|
64 |
|
65 | TSIC_ON();
|
66 | _delay_us(60); // wait for stabilization
|
67 | _delay_us(60);
|
68 |
|
69 | while (TSIC_SIGNAL_HIGH); // wait until start bit starts
|
70 |
|
71 | // wait, TStrobe
|
72 | while (TSIC_SIGNAL_LOW);
|
73 |
|
74 | // first data byte
|
75 | // read 8 data bits and 1 parity bit
|
76 | for (i = 0; i < 9; i++) {
|
77 | while (TSIC_SIGNAL_HIGH); // wait for falling edge
|
78 | _delay_us(60);
|
79 | if (TSIC_SIGNAL_HIGH)
|
80 | temp_value1 |= 1 << (8-i); // get the bit
|
81 | else
|
82 | while (TSIC_SIGNAL_LOW); // wait until line comes high again
|
83 | }
|
84 |
|
85 | // second byte
|
86 | while (TSIC_SIGNAL_HIGH);
|
87 | // wait, TStrobe
|
88 | while (TSIC_SIGNAL_LOW);
|
89 | // read 8 data bits and 1 parity bit
|
90 | for (i = 0; i < 9; i++) {
|
91 | while (TSIC_SIGNAL_HIGH); // wait for falling edge
|
92 | _delay_us(60);
|
93 | if (TSIC_SIGNAL_HIGH)
|
94 | temp_value2 |= 1 << (8-i); // get the bit
|
95 | else
|
96 | while (TSIC_SIGNAL_LOW); // wait until line comes high again
|
97 | }
|
98 |
|
99 | TSIC_OFF(); // switch TSic off
|
100 |
|
101 | // check parity for byte 1
|
102 | parity = 0;
|
103 | for (i = 0; i < 9; i++)
|
104 | if (temp_value1 & (1 << i))
|
105 | parity++;
|
106 | if (parity % 2)
|
107 | return 0;
|
108 |
|
109 | // check parity for byte 2
|
110 | parity = 0;
|
111 | for (i = 0; i < 9; i++)
|
112 | if (temp_value2 & (1 << i))
|
113 | parity++;
|
114 | if (parity % 2)
|
115 | return 0;
|
116 | temp_value1 >>= 1; // delete parity bit
|
117 | temp_value2 >>= 1; // delete parity bit
|
118 | Temperature = (temp_value1 << 8) | temp_value2;
|
119 | *temp_value16 = Temperature;
|
120 |
|
121 | return 1; // parity is OK
|
122 | }
|
123 | void ItoA( int z, char* Buffer )
|
124 | {
|
125 | int i = 0;
|
126 | int j;
|
127 | char tmp;
|
128 | unsigned u; // In u bearbeiten wir den Absolutbetrag von z.
|
129 |
|
130 | // ist die Zahl negativ?
|
131 | // gleich mal ein - hinterlassen und die Zahl positiv machen
|
132 | if( z < 0 ) {
|
133 | Buffer[0] = '-';
|
134 | Buffer++;
|
135 | // -INT_MIN ist idR. größer als INT_MAX und nicht mehr
|
136 | // als int darstellbar! Man muss daher bei der Bildung
|
137 | // des Absolutbetrages aufpassen.
|
138 | u = ( (unsigned)-(z+1) ) + 1;
|
139 | }
|
140 | else {
|
141 | u = (unsigned)z;
|
142 | }
|
143 | // die einzelnen Stellen der Zahl berechnen
|
144 | do {
|
145 | Buffer[i++] = '0' + u % 10;
|
146 | u /= 10;
|
147 | } while( u > 0 );
|
148 |
|
149 | // den String in sich spiegeln
|
150 | for( j = 0; j < i / 2; ++j ) {
|
151 | tmp = Buffer[j];
|
152 | Buffer[j] = Buffer[i-j-1];
|
153 | Buffer[i-j-1] = tmp;
|
154 | }
|
155 | Buffer[i] = '\0';
|
156 | }
|
157 |
|
158 | /******************************************************************************
|
159 | * Test application
|
160 | ******************************************************************************/
|
161 | int main (void) {
|
162 |
|
163 | uint16_t temperatur; // 11-bit temperature value
|
164 | uint8_t returnvalue; // return value of getTSicTemp(*temp);
|
165 | uint8_t Temp_celsius; // converted temperature in °C
|
166 |
|
167 | TSIC_INIT(); // set data direction of IO-Pins
|
168 |
|
169 | char asdf[20];
|
170 | while(1){
|
171 |
|
172 | returnvalue = getTSicTemp(&temperatur); // pull the TSIC-Sensor
|
173 |
|
174 | // conversion equation from TSic's data sheet
|
175 | Temp_celsius = ((float)temperatur / 2047 * 200) - 50;
|
176 |
|
177 | // DO SOMETHING USEFUL WITH THE VALUES HERE!
|
178 | // e.g. display them ;)
|
179 | if(returnvalue==1){
|
180 | ItoA(Temp_celsius,asdf);
|
181 | }
|
182 |
|
183 |
|
184 | }
|
185 |
|
186 | }
|