#include "owi.h" #include "delay.h" #include #include "uart.h" /** * 함수명: OWI_EnablePower * 목적: 1-Wire 장치의 전원을 켠다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * - MCU 포트 P7의 1번 핀(P7.1)을 출력 모드로 설정하고 논리 HIGH(_02_Pn1_OUTPUT_1)로 설정하여 * 1-Wire 장치에 전원을 공급한다. */ void OWI_EnablePower(void) { P7 = _02_Pn1_OUTPUT_1; } /** * 함수명: OWI_DisablePower * 목적: 1-Wire 장치의 전원을 끈다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * - MCU 포트 P7의 1번 핀(P7.1)을 출력 모드로 설정하고 논리 LOW(_00_Pn1_OUTPUT_0)로 설정하여 * 1-Wire 장치에 공급되는 전원을 차단한다. */ void OWI_DisablePower(void) { P7 = _00_Pn1_OUTPUT_0; } /** * 함수명: GPIO_Clear * 목적: 1-Wire 통신에 사용하는 GPIO(P70)를 초기화하고 Low 상태로 설정한다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * - OWI_PORT_P 레지스터에서 해당 핀(OWI_PIN_MASK) 비트를 0으로 설정하여 P70을 Low로 만든다. * - OWI_PORT_PM 레지스터에서 해당 핀 비트를 0으로 설정하여 P70을 출력 모드로 설정한다. * - 결과적으로 P70 핀은 출력 모드로 Low 상태가 된다. */ void GPIO_Clear(void) { OWI_PORT_P &= ~OWI_PIN_MASK; // P70 = 0 (Low) OWI_PORT_PM &= ~OWI_PIN_MASK; // P70 출력 모드 } /** * 함수명: GPIO_Input * 목적: 1-Wire 통신에 사용하는 GPIO(P70)를 입력 모드로 설정한다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * - OWI_PORT_PM 레지스터에서 해당 핀(OWI_PIN_MASK) 비트를 1로 설정하여 P70을 입력 모드(High-Z)로 만든다. * - 출력 신호를 끄고 외부 장치로부터 신호를 읽을 준비를 한다. */ void GPIO_Input(void) { OWI_PORT_PM |= OWI_PIN_MASK; // P70 입력 모드 (High-Z) } /** * 함수명: GPIO_Read * 목적: 1-Wire 통신에 사용하는 GPIO(P70)의 현재 상태를 읽는다. * * 매개변수: 없음 * * 반환값: * - 1 : P70 핀이 High 상태일 때 * - 0 : P70 핀이 Low 상태일 때 * * 동작 방식: * - OWI_PORT_P 레지스터에서 해당 핀(OWI_PIN_MASK) 비트를 확인한다. * - 비트가 1이면 High, 0이면 Low로 판단하여 정수값으로 반환한다. * - 외부 장치에서 보내는 신호를 읽거나, 현재 GPIO 상태를 확인할 때 사용된다. */ int GPIO_Read(void) { return (OWI_PORT_P & OWI_PIN_MASK) ? 1 : 0; } /** * 함수명: OWI_Init * 목적: 1-Wire 통신을 시작하기 위해 GPIO 및 통신 속도를 초기화한다. * * 매개변수: * - bit_time_us : 1비트 전송에 걸리는 시간(마이크로초 단위) * * 반환값: 없음 (void) * * 동작 방식: * 1. bit_period_us 전역 변수에 비트 전송 시간을 저장. * 2. OWI_PORT_POM 레지스터에서 해당 핀(OWI_PIN_MASK)을 Open-drain(n-channel) 모드로 설정. * 3. OWI_PORT_PU 레지스터에서 해당 핀의 내부 풀업 저항 활성화. * 4. 초기 상태에서 GPIO를 입력 모드로 설정하여 외부 신호를 기다리는 상태로 대기. * */ void OWI_Init(uint32_t bit_time_us) { bit_period_us = bit_time_us; OWI_PORT_POM |= OWI_PIN_MASK; // Open-drain (n-channel) OWI_PORT_PU |= OWI_PIN_MASK; // 내부 풀업 활성화 GPIO_Input(); // 초기엔 입력으로 대기 } // ---------------------------------------- // OWI Start/Stop/Secure // ---------------------------------------- /** * 함수명: OWI_Start * 목적: 1-Wire 통신에서 Start 신호를 발생시켜 통신을 시작한다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * 1. GPIO_Clear() 호출: P70 핀을 Low 상태로 설정하여 Start 신호를 준비. * 2. delay_us(TSTART_HOLD): Start 신호를 일정 시간 유지. * 3. GPIO_Input() 호출: 핀을 입력 모드(High-Z)로 전환하여 외부 장치가 반응하도록 대기. * 4. delay_us(TBIT / 2): 반비트 시간만큼 대기하여 1-Wire 타이밍 맞춤. * */ void OWI_Start(void) { GPIO_Clear(); delay_us(TSTART_HOLD); GPIO_Input(); delay_us(TBIT / 2); } /** * 함수명: OWI_Stop * 목적: 1-Wire 통신을 종료하고 통신 라인을 정리한다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * 1. GPIO_Input() 호출: 핀을 입력 모드(High-Z)로 설정하여 초기 상태로 대기. * 2. delay_us(TSTOP_LOW): Stop 조건을 만족시키기 위해 일정 시간 대기. * 3. delay_us(TIDLE): 통신 라인을 안정화시키기 위해 추가 지연. * 4. GPIO_Clear() 호출: 핀을 Low로 초기화하여 다음 통신 준비. * */ void OWI_Stop(void) { GPIO_Input(); delay_us(TSTOP_LOW); delay_us(TIDLE); GPIO_Clear(); } /** * 함수명: OWI_SecureStop * 목적: 1-Wire 통신 종료 시 라인을 안전하게 토글하여 슬레이브가 확실히 종료 상태를 인식하도록 한다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * 1. GPIO_Clear() 호출 후 SECURE_HIGH 시간만큼 지연: 라인을 Low 상태로 초기화. * 2. SECURE_TOGGLE_COUNT만큼 반복: * - GPIO_Input()로 라인을 High-Z 상태로 설정 후 SECURE_TOGGLE_HIGH 시간 대기. * - GPIO_Clear()로 라인을 Low 상태로 설정 후 SECURE_TOGGLE_LOW 시간 대기. * - 이 과정을 통해 슬레이브가 안전하게 라인 종료를 감지. * 3. GPIO_Input() → SECURE_HIGH 지연 → GPIO_Clear() → TSTART_HOLD 지연 → GPIO_Input() 호출: * - 라인을 초기 상태로 복귀시켜 다음 통신 준비 완료. * */ void OWI_SecureStop(void) { int i; GPIO_Clear(); delay_us(SECURE_HIGH); for (i = 0; i < SECURE_TOGGLE_COUNT; i++) { GPIO_Input(); delay_us(SECURE_TOGGLE_HIGH); GPIO_Clear(); delay_us(SECURE_TOGGLE_LOW); } GPIO_Input(); delay_us(SECURE_HIGH); GPIO_Clear(); delay_us(TSTART_HOLD); GPIO_Input(); } // ---------------------------------------- // OWI Bit/Byte Write & Read // ---------------------------------------- /** * 함수명: OWI_WriteBit * 목적: 1-Wire 통신 라인을 통해 단일 비트(bit)를 송신한다. * * 매개변수: * - bit : 전송할 비트 값 (0 또는 1) * * 반환값: 없음 (void) * * 동작 방식: * 1. 전송할 비트에 따라 Low 상태 유지 시간(t_low)을 결정: * - bit가 1이면 TLOW_1, 0이면 TLOW_0 * 2. t_high = TBIT - t_low 계산: 비트 프레임에서 High 유지 시간 결정. * 3. GPIO_Input() 호출: 라인을 풀업 상태(High-Z)로 유지. * 4. delay_us(t_high): High 상태 유지. * 5. GPIO_Clear() 호출: 라인을 Low 상태로 드라이브. * 6. delay_us(t_low): Low 상태 유지. * */ void OWI_WriteBit(int bit) { uint32_t t_low = bit ? TLOW_1 : TLOW_0; uint32_t t_high = TBIT - t_low; GPIO_Input(); // 풀업 상태 유지 delay_us(t_high); // High 유지 GPIO_Clear(); // Low로 드라이브 delay_us(t_low); // Low 시간 유지 } /** * 함수명: OWI_WriteByte * 목적: 1-Wire 통신 라인을 통해 1바이트 데이터를 전송한다. * * 매개변수: * - data : 전송할 1바이트 데이터(uint8_t) * * 반환값: 없음 (void) * * 동작 방식: * 1. 최상위 비트(MSB)부터 최하위 비트(LSB)까지 반복: * - 각 비트를 OWI_WriteBit() 함수를 통해 송신. * - (data >> i) & 0x01 연산으로 i번째 비트 추출. * 2. 모든 8비트를 전송한 후 GPIO_Input() 호출: * - 라인을 High-Z 상태로 전환하여 다음 통신 준비. * */ void OWI_WriteByte(uint8_t data) { int i; for (i = 7; i >= 0; i--) { OWI_WriteBit((data >> i) & 0x01); } GPIO_Input(); } /** * 함수명: OWI_ReadBit * 목적: 1-Wire 통신 라인에서 단일 비트를 읽는다. * * 매개변수: 없음 * * 반환값: * - 0 또는 1 : 읽은 비트 값 * - 0xFF : 타임아웃 발생 시 에러 값 * * 동작 방식: * 1. GPIO_Read()를 사용하여 라인이 High가 될 때까지 대기: * - 최대 500us까지 대기(timeout). * - 타임아웃 시 UART로 오류 메시지 전송 후 0xFF 반환. * 2. delay_us(50) 호출하여 비트 중앙 위치로 대기. * 3. GPIO_Read()로 비트 값 판독. * 4. delay_us(30)으로 나머지 비트 시간 동안 대기. * 5. 판독한 비트 값을 반환. * */ uint8_t OWI_ReadBit(void) { uint8_t bit; int timeout = 500; while (!(GPIO_Read()) && timeout-- > 0) { delay_us(1); } if (timeout <= 0) { uart_send_string("OWI Timeout\r\n"); return 0xFF; } delay_us(50); bit = GPIO_Read(); delay_us(30); return bit; } /** * 함수명: OWI_ReadByte * 목적: 1-Wire 통신 라인에서 1바이트 데이터를 읽는다. * * 매개변수: 없음 * * 반환값: * - 읽은 1바이트 데이터(uint8_t) * * 동작 방식: * 1. 최상위 비트(MSB)부터 최하위 비트(LSB)까지 반복: * - OWI_ReadBit() 함수를 호출하여 1비트씩 읽는다. * - 읽은 비트를 적절히 시프트하여 data 변수에 저장. * 2. 모든 8비트를 읽은 후 data 반환. * */ uint8_t OWI_ReadByte(void) { uint8_t data = 0; int i; for (i = 7; i >= 0; i--) { data |= (OWI_ReadBit() << i); } return data; } /** * 함수명: OWI_T_ReadBytesAndPrint * 목적: 1-Wire 통신으로 지정한 길이만큼 데이터를 읽고, UART로 형식화하여 출력한다. * * 매개변수: * - length : 읽을 데이터 바이트 수 * * 반환값: 없음 (void) * * 동작 방식: * 1. buf 배열에 length만큼 OWI_ReadByte() 호출하여 1바이트씩 읽어 저장. * 2. 첫 번째 바이트(buf[0])를 16진수 2자리 문자열로 변환하여 UART 전송. * 3. 그 이후 바이트들은 두 개씩 묶어서 16진수 4자리 문자열로 변환 후 UART 전송: * - delay(10000) 호출하여 출력 간 간격을 둠. * 4. UART 출력은 sprintf → strcpy → uart_send_string 순으로 처리. * * 참고: * - buf[0]는 별도로 출력하고, 이후 바이트들은 2바이트 단위로 묶어 출력. * - delay를 통해 슬레이브와 UART 전송 간 타이밍을 확보. * - 1-Wire 데이터를 확인하거나 디버깅용으로 사용되는 함수. */ void OWI_T_ReadBytesAndPrint(int length) { uint8_t buf[129]; int i; char uart_buf[8]; char tmp_buf[8]; uint8_t va0, va1; for (i = 0; i < length; i++) { buf[i] = OWI_ReadByte(); } sprintf(uart_buf, "%02X ", buf[0]); strcpy(tmp_buf, uart_buf); uart_send_string(tmp_buf); for (i = 1; i < length; i+=2) { va0 = buf[i]; va1 = buf[i+1]; delay(10000); sprintf(uart_buf, "%02X%02X ", va0, va1); strcpy(tmp_buf, uart_buf); uart_send_string(tmp_buf); delay(10000); } } /** * 함수명: OWI_A_CommandMode * 목적: 1-Wire 장치에서 ADC 데이터 및 명령어(CMD)를 처리하고 결과를 UART로 출력한다. * * 매개변수: * - tx_data : 사용자 전송 데이터 포인터 (3바이트) * - tx_len : 사용자 전송 데이터 길이 * - id : 장치 ID * * 반환값: 없음 (void) * * 동작 방식: * 1) ADC 읽기 * - ADC_ReadAndSend_UART() 호출하여 ADC 데이터를 읽음. * - g_adc_bytes 배열을 읽고 2자리 소수점 형식으로 line 배열에 저장. * - ADC 채널 수 불일치 시 "Err:adc_count" 출력 후 종료. * * 2) 1-Wire 장치 전원 켜기 * - OWI_EnablePower() 호출. * - 전원 안정화를 위해 7ms 지연. * * 3) 기본 명령(CMD) 전송 및 안전한 읽기 * - CMD_LIST에 정의된 6개의 4바이트 명령을 순차적으로 전송. * - 각 명령 전/후에 OWI_SecureStop() 호출하여 통신 라인을 초기화. * - 각 명령 실행 후 read_address(0x51)로 데이터를 읽음. * - 읽은 데이터가 모두 0xFF일 경우 최대 OWI_MAX_RETRY만큼 재시도. * - 읽은 Rx 데이터에서 2번째, 3번째 바이트를 line 배열에 16진수로 추가. * * 4) 사용자 CMD 처리 (tx_data 존재 시) * - tx_len가 3바이트인 경우 ID를 포함한 write 후 read 수행. * - Rx 데이터 모두 0xFF일 경우 OWI_MAX_RETRY 재시도. * - 정상 데이터 수신 시 line 배열에 2번째, 3번째 바이트 추가. * - tx_data가 없으면 "0000"을 line 배열에 추가. * * 5) UART 출력 * - 완성된 line 배열 끝에 CRLF 추가 후 uart_send_string()로 전송. * * 6) 마무리 * - delay(10000) 후 OWI_DisablePower() 호출하여 장치 전원 차단. * * 참고: * - OWI_SecureStop() 및 delay_us()를 통해 1-Wire 통신 타이밍과 안정성을 확보. * - g_adc_bytes, RAM_BYTES, OWI_MAX_RETRY 등의 상수 및 전역 변수 활용. * - UART로 출력되는 형식은 ADC값, 각 CMD 결과, 사용자 CMD 결과가 쉼표로 구분됨. */ #define OWI_MAX_RETRY 2 // 재시도 2회 #define OWI_RECOVERY_MIN_US 500 // datasheet 기준 최소 recovery 시간 void OWI_A_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id) { uint8_t CMD_LIST[6][4] = { {0x50,0x2E,0x00,0x00}, // BR {0x50,0x2E,0x01,0x00}, // BR_AZ {0x50,0x2E,0x02,0x00}, // T_RAW {0x50,0x2E,0x16,0x00}, // Y_data {0x50,0x2E,0x41,0x00}, // BR_AOUT {0x50,0x2E,0x00,0x00} // BR_AOUT duplicate }; char line[128]; size_t n = 0; uint8_t rx[RAM_BYTES]; int i, j, retry, all_ff; float v; uint8_t read_address = 0x51; // ===== 1) ADC 읽기 ===== ADC_ReadAndSend_UART(); if (g_adc_len != ADC_NUM_CH) { uart_send_string("Err:adc_count\r\n"); return; } for (j = 0; j < g_adc_len; j++) { v = g_adc_bytes[j]; n += sprintf(&line[n], "%.2f", v); if (j + 1 < g_adc_len) line[n++] = ','; } line[n++] = ','; // ===== 2) OWI Power On ===== OWI_EnablePower(); delay_us(7000); // Power-on delay // ===== 3) CMD 전송 및 안전한 읽기 ===== for (j = 0; j < 6; j++) { OWI_SecureStop(); for (i = 0; i < 4; i++) OWI_WriteByte(CMD_LIST[j][i]); OWI_Stop(); // CMD → read 회복 시간 delay_us(OWI_RECOVERY_MIN_US); // Rx 초기화 for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF; for (retry = 0; retry <= OWI_MAX_RETRY; retry++) { // read 전 충분한 recovery 확보 delay_us(OWI_RECOVERY_MIN_US); OWI_SecureStop(); OWI_WriteByte(read_address); for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte(); OWI_Stop(); all_ff = 1; for (i = 0; i < RAM_BYTES; i++) { if (rx[i] != 0xFF) { all_ff = 0; break; } } if (!all_ff) break; // 정상 데이터 수신 if (retry == OWI_MAX_RETRY) { // 모든 재시도 실패 OWI_DisablePower(); return; } } n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]); line[n++] = ','; } // ===== 4) 사용자 CMD 처리 ===== if (tx_data != NULL && tx_len == 3) { for (retry = 0; retry <= OWI_MAX_RETRY; retry++) { // write CMD OWI_SecureStop(); OWI_WriteByte(id << 1); for (i = 0; i < 3; i++) OWI_WriteByte(tx_data[i]); OWI_Stop(); // read 준비 delay_us(OWI_RECOVERY_MIN_US); // read for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF; OWI_SecureStop(); OWI_WriteByte((id << 1) | 1); for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte(); OWI_Stop(); all_ff = 1; for (i = 0; i < RAM_BYTES; i++) { if (rx[i] != 0xFF) { all_ff = 0; break; } } if (!all_ff) break; if (retry == OWI_MAX_RETRY) { OWI_DisablePower(); return; } } n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]); } else { n += sprintf(&line[n], "0000"); } // ===== 5) UART 출력 ===== line[n++] = '\r'; line[n++] = '\n'; line[n] = '\0'; uart_send_string(line); delay(10000); OWI_DisablePower(); } /** * 함수명: OWI_Diagnostic * 목적: 1-Wire 장치에서 진단용 명령어를 전송하고 결과를 UART로 출력한다. * * 매개변수: * - id : 장치 ID (사용되지 않지만 인터페이스 일관성 유지) * * 반환값: 없음 (void) * * 동작 방식: * 1) CMD_LIST에 정의된 10개의 4바이트 진단 명령어를 순차적으로 전송. * - OWI_SecureStop() 호출로 통신 라인 초기화. * - 각 명령 전송 후 OWI_Stop() 호출. * - OWI_RECOVERY_MIN_US 동안 지연하여 장치 준비 시간 확보. * * 2) 각 명령어 수행 후 read_address(0x51)로 데이터를 읽음. * - Rx 배열 초기화(0xFF) 후 OWI_ReadByte()로 데이터 수신. * - 읽은 데이터가 모두 0xFF일 경우 최대 OWI_MAX_RETRY만큼 재시도. * * 3) 정상 데이터 수신 시 rx[1], rx[2] 바이트를 16진수로 line 배열에 추가. * - 마지막 명령어가 아니면 콤마(,) 추가. * * 4) UART 출력 * - line 배열 끝에 CRLF 추가 후 uart_send_string()으로 전송. * * 참고: * - OWI_SecureStop() 및 delay_us()를 통해 1-Wire 통신 안정성을 확보. * - 이 함수는 장치의 상태 진단 및 디버깅용으로 사용됨. */ void OWI_Diagnostic(uint8_t id) { uint8_t CMD_LIST[10][4] = { {0x50,0x2E,0x01,0x00}, // BR {0x50,0x2E,0x00,0x00}, // BR_AZ {0x50,0x2E,0x02,0x00}, // T_RAW {0x50,0x2E,0x03,0x00}, // Y_data {0x50,0x2E,0x21,0x00}, // BR_AOUT {0x50,0x2E,0x04,0x00}, {0x50,0x2E,0x05,0x00}, {0x50,0x2E,0x07,0x00}, {0x50,0x2E,0x19,0x00}, {0x50,0x2E,0x0B,0x00} }; char line[128]; size_t n = 0; uint8_t rx[RAM_BYTES]; int i, j, retry, all_ff; float v; uint8_t read_address = 0x51; // ===== 3) CMD 전송 및 안전한 읽기 ===== for (j = 0; j < 10; j++) { OWI_SecureStop(); for (i = 0; i < 4; i++) OWI_WriteByte(CMD_LIST[j][i]); OWI_Stop(); // CMD → read 회복 시간 delay_us(OWI_RECOVERY_MIN_US); // Rx 초기화 for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF; for (retry = 0; retry <= OWI_MAX_RETRY; retry++) { // read 전 충분한 recovery 확보 delay_us(OWI_RECOVERY_MIN_US); OWI_SecureStop(); OWI_WriteByte(read_address); for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte(); OWI_Stop(); all_ff = 1; for (i = 0; i < RAM_BYTES; i++) { if (rx[i] != 0xFF) { all_ff = 0; break; } } if (!all_ff) break; // 정상 데이터 수신 if (retry == OWI_MAX_RETRY) { // 모든 재시도 실패 OWI_DisablePower(); return; } } // 데이터 추가 n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]); // 마지막이 아닐 때만 콤마 추가 if (j < 9) { line[n++] = ','; } } // ===== 5) UART 출력 ===== line[n++] = '\r'; line[n++] = '\n'; line[n] = '\0'; uart_send_string(line); delay(10000); } /** * 함수명: OWI_disable * 목적: 1-Wire 장치 전원을 끄고, UART로 상태를 알린다. * * 매개변수: 없음 * * 반환값: 없음 (void) * * 동작 방식: * 1) OWI_DisablePower() 호출하여 1-Wire 장치 전원 차단. * 2) UART로 "51" 문자열과 CRLF 전송하여 장치가 종료되었음을 표시. * * 참고: * - 장치 종료 후 외부 장치나 사용자에게 상태 알림용으로 UART 출력. */ void OWI_disable() { OWI_DisablePower(); uart_send_string("51\r\n"); } /** * 함수명: OWI_T_CommandMode * 목적: 1-Wire 장치에 명령어를 전송하고, UART로 완료 상태를 출력한다. * * 매개변수: * - tx_data : 전송할 명령 데이터 배열 * - tx_len : 전송할 명령 데이터 길이 * - id : 1-Wire 장치 ID (슬레이브 주소) * * 반환값: 없음 (void) * * 동작 방식: * 1) 1-Wire 장치 전원 켜기 * - OWI_EnablePower() 호출 * - 전원 안정화를 위해 7ms 지연 * * 2) 1-Wire 초기화 * - OWI_Init() 호출하여 통신 비트 주기 설정 * * 3) 명령 전송 (Write sequence) * - OWI_SecureStop() 호출로 통신 라인 초기화 * - 슬레이브 주소(id << 1)를 전송 (쓰기 모드) * - tx_data 배열에 있는 명령 데이터를 순차적으로 전송 * - OWI_Stop() 호출하여 쓰기 종료 * * 4) UART 출력 * - "51" 문자열 전송하여 명령 전송 완료 상태 알림 * * 참고: * - 이 함수는 단순히 명령어 전송만 수행하며, 데이터 읽기는 수행하지 않는다. * - OWI_SecureStop()와 OWI_Stop()을 사용해 1-Wire 통신 안정성을 확보. */ void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id) { uint8_t rx[3] = {0}; char uart_buf[16]; int i; OWI_EnablePower(); delay_us(7000); // Power-on delay OWI_Init(OWI_BIT_PERIOD_US); // Write sequence (슬레이브 주소와 명령 전송) OWI_SecureStop(); // 통신 준비 OWI_WriteByte(id << 1); // 슬레이브 write 주소 for (i = 0; i < tx_len; i++) { OWI_WriteByte(tx_data[i]); // 명령 전송 } OWI_Stop(); // 쓰기 종료 uart_send_string("51\r\n"); } /** * 함수명: OWI_CommandMode * 목적: 1-Wire 장치에 명령어를 전송하고, UART로 완료 상태를 출력한다. * * 매개변수: * - tx_data : 전송할 명령 데이터 배열 * - tx_len : 전송할 명령 데이터 길이 * - id : 1-Wire 장치 ID (슬레이브 주소) * * 반환값: 없음 (void) * * 동작 방식: * 1) 명령 전송 (Write sequence) * - OWI_SecureStop() 호출로 통신 라인 초기화 * - 슬레이브 주소(id << 1)를 전송 (쓰기 모드) * - tx_data 배열에 있는 명령 데이터를 순차적으로 전송 * - OWI_Stop() 호출하여 쓰기 종료 * * 2) UART 출력 * - "51" 문자열 전송하여 명령 전송 완료 상태 알림 * * 참고: * - 전원 켜기/통신 초기화 단계는 포함되어 있지 않음 * - 이 함수는 단순히 명령어 전송만 수행하며, 데이터 읽기는 수행하지 않는다 * - OWI_SecureStop()와 OWI_Stop()을 사용해 1-Wire 통신 안정성을 확보 */ void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id) { uint8_t rx[3] = {0}; char uart_buf[16]; int i; // Write sequence (슬레이브 주소와 명령 전송) OWI_SecureStop(); // 통신 준비 OWI_WriteByte(id << 1); // 슬레이브 write 주소 for (i = 0; i < tx_len; i++) { OWI_WriteByte(tx_data[i]); // 명령 전송 } OWI_Stop(); // 쓰기 종료 uart_send_string("51\r\n"); } /** * 함수명: OWI_ReadBytesAndPrint * 목적: 1-Wire 장치에서 지정된 길이만큼 데이터를 읽고, UART로 출력한다. * * 매개변수: * - length : 읽을 바이트 수 * - id : 1-Wire 장치 ID (슬레이브 주소) * * 반환값: 없음 (void) * * 동작 방식: * 1) 읽기 시작 * - OWI_SecureStop() 호출로 통신 라인 초기화 * - (id << 1) | 1 전송하여 슬레이브 읽기 모드 설정 * * 2) 지정된 length만큼 OWI_ReadByte()로 데이터 읽기 * - 읽은 데이터는 buf 배열에 저장 * * 3) UART 출력 * - buf[0] 단독 출력 * - 이후 1번부터는 두 바이트씩 페어로 묶어 출력 * - 마지막 바이트가 홀수이면 단독 출력 * - 각 출력 전후에 delay(10000) 호출 (UART 전송 안정성 확보) * - 출력 포맷: 16진수 문자열 * - 마지막에 CRLF("\r\n") 추가 * * 참고: * - UART 출력 시 임시 버퍼(uart_buf, tmp_buf)를 사용 * - delay를 통해 데이터 안정성 및 가독성 확보 */ void OWI_ReadBytesAndPrint(int length, uint8_t id) { uint8_t buf[600]; int i; char uart_buf[8]; char tmp_buf[8]; uint8_t va0, va1; OWI_SecureStop(); OWI_WriteByte((id << 1) | 1); for (i = 0; i < length; i++) { buf[i] = OWI_ReadByte(); } sprintf(uart_buf, "%02X ", buf[0]); strcpy(tmp_buf, uart_buf); uart_send_string(tmp_buf); for (i = 1; i < length; i += 2) { va0 = buf[i]; if (i + 1 < length) { // 완전한 페어 va1 = buf[i + 1]; delay(10000); sprintf(uart_buf, "%02X%02X ", va0, va1); strcpy(tmp_buf, uart_buf); uart_send_string(tmp_buf); delay(10000); } else { // 마지막 1바이트가 남은 경우 단독 출력 delay(10000); sprintf(uart_buf, "%02X", va0); strcpy(tmp_buf, uart_buf); uart_send_string(tmp_buf); delay(10000); } } uart_send_string("\r\n"); }