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 | void readSens(uint8_t *temp_value){
|
58 | while (TSIC_SIGNAL_HIGH); // wait until start bit starts
|
59 |
|
60 | // wait, TStrobe
|
61 | while (TSIC_SIGNAL_LOW);
|
62 |
|
63 | // read 8 data bits
|
64 | for (int i = 0; i < 9; i++) {
|
65 | while (TSIC_SIGNAL_HIGH); // wait for falling edge
|
66 | _delay_us(60);
|
67 | if (TSIC_SIGNAL_HIGH)
|
68 | *temp_value |= 1;
|
69 | *temp_value <<= 1;
|
70 | while (TSIC_SIGNAL_LOW); // wait until line comes high again
|
71 | }
|
72 |
|
73 |
|
74 | }
|
75 | uint8_t readParity(){
|
76 | while (TSIC_SIGNAL_HIGH); // wait for falling edge
|
77 | _delay_us(60);
|
78 | if (TSIC_SIGNAL_HIGH){
|
79 | return 1;
|
80 | }
|
81 | else{
|
82 | while (TSIC_SIGNAL_LOW); // wait until line comes high again
|
83 | return 0;
|
84 | }
|
85 | }
|
86 | uint8_t checkParity(uint8_t temp_value,uint8_t parityadd){
|
87 | uint8_t parity = 0;
|
88 | uint8_t mask =0b00000001;
|
89 | for (int i = 0; i < 7; i++){
|
90 | if (temp_value & mask)
|
91 | parity++;
|
92 | mask<<=1;
|
93 | }
|
94 | parity+=parityadd;
|
95 | return parity & 1; // AND 1 entspricht MOD 2
|
96 | }
|
97 | uint8_t getTSicTemp (uint16_t *temp_value16) {
|
98 |
|
99 | uint8_t temp_value1 = 0;
|
100 | uint8_t temp_value2 = 0;
|
101 | uint8_t paritybits;
|
102 |
|
103 | TSIC_ON();
|
104 | _delay_us(60); // wait for stabilization
|
105 | _delay_us(60);
|
106 |
|
107 | //first byte
|
108 | readSens(&temp_value1);
|
109 | paritybits=readParity();
|
110 |
|
111 | // second byte
|
112 | readSens(&temp_value2);
|
113 | paritybits |=(readParity()<<1);
|
114 |
|
115 | TSIC_OFF();
|
116 |
|
117 | if(checkParity(temp_value1,paritybits&1)) return 0;
|
118 | if(checkParity(temp_value2,paritybits&2)) return 0;
|
119 |
|
120 | /*
|
121 | while (TSIC_SIGNAL_HIGH);
|
122 | // wait, TStrobe
|
123 | while (TSIC_SIGNAL_LOW);
|
124 | // read 8 data bits and 1 parity bit
|
125 | for (i = 0; i < 9; i++) {
|
126 | while (TSIC_SIGNAL_HIGH); // wait for falling edge
|
127 | _delay_us(60);
|
128 | if (TSIC_SIGNAL_HIGH)
|
129 | temp_value2 |= 1 << (8-i); // get the bit
|
130 | else
|
131 | while (TSIC_SIGNAL_LOW); // wait until line comes high again
|
132 | }
|
133 | */
|
134 | // switch TSic off
|
135 | /*
|
136 | return 0;
|
137 |
|
138 | // check parity for byte 2
|
139 | parity = 0;
|
140 | for (int i = 0; i < 8; i++)
|
141 | if (temp_value2 & (1 << i))
|
142 | parity++;
|
143 | if (parity % 2)
|
144 | return 0;
|
145 | */
|
146 |
|
147 | *temp_value16 = (temp_value1 << 8) | temp_value2;
|
148 |
|
149 | return 1; // parity is OK
|
150 | }
|
151 | void ItoA( int z, char* Buffer )
|
152 | {
|
153 | int i = 0;
|
154 | int j;
|
155 | char tmp;
|
156 | unsigned u; // In u bearbeiten wir den Absolutbetrag von z.
|
157 |
|
158 | // ist die Zahl negativ?
|
159 | // gleich mal ein - hinterlassen und die Zahl positiv machen
|
160 | if( z < 0 ) {
|
161 | Buffer[0] = '-';
|
162 | Buffer++;
|
163 | // -INT_MIN ist idR. größer als INT_MAX und nicht mehr
|
164 | // als int darstellbar! Man muss daher bei der Bildung
|
165 | // des Absolutbetrages aufpassen.
|
166 | u = ( (unsigned)-(z+1) ) + 1;
|
167 | }
|
168 | else {
|
169 | u = (unsigned)z;
|
170 | }
|
171 | // die einzelnen Stellen der Zahl berechnen
|
172 | do {
|
173 | Buffer[i++] = '0' + u % 10;
|
174 | u /= 10;
|
175 | } while( u > 0 );
|
176 |
|
177 | // den String in sich spiegeln
|
178 | for( j = 0; j < i / 2; ++j ) {
|
179 | tmp = Buffer[j];
|
180 | Buffer[j] = Buffer[i-j-1];
|
181 | Buffer[i-j-1] = tmp;
|
182 | }
|
183 | Buffer[i] = '\0';
|
184 | }
|
185 |
|
186 | /******************************************************************************
|
187 | * Test application
|
188 | ******************************************************************************/
|
189 | int main (void) {
|
190 |
|
191 | uint16_t temperatur; // 11-bit temperature value
|
192 | uint8_t returnvalue; // return value of getTSicTemp(*temp);
|
193 | uint8_t Temp_celsius; // converted temperature in °C
|
194 |
|
195 | TSIC_INIT(); // set data direction of IO-Pins
|
196 |
|
197 | char asdf[20];
|
198 | while(1){
|
199 |
|
200 | returnvalue = getTSicTemp(&temperatur); // pull the TSIC-Sensor
|
201 |
|
202 | // conversion equation from TSic's data sheet
|
203 | Temp_celsius =(temperatur * 200 / 2047) - 50;
|
204 |
|
205 | // DO SOMETHING USEFUL WITH THE VALUES HERE!
|
206 | // e.g. display them ;)
|
207 | if(returnvalue==1){
|
208 | ItoA(Temp_celsius,asdf);
|
209 | }
|
210 |
|
211 |
|
212 | }
|
213 |
|
214 | }
|