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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 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 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | #include<avr/io.h> #include<avr/interrupt.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include "basedef.h" void uart_init() // UART 초기화 { UBRR0L = (unsigned char)BAUD_RATE_L; // baud rate 설정 UBRR0H = (unsigned char)BAUD_RATE_H; // no parity, 1 stop bit, 8bit 설정 UCSR0C = (0 << UPM01) | (0 << UPM00) | (0 << USBS0) | (1 << UCSZ01) | (1 << UCSZ00); UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (0 << UCSZ02); // rx/tx interrupt 설정, 8bit 설정 } void uart_send_byte(unsigned char byte) // 1 byte 전송 함수 { while (!(UCSR0A & (1 << UDRE0))) ; // 전송 버퍼가 빌 때 까지 기다린다. UDR0 = byte; } // UART 문자열 전송 void uart_send_string(unsigned char *str, unsigned char len) { int i; for (i = 0; i < len; i++) { if (!(*(str + i))) { break; } uart_send_byte(*(str + i)); } uart_send_byte('\r'); uart_send_byte('\n'); } // micro second delay void delay_us(unsigned int us) { while (us) us--; } // TWI시작신호 , SHT11 에 데이터 전송 신호 발생 void transStart(void) { // 1: High 0: Low setWRITE; DATA(1); SCK(0); delay_us(1); SCK(1); delay_us(1); DATA(0); delay_us(1); SCK(0); delay_us(5); SCK(1); delay_us(1); DATA(1); delay_us(1); SCK(0); } //SDA를 통해 SHT11에 데이터 쓰기 unsigned char writeByte(unsigned char value) { unsigned char i; unsigned char error = 0; setWRITE; for(i = 0x80; i > 0; i /= 2) { if(i & value) DATA(1); else DATA(0); SCK(1); delay_us(5); SCK(0); } setREAD; SCK(1); delay_us(1); error=bit_is_set(PIND, 1); SCK(0); return error; } //SDA 를 통해 SHT11로부터 데이터 받기 unsigned char readByte(unsigned char ack) { unsigned char i; unsigned char val = 0; setREAD; for(i = 0x80; i > 0; i /= 2) { SCK(1); if(bit_is_set(PIND, 1)) val=(val | i); SCK(0); } setWRITE; DATA(!ack); SCK(1); delay_us(5); SCK(0); return val; } void conv_byte(unsigned char in, unsigned char *out) { unsigned char a; a = in & 0xf0; a = a >> 4; if(a > 9) { out[0] = a - 10 + 0x41; } else { out[0] = a + 0x30; } a = in & 0x0f; if(a > 9) { out[1] = a - 10 + 0x41; } else { out[1] = a + 0x30; } } // BYTE -> int 변환 void conv_int(int in, unsigned char * out) { unsigned int temp; unsigned char a; if(in >= 0) { temp = in & 0xff00; a = (unsigned char)(temp >> 8); conv_byte(a, out); a = (in & 0x00ff); conv_byte(a, out + 2); } else { *out = '-'; out++; in *= -1; temp = in & 0xff00; a = (unsigned char)(temp >> 8); conv_byte(a, out); a = (in & 0x00ff); conv_byte(a, out + 2); } } // SHT11로 부터 받은 값을 실제 수치로 환산 int conv_data(int in, unsigned char mode) { unsigned char data[5]; int calc = 0; conv_int(in, data); itoa(in, data, 10); // 습도 : 12비트 분해능의 경우 계산용 C1, C2, C3 // C1 + C2*value + C3*value^2 value는 SHT11로부터 받은 (conv_int()로 변환된)값 #define HUMI_C1 (-4) #define HUMI_C2 (0.0405) #define HUMI_C3 (-0.0000028) // 온도 : 14비트 분해능의 경우 계산용 D1 // 3.5V 입력 전압에 따른 계산용 D2 // D1 + D2*value #define TEMP_D1 (-39.66) #define TEMP_D2 (0.01) switch(mode) { case TEMP: calc = (TEMP_D1) + (TEMP_D2 * in); break; case HUMI: calc = ((HUMI_C1) + (HUMI_C2 * in) + (HUMI_C3 * (in * in))); break; } return calc; } // TWI 상태 리셋 void connReset(void) { unsigned int i; setWRITE; DATA(1); SCK(0); for(i = 0; i < 9; i++) { SCK(1); SCK(0); } transStart(); } // SHT11로 부터 각 센서의 값을 읽어 들이는 함수 unsigned char measure(unsigned int *p_value, unsigned char *p_checksum, unsigned char mode) { unsigned char error = 0; unsigned long i = 0; transStart(); switch(mode) { case TEMP : error+=writeByte(MEASURE_TEMP); break; case HUMI : error+=writeByte(MEASURE_HUMI); break; default : break; } setREAD; for(i=0;i<100000;i++) if(bit_is_set(PIND, 1) == 0) break; if (bit_is_set(PIND, 1)) error+=1; *p_value = readByte(ACK); *p_value <<= 8; *p_value += readByte(ACK); *p_checksum = readByte(noACK); return error; } int main(void) { unsigned char check; unsigned char error; unsigned int temp; unsigned int humi; unsigned char outdata[20]; volatile unsigned int i; volatile unsigned int j; uart_init(); while(1) { uart_send_string("Sensing Start", 13); error = 0; error += measure(&temp, &check, TEMP); error += measure(&humi, &check, HUMI); if (error) { uart_send_string("Sensing Error", 13); connReset(); } else { sprintf(outdata, "Temp : %d ℃", conv_data(temp, TEMP)); uart_send_string(outdata, strlen(outdata)); sprintf(outdata, "Humi : %d %%", conv_data(humi, HUMI)); uart_send_string(outdata, strlen(outdata)); } for(i = 0; i < 600; ++i) for(j = 0; j < 500; ++j) ; // Do Nothing, for sleep } return 0; } | cs |
카테고리 다른 글