LIN 통신 기능이 없는 마이크로프로세서에서의 LIN2.0 프로그래밍 강좌
본 강좌에서는 대부분의 마이크로프로세서에서와 같이 LIN Function 뿐만 아니라 BREAK/SYNC 기능도 없는 마이크로프로세서를 대상으로 LIN 2.0 슬레이브 노드 프로그래밍의 작성에 대하여 설명한다.
LIN 2.0을 구현하기 위한 마이크로프로세서의 resource는 UART, 3개의 timer(프레임 시간 초과 감시용 1개, input capture 할당 1개, sleep 시간 측정용(범용, 타 기능과 겸용) 1개)와 input capture가 필요하다. Input capture는 SYNC 신호를 수신하여 baud rate를 계산하기 위하여 필요하다. (마스터에는 필요 없다.)
Input capture 기능이 없는 경우, 외부 인터럽트를 사용을 고려할 수 있으나, interrupt latency로 인하여 오차가 발생한다. 이 오차를 LIN 규정 이내로 억제할 수 있다면 외부 인터럽트도 사용 가능할 것으로 생각되나 추천하는 방법은 아니며 본 강좌는 input capture를 사용하는 것으로 가정한다. Interrupt latency는 각자 사용하고자하는 프로세서의 스펙 문서를 참조하기 바란다.
Input capture를 이용하여 baud rate를 계산하기 위한 슬레이브 회로는 아래 그림과 같다.
LIN 통신은 BREAK와 SYNC 신호로 시작된다.
● 마스터에서는
- BREAK의 송신은 baud rate를 정상속도보다 낮춰서 0x00을 송신한다.
- start bit와 data bit 합하여 9 bit가 0으로 출력된다.
- 정상 속도에서는 13 bit time 이상 0이 유지되어야하므로
- (BREAK 전송 baud rate) =< (정상 baud rate)*9/13
- Tip : 간단히 전송 속도를 1/2로 낮춰서 0을 전송한다.(baud rate >>= 1; )
- SYNC 신호는 baud rate를 정상 속도로 복구한 뒤 0x55를 송신한다.
● 슬레이브에서는
- 마스터의 전송 속도를 모르므로 BREAK 신호 수신 이전에 baud rate를 최고속도(20kbps)로 설정하고, UART 수신 인터럽트를 enable로 설정한다.
- 수신 인터럽트에서 UART 상태 레지스터에 Frame Error 비트를 검사하여 에러가 발생하였는지를 검사한다.
- Frame Error가 발생하고, 수신 데이터가 0x00이면 9.5 bit-time 이상 도미넌트가 유지된 것이므로 BREAK 신호로 판단한다.
- BREAK가 수신되면 즉시 UART는 disable로 설정하고,
- Input Capture 기능을 falling edge에서 interrupt가 발생하도록 설정한다.
- Input Capture는 SYNC 신호에서 첫 falling edge와 5번째 falling edge의 발생 시각을 저장한다.
- 두 시각의 차이로 baud rate를 계산한다.
- Tip : input capture가 참조하는 timer의 prescale을 baud rate generator의 1/4로 설정하면 시간차를 4로 나누면 baud rate가 된다.(input capture 참조 timer의 정밀도를 baud rate generator 보다 4배가 되도록 설정한다.)
- UART를 계산된 baud rate로 변경 설정한 다음, UART 인터럽트를 enable로 설정하여 PID 프레임의 수신에 대비한다.
void main(void){
...
//initialize session
baud_rate = 20000;
UART_RX_interrupt = ENABLE;
input_capture_interrupt = disable;
...
}
int edge_count; // input capture에서 falling edge event 수 카운트
unsigned int t1, t5; // falling edge 이벤트가 발생한 시간 저장
interrupt_service_routine UART_RX(void)
{
if (RX_FRAME_ERROR)
{
if (RX_BUFFER == 0) //BREAK 수신
{
UART_RX_interrupt = DISABLE; // SYNC 신호는 input capture에서 처리한다.
input_capture_mode = FALLING_EDGE;
input_capture_timer_prescale = 4*baud_rate_generator;
input_capture_buffer = EMPTY; // input capture buffer를 비운다.
edge_count = 0; // 변수 초기화
input_capture_interrupt = ENABLE;
}
}
}
interrupt_service_routine INPUT_CAPTURE(void)
{
edge_count++;
if (edge_count == 1)
t1 = input_capture_buffer;
else if (degd_count == 5)
{
t5 = input_capture_buffer;
baud_rate = (t5 - t1) >> 2; // baud_rate 계산 완료
// input capture 종료 && UART 복구
input_capture_interrupt = DISABLE;
UART_RX_interrupt = ENABLE;
}
else{
input capture_buffer; // 버퍼 비움
}
}
위의 의사(pseudo) 코드에서 input capture로 SYNC를 수신하여 baud rate를 계산한 후, UART로 복귀할 때에 주의해야한다. UART는 에지 검출이 아니고 레벨 검출이다. 위의 코드에서와 같이 다섯번 째 input capture interrupt에서 baud rate를 계산하고 바로 UART를 enable하면, RX 입력 포트의 레벨이 low이므로 UART는 start bit로 인식한다. 따라서 PID 프레임이 정상적으로 수신되지 않고, 항상 잘못된 데이터가 수신되거나 프레임 에러가 발생한다.
이를 방지하려면 SYNC의 t5와 stop bit 사이의 상승 에지를 검출하여 레벨이 high일 때, UART를 enable해야한다. 따라서 t5 직후 input capture 모드를 rising edge로 전환하고, input capture 이벤트를 한 번 더 기다렸다가 UART를 enable한다.
따라서 input capture 인터럽트 서비스 루틴은 다음과 같이 수정되어야 한다.
interrupt_service_routine INPUT_CAPTURE(void)
{
edge_count++;
if (edge_count == 1)
t1 = input_capture_buffer;
else if (degd_count == 5)
{
t5 = input_capture_buffer;
baud_rate = (t5 - t1) >> 2; // baud_rate 계산 완료
//stop bit 검출
input_capture_mode = RISING_EDGE;
}
else if (edge_count >= 6)
{
// input capture 종료 && UART 복구
input_capture_interrupt = DISABLE;
UART_RX_interrupt = ENABLE;
}
else{
input capture_buffer = EMPTY; // 버퍼 비움
}
}
'LIN 2.0' 카테고리의 다른 글
LIN2.0 통신 프로그래밍 강좌 3 - 응답 송/수신 (0) | 2013.02.20 |
---|---|
LIN2.0 통신 프로그래밍 강좌 2 - PID 수신 처리 (0) | 2013.02.13 |
LIN통신 LIN 인증 시험 (LIN Conformance Test) (0) | 2013.01.11 |
LIN통신 LIN2.0 Diag. & Config. Spec.(2)...진단 (0) | 2012.12.10 |
LIN통신 LIN2.0 Diag. & Config. Spec.(1)...노드 설정 (0) | 2012.12.04 |