You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.5 KiB
182 lines
4.5 KiB
|
10 hours ago
|
#include "uart.h"
|
||
|
|
#include "delay.h"
|
||
|
|
#include "r_cg_adc.h"
|
||
|
|
#include "r_cg_port.h"
|
||
|
|
|
||
|
|
#define RS485_EN_PORT P4
|
||
|
|
#define RS485_EN_PM PM4
|
||
|
|
#define RS485_EN_MASK (0x20U) // P4.5
|
||
|
|
|
||
|
|
float g_adc_bytes[ADC_NUM_CH] = {0.0f};
|
||
|
|
uint8_t g_adc_len = 0;
|
||
|
|
|
||
|
|
void rs485_set_tx(uint8_t on)
|
||
|
|
{
|
||
|
|
if (on) RS485_EN_PORT |= RS485_EN_MASK; // EN=1 (TX)
|
||
|
|
else RS485_EN_PORT &= (uint8_t)~RS485_EN_MASK; // EN=0 (RX)
|
||
|
|
}
|
||
|
|
|
||
|
|
void rs485_init(void)
|
||
|
|
{
|
||
|
|
RS485_EN_PM &= (uint8_t)~RS485_EN_MASK; // 출력
|
||
|
|
rs485_set_tx(0); // 기본 RX 모드
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 함수명: uart_send_string
|
||
|
|
* 목적: null 종료된 문자열을 UART0로 전송
|
||
|
|
*
|
||
|
|
* 매개변수:
|
||
|
|
* - str : 전송할 문자열 (C 문자열, '\0'로 종료)
|
||
|
|
*
|
||
|
|
* 반환값: 없음 (void)
|
||
|
|
*
|
||
|
|
* 동작 방식:
|
||
|
|
* 1) 문자열 길이 계산
|
||
|
|
* - 문자열 끝을 나타내는 '\0'이 나올 때까지 len 증가
|
||
|
|
*
|
||
|
|
* 2) UART 전송
|
||
|
|
* - R_UART0_Send() 함수를 사용하여 계산한 길이만큼 문자열 전송
|
||
|
|
* - (uint8_t *)로 캐스팅하여 바이트 배열 형식 전달
|
||
|
|
*
|
||
|
|
* 참고:
|
||
|
|
* - null 문자('\0')는 전송되지 않음
|
||
|
|
* - UART0 초기화와 전송 준비는 별도로 되어 있어야 함
|
||
|
|
*/
|
||
|
|
|
||
|
|
// UART0(RS485)
|
||
|
|
void uart_send_string(const char *str)
|
||
|
|
{
|
||
|
|
uint16_t len = 0;
|
||
|
|
while (str[len] != '\0') len++;
|
||
|
|
|
||
|
|
rs485_set_tx(1);
|
||
|
|
R_UART0_Send((uint8_t *)str, len);
|
||
|
|
}
|
||
|
|
|
||
|
|
// UART1(PC)
|
||
|
|
void uart1_send_string(const char *str)
|
||
|
|
{
|
||
|
|
uint16_t len = 0;
|
||
|
|
while (str[len] != '\0') len++;
|
||
|
|
R_UART1_Send((uint8_t *)str, len);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 함수명: uart_send_hex
|
||
|
|
* 목적: 8비트 값(uint8_t)을 16진수 문자열로 변환 후 UART0로 전송
|
||
|
|
*
|
||
|
|
* 매개변수:
|
||
|
|
* - val : 전송할 8비트 값
|
||
|
|
*
|
||
|
|
* 반환값: 없음 (void)
|
||
|
|
*
|
||
|
|
* 동작 방식:
|
||
|
|
* 1) 상위/하위 4비트 분리
|
||
|
|
* - high = val >> 4, 상위 4비트
|
||
|
|
* - low = val & 0x0F, 하위 4비트
|
||
|
|
*
|
||
|
|
* 2) 16진수 문자로 변환
|
||
|
|
* - 0~9 → '0'~'9'
|
||
|
|
* - 10~15 → 'A'~'F'
|
||
|
|
* - hex[0] = 상위 4비트 문자
|
||
|
|
* - hex[1] = 하위 4비트 문자
|
||
|
|
*
|
||
|
|
* 3) UART 전송
|
||
|
|
* - R_UART0_Send()를 사용해 2바이트 전송
|
||
|
|
*
|
||
|
|
* 4) 전송 후 지연
|
||
|
|
* - delay(10000)으로 약간의 전송 간격 확보
|
||
|
|
*
|
||
|
|
* 참고:
|
||
|
|
* - 이 함수는 1바이트 값을 항상 2자리 16진수로 표현
|
||
|
|
* - 예: val = 0xAF → "AF" 전송
|
||
|
|
*/
|
||
|
|
void uart_send_hex(uint8_t val)
|
||
|
|
{
|
||
|
|
uint8_t hex[2];
|
||
|
|
uint8_t high = (val >> 4) & 0x0F;
|
||
|
|
uint8_t low = val & 0x0F;
|
||
|
|
|
||
|
|
hex[0] = (high < 10) ? ('0' + high) : ('A' + (high - 10));
|
||
|
|
hex[1] = (low < 10) ? ('0' + low) : ('A' + (low - 10));
|
||
|
|
|
||
|
|
rs485_set_tx(1);
|
||
|
|
R_UART0_Send(hex, 2);
|
||
|
|
delay(10000);
|
||
|
|
}
|
||
|
|
|
||
|
|
void uart1_send_hex(uint8_t val)
|
||
|
|
{
|
||
|
|
uint8_t hex[2];
|
||
|
|
uint8_t high = (val >> 4) & 0x0F;
|
||
|
|
uint8_t low = val & 0x0F;
|
||
|
|
|
||
|
|
hex[0] = (high < 10) ? ('0' + high) : ('A' + (high - 10));
|
||
|
|
hex[1] = (low < 10) ? ('0' + low ) : ('A' + (low - 10));
|
||
|
|
|
||
|
|
R_UART1_Send(hex, 2);
|
||
|
|
delay(10000);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 함수명: ADC_ReadAndSend_UART
|
||
|
|
* 목적: 여러 ADC 채널을 읽고 전압으로 변환하여 전역 배열에 저장
|
||
|
|
*
|
||
|
|
* 동작 방식:
|
||
|
|
* 1) ADC 채널 배열 정의
|
||
|
|
* - ADC_NUM_CH 개수만큼 읽을 채널 지정
|
||
|
|
* - 예: {0x02, 0x03, 0x04, 0x05}
|
||
|
|
*
|
||
|
|
* 2) 각 채널 순차적으로 읽기
|
||
|
|
* for (i = 0; i < ADC_NUM_CH; i++)
|
||
|
|
* a) ADS 레지스터에 채널 선택
|
||
|
|
* b) R_ADC_Start()로 변환 시작
|
||
|
|
* c) 변환 완료 대기 (ADIF == 1 될 때까지)
|
||
|
|
* d) ADIF 플래그 클리어
|
||
|
|
* e) 변환 값 읽기: R_ADC_Get_Result(&adc_value)
|
||
|
|
* f) ADC 정지: R_ADC_Stop()
|
||
|
|
*
|
||
|
|
* 3) ADC 값을 전압으로 변환
|
||
|
|
* - voltage = (adc_value / ADC_RESOLUTION) * VREF
|
||
|
|
* - 예: 12bit ADC, VREF = 5V이면 0~4095 → 0~5V 변환
|
||
|
|
*
|
||
|
|
* 4) 전역 배열에 저장
|
||
|
|
* - g_adc_bytes[i] = voltage
|
||
|
|
* - g_adc_len 증가
|
||
|
|
*
|
||
|
|
* 참고:
|
||
|
|
* - g_adc_bytes[]: 변환된 전압 저장용 전역 배열
|
||
|
|
* - g_adc_len: 현재 읽은 채널 수
|
||
|
|
*/
|
||
|
|
void ADC_ReadAndSend_UART(void)
|
||
|
|
{
|
||
|
|
static const uint8_t ADC_CHANNELS[ADC_NUM_CH] = { 0x02,0x03,0x04,0x05};
|
||
|
|
|
||
|
|
uint16_t adc_value;
|
||
|
|
float voltage;
|
||
|
|
int i;
|
||
|
|
|
||
|
|
g_adc_len = 0;
|
||
|
|
|
||
|
|
for (i = 0; i < ADC_NUM_CH; i++) {
|
||
|
|
ADS = ADC_CHANNELS[i]; // 채널 선택
|
||
|
|
R_ADC_Start(); // 변환 시작
|
||
|
|
while (ADIF == 0U); // 변환 완료 대기
|
||
|
|
ADIF = 0U;
|
||
|
|
|
||
|
|
R_ADC_Get_Result(&adc_value);
|
||
|
|
R_ADC_Stop();
|
||
|
|
|
||
|
|
/* V 계산 */
|
||
|
|
voltage = (adc_value / ADC_RESOLUTION) * VREF;
|
||
|
|
|
||
|
|
g_adc_bytes[i] = voltage;
|
||
|
|
g_adc_len++;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|