반응형
[다시 쓰는 8051 따라하기] 시리얼통신
+------------------------------------------------------+
게시장소 : 개인블로그와 다음카페 로봇자작천국
작 성 자 : Timy(me^^;)
작 성 일 : 2004.11.1
문 의 : 다음카페 http://cafe.daum.net/tinyrobo 혹은
개인블로그 http://electoy.cafe24.com/blog
+------------------------------------------------------+
[시작]
## 시리얼통신
데이타를 외부로 보낼때 두가지 방법이 있다. 첫째는 여러개의 선을 사용해서 한번에 여러비트의 정보를 전달하는 방법이 있다. 보통 8개 혹은 16개 정도의 선을 이용해서 한번에 8비트 또는 16비트의 정보를 전달할 수 있다. 두번째는 한개의 선을 이용해서 일정한 간격으로 마치 모르스 신호를 보내듯이 1 과 0 을 끊어서 보내주고 받는 쪽에서는 그 내용을 받아서 다시 원래신호로 해석하는 방법이 있다.
보통 패리얼, 혹은 프린트포트를 이용하는 전달방식이 전자에 속한다. 여러개의 신호를 묶어서 한번에 보내고 받는 식이다. 반면에 시리얼통신은 한개의 선에 데이타를 비트단위로 보낸다. 마치 모르스신호 보내듯이 말이다...
시리얼통신에도 여러 방식이 있다. 그중 여기서는 RS232C 를 사용한다.
RS232C 는 5V, 0V 가 아니라, +3에서 +15V 의 마크신호와 -3 에서 -15V 의 스페이스신호를 보내게 된다. 마크와 스페이스 마로 모르스의 돈쓰와 같은 것이다. 그러니까 1대신에 마크신호, 0대신에 스페이스 신호가 가게 되는 것이다.
8051은 시리얼통신을 위한 내부회로를 가지고 있다. 그러니까 그렇게 사용하기에 몇가지 사항만 알면 어려울것은 없다. 한번 살펴보자.
우선 5V 와 0V 를 +-3에서 15V 까지 만들어줄 필요가 있다. 이것을 위해서 MAX232 라는 칩을 사용한다. 워낙 유명한 칩이라 구하기는 어렵지 않다. 호환칩도 많다.
세부적인 시리얼통신에 대한 내용은 별도의 자료들을 참고하거나 인터넷 사이트를 뒤지기 바란다. 여기서는 깊은 내용을 다루기보다 8051에서 어떻게 시리얼통신을 할수 있는지에 중점을 둘 테니까.. (이제 슬슬 귀차니즘이 발동하기 시작했다는 증거다... ^^;)
시리얼통신 방식중 [모드1] 방식은 다음과 같다. 모드1이 뭐냐고? 그거 말고도 다른 방식도 있다는 거다. 다른 방식은 뭐냐고? 그러니까 인터넷에서 알아서 자료 찾아보라고 위에 썼쟌나.... -_- 자꾸 이런 식으로 나오면 곤란하다....-_-#
2CH = 0x2C 는 이진수로 고치면 다음과 같다. 0010 1100 B (편의상 4개씩 나누어놓았다. 왜 그랬는지 알겠지? ^^)
이것이 시리얼통신을 통해 전송될때 다음과 같아진다.
[0]-[0011 0100]-[1]
이것이 무슨 소리냐면, 시리얼통신으로 8개의 비트가 전동될때 앞에서 부터 뒤로 가는 것이 아니라 뒤에 있는 것부터 전송된다는 의미다. 그리고 전송 시작을 알리는 신호로 [0]이 있다. 그리고 전송이 끝났다는 것을 알리는 신호가 [1]이다. 그러니까 대충 감이 잡히겠지...
시리얼통신을 하려고 할때 기본적으로 신호선은 1로 세팅되어 있다(왜냐하면 이전 통신이 끝났을때 1로 종료되었으니까..). 거기에 0이 들어가는 순간 시리얼통신은 시작됨을 알린다. 0 다음에 들어가는 8개의 비트는 거꾸로 하나씩 들어가게 된다. 그리고 8개의 비트가 모두 전송 완료되면 이제 통신이 끝났음을 알리는 신호로 다시 1이 세팅된다. 그래서 N81 이라는 소리를 혹시 들어봤을지 모르겠다. No parity, 8 bit, One stop bit 를 의미한다. 패리티가 없다는 의미는 혹시 중간에 있는 8개의 데이타 비트가 잘못 전송이 되도 고칠 도리가 없다는 소리다. 혹시 잡음이 껴 들어서 0011 이 0110 으로 되었다고 치자, 패리티가 없으니까, 즉 이 데이타가 좋은 양질의 데이타인지를 검사할 자료가 없으니까 그냥 받아두고 오류 검사를 하지 못해서 0110 으로 인식해 버렸다는 게다.
시리얼통신 말고는 대부분 패리티비트를 제공한다. 시리얼에서도 패리티를 제공해서 할수도 있다. 그런데 여기서는 그것까지는 하지 않을게다. 자료도 없고, 만들수야 있지만, 그거 만든다고 누가 칭찬을 해주기를 하겠나? 누가 써 주기나 하겠다. 차라리 그 시간에 대충 시리얼 익히고 USB 를 익히는게 낫다. 그러니까 패리티가 없는 모드를 쓴다고 너무 억울해하지 말자. 전송해보고 안되면 다시 전송하고, 될때까지 하면 된다.... 될때까지... 알겠나? ^^
시리얼통신을 하려면 레지스터값을 변화시켜야한다.
앞에서 인터럽트를 소개하면서 몇가지 것들을 간단히 소개했다. 여기서는 조금 구체적으로 내용도 들어간다. ^^
## SBUF(Serial Data BUFfer)
시리얼데이타버퍼는 이중구조로 되어 있다. 전송을 위한 구조와 수신을 위한 구조다. 다르지만 같은 이름이다. 그래서 쓸때와 읽을때, 이름은 같지만 다른 물리적인 공간에서 작업을 한다. 마치 램의 비트억세스 가능 영역의 주소번지와 램 전체의 주소번지가 같지만 명령어를 어떤 것을 쓰느냐에 따라서 번지수를 알아서 찾아가는 것과 마찬가지다.
SBUF 에 값을 써 넣으면, 시리얼포트(TXD핀)로 출력되고, 반대로 SBUF에 값을 읽으면 시리얼포트(RXD핀)로 받은 값을 가져온다.
SCON - Serial port CONtrol register (비트별 제어가능)
[ SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI ]
SM0, SM1 : 각각 0 1로 설정한다. 이는 모드1을 쓴다는 의미이다.
SM2 : 0 으로 설정, 모드 1에서는 사용하지 않는다.
REN : 수신 가능 비트, 1로 설정하면 수신 가능, 0으로 설정하면 수신 불가
TB8 : 0, 모드 1에서 사용하지 않음
RB8 : 0, 모드 1에서 수신된 스톱비트값.
TI : 전송 인터럽트 플래그, 모두 전동되면 1이 된다.
RI : 수신 인터럽트 플래그, 모두 수신되면 1이 된다.
PCON - Power CONtrol register (비트별제어 불가능)
[ SMOD | - | - | - | GF1 | GF0 | PD | IDL ]
SMOD : 1로 설정, baud rate 설정시 사용
- : 예약된 비트
GF1, GF0 : 일반목적 사용가능, 별로 사용하지 않음
PD : Power Down bit, 1로 설정하면 CPU가 파워다운 모드로 들어감
IDL : Idle Mode bit, 1로 설정하면 아이들모드로 들어감
SCON 과 PCON 이 어디에 있는지는 앞 강의자료를 참고하기 바람 ^^
## Baud Rate 설정
Baud Rate = ( 2^smod / 32 ) * (주파수 / (12*(256-TH1)))
TH1 = 256-((2^SMOD) * 주파수 )/(32*12*BaudRate)
TH1 = 243 : 9600 bps
위 식대로 계산하면 대충 9600 일때, TH1 이 243 정도가 나온다. 이걸 사용하면 되겠다.
자세하게 더 깊이 알고 싶다면 첨부한 문서를 살펴보기 바란다.
http://www.atmel.com/dyn/resources/prod_documents/doc4316.pdf
인텔에서 만든 8051 문서를 인터넷에 PDF 파일로 된것을 보았는데, 예전 자료를 그대로 스캔해서 올려둔 것이라 크기도 크고 약간 지저분하게 스캔이 되어 있었다. 그래서 그냥 하는 김에 ATMEL 자료를 찾아봤더니 이것이 보였다. 자료도 잘 나와있다. 다만 클래식한 8051 자료라기 보다는 아트멜쪽에서 나오는 8051 유사품들에 대한 선전이 조금 심한 것 같긴하다. 그래도 보고 이해하는데는 별 지장이 없으리란 생각에 링크걸어둔다. 한번 받아서 보도록 (프린트는 하지 않아도 된다. 꽤 큰 문서다..)
그러면 9600 bps 로 시리얼통신을 할때 타이머1을 초기화하면 다음과 같다.
SERIAL9600:
CLR ET1
MOV TMOD, #25H
MOV SCON, #52H
MOV PCON, #80H
MOV TH1, #0F3H
SETB TR1
RET
간단히 각 줄을 설명하면 다음과 같다.
SERIAL9600:
이것은 레이블이라고 한다. 이를테면 사용자가 프로그램시 보기 좋게 일종의 인덱스를 주는 것이라고 보면 되겠다. GOTO 명령 같은 것을 쓰는데 사용된다고 보면 된다.
CLR ET1
ET1 을 지우라는 명령이다. 그러니까 0으로 채우라는 것과 동일하다. ET1 이 0 이 되면 타이머1이 DISABLE 된다. 타이머1을 쓰지 않겠다는 것이다.
MOV TMOD, #25H
TMOD 에 0x25 를 넣으라는 명령이다. TMOD 는 앞 SFR 테이블을 살펴보면 거기 있다. 레지스터를 지금 조작하고 있는 것이다. 0x25 는 0010 0101 B 라는 이진수와 동일하다. 즉, 앞에서부터 세번째, 여섯번째, 여덟번째 비트를 각각 1로 만들라는 명령이다. 각각의 비트가 무엇을 의미하는 지는 역시 자료를 참고하기를...
앞에서 인터럽트를 말하면서 이부분은 아직 말하지 않았다. 그냥 한번 찾아봐라. 책을 가지고 있을테니 그 책을 뒤져봐도 된다. 타이머 설정에 관한 레지스터가 TIMER1 을 사용할때 자동재설정모드 COUNTER 로 사용하겠다는 의미이다. 이 부분, 타이머와 카운터를 다루는 인터럽트는 나중에 한번 더 살펴보도록 하자.
MOV SCON, #52H
마찬가지로 SCON 이라는 레지스트를 설정하는 명령
MOV PCON, #80H
PCON 은 첫번째 비트를 1로 두라고 앞에서 했다. BAUD RATE 설정을 위해 1로 둔다.
MOV TH1, #0F3H
TH1 에 계산된 값인 243 을 넣는다. 여기서는 16진수로 표시된 0F3H로 표시했다. 어셈블러에서 16진수 표현은 보통 뒤에 H 를 붙여 표현한다. 그러니까 0xF3 은 F3H와 같은데, 첫 시작이 A,B,C,D,E,F 로 시작될 경우 문자열과 혼동을 방지하기 위해 그 앞에 0을 덧붙여 써준다. 그래서 0F3H 가 되었고, 앞에 붙은 #은 이것이 번지수가 아닌 REAL NUMBER 임을 드러내는 표식이다. 만약 #을 붙이지 않으면 이 명령은 F3 이라는 번지에 있는 값을 PCON 에 집어넣고 만다.
SETB TR1
TR1을 1로 만든다. 그러므로 다시 TIMER1 이 시작된다.
RET
RETURN 명령이다. 서브루틴이었던 SERIAL9600 을 끝내고 호출전의 명령줄로 돌아간다.
8051에서 시리얼통신을 하기 위해서는 TI 값과 RI 값을 알아야 한다. RI 는 시리얼포트로 들어온 값이 SBUF 에 있게되면 자동적으로 1이 된다. 또 사용자가 시리얼통신을 통해 보낼 데이타를 SBUF 에 넣게 되면 TI 값이 1이 된다. 여기서 SBUF 는 RI 값과 TI 값 모두에 작용하는 듯 하지만, 실제적으로 SBUF 는 RI와 TI동작을 할때 전혀 다른 물리적 공간을 점유한다. 그러니까 시리얼포트로 들어온 값을 읽을때 RI 가 1인지 살피고 1이면 SBUF 에 있는 값을 읽어오면 된다. 그 다음 SBUF 가 비워져 있으니 다음 데이타를 넣어도 좋다는 신호로 RI 에 0을 넣어준다. 반대로 시리얼로 데이타를 보낼때는 TI 가 1이 되었는지 확인한 다음 1이면 SBUF 에 데이타가 비어있는 상태인것이니 TI 값을 0으로 만든다음 SBUF 에 값을 써넣는다. 그러면 SBUF 로 값이 들어가고 이 값은 자동으로 시리얼통신으로 전송되게 된다. 전송이 완료되면 자동으로 TI 값은 다시 1로 된다.
간단한 시리얼통신 입출력 루틴이다.
TXDATA:
JNB TI , $
CLR TI
MOV SBUF, A
RET
RXDATA:
JNB RI , $
MOV A , SBUF
CLR RI
RET
여기서 JNB 는 Jump If Direct Bit is set & Clear bit 로,
JNB TI , $
명령은 TI 값이 1이면 $로 점프하라는 명령이다. $는 PC Program Counter 가 제자리에서 계속 된다는 뜻이다.
CLR TI 는 TI 값을 0으로 만들라는 뜻이고, 나머지는 별 어려움이 없을 것이다.
[끝]
+------------------------------------------------------+
+------------------------------------------------------+
게시장소 : 개인블로그와 다음카페 로봇자작천국
작 성 자 : Timy(me^^;)
작 성 일 : 2004.11.1
문 의 : 다음카페 http://cafe.daum.net/tinyrobo 혹은
개인블로그 http://electoy.cafe24.com/blog
+------------------------------------------------------+
[시작]
## 시리얼통신
데이타를 외부로 보낼때 두가지 방법이 있다. 첫째는 여러개의 선을 사용해서 한번에 여러비트의 정보를 전달하는 방법이 있다. 보통 8개 혹은 16개 정도의 선을 이용해서 한번에 8비트 또는 16비트의 정보를 전달할 수 있다. 두번째는 한개의 선을 이용해서 일정한 간격으로 마치 모르스 신호를 보내듯이 1 과 0 을 끊어서 보내주고 받는 쪽에서는 그 내용을 받아서 다시 원래신호로 해석하는 방법이 있다.
보통 패리얼, 혹은 프린트포트를 이용하는 전달방식이 전자에 속한다. 여러개의 신호를 묶어서 한번에 보내고 받는 식이다. 반면에 시리얼통신은 한개의 선에 데이타를 비트단위로 보낸다. 마치 모르스신호 보내듯이 말이다...
시리얼통신에도 여러 방식이 있다. 그중 여기서는 RS232C 를 사용한다.
RS232C 는 5V, 0V 가 아니라, +3에서 +15V 의 마크신호와 -3 에서 -15V 의 스페이스신호를 보내게 된다. 마크와 스페이스 마로 모르스의 돈쓰와 같은 것이다. 그러니까 1대신에 마크신호, 0대신에 스페이스 신호가 가게 되는 것이다.
8051은 시리얼통신을 위한 내부회로를 가지고 있다. 그러니까 그렇게 사용하기에 몇가지 사항만 알면 어려울것은 없다. 한번 살펴보자.
우선 5V 와 0V 를 +-3에서 15V 까지 만들어줄 필요가 있다. 이것을 위해서 MAX232 라는 칩을 사용한다. 워낙 유명한 칩이라 구하기는 어렵지 않다. 호환칩도 많다.
세부적인 시리얼통신에 대한 내용은 별도의 자료들을 참고하거나 인터넷 사이트를 뒤지기 바란다. 여기서는 깊은 내용을 다루기보다 8051에서 어떻게 시리얼통신을 할수 있는지에 중점을 둘 테니까.. (이제 슬슬 귀차니즘이 발동하기 시작했다는 증거다... ^^;)
시리얼통신 방식중 [모드1] 방식은 다음과 같다. 모드1이 뭐냐고? 그거 말고도 다른 방식도 있다는 거다. 다른 방식은 뭐냐고? 그러니까 인터넷에서 알아서 자료 찾아보라고 위에 썼쟌나.... -_- 자꾸 이런 식으로 나오면 곤란하다....-_-#
2CH = 0x2C 는 이진수로 고치면 다음과 같다. 0010 1100 B (편의상 4개씩 나누어놓았다. 왜 그랬는지 알겠지? ^^)
이것이 시리얼통신을 통해 전송될때 다음과 같아진다.
[0]-[0011 0100]-[1]
이것이 무슨 소리냐면, 시리얼통신으로 8개의 비트가 전동될때 앞에서 부터 뒤로 가는 것이 아니라 뒤에 있는 것부터 전송된다는 의미다. 그리고 전송 시작을 알리는 신호로 [0]이 있다. 그리고 전송이 끝났다는 것을 알리는 신호가 [1]이다. 그러니까 대충 감이 잡히겠지...
시리얼통신을 하려고 할때 기본적으로 신호선은 1로 세팅되어 있다(왜냐하면 이전 통신이 끝났을때 1로 종료되었으니까..). 거기에 0이 들어가는 순간 시리얼통신은 시작됨을 알린다. 0 다음에 들어가는 8개의 비트는 거꾸로 하나씩 들어가게 된다. 그리고 8개의 비트가 모두 전송 완료되면 이제 통신이 끝났음을 알리는 신호로 다시 1이 세팅된다. 그래서 N81 이라는 소리를 혹시 들어봤을지 모르겠다. No parity, 8 bit, One stop bit 를 의미한다. 패리티가 없다는 의미는 혹시 중간에 있는 8개의 데이타 비트가 잘못 전송이 되도 고칠 도리가 없다는 소리다. 혹시 잡음이 껴 들어서 0011 이 0110 으로 되었다고 치자, 패리티가 없으니까, 즉 이 데이타가 좋은 양질의 데이타인지를 검사할 자료가 없으니까 그냥 받아두고 오류 검사를 하지 못해서 0110 으로 인식해 버렸다는 게다.
시리얼통신 말고는 대부분 패리티비트를 제공한다. 시리얼에서도 패리티를 제공해서 할수도 있다. 그런데 여기서는 그것까지는 하지 않을게다. 자료도 없고, 만들수야 있지만, 그거 만든다고 누가 칭찬을 해주기를 하겠나? 누가 써 주기나 하겠다. 차라리 그 시간에 대충 시리얼 익히고 USB 를 익히는게 낫다. 그러니까 패리티가 없는 모드를 쓴다고 너무 억울해하지 말자. 전송해보고 안되면 다시 전송하고, 될때까지 하면 된다.... 될때까지... 알겠나? ^^
시리얼통신을 하려면 레지스터값을 변화시켜야한다.
앞에서 인터럽트를 소개하면서 몇가지 것들을 간단히 소개했다. 여기서는 조금 구체적으로 내용도 들어간다. ^^
## SBUF(Serial Data BUFfer)
시리얼데이타버퍼는 이중구조로 되어 있다. 전송을 위한 구조와 수신을 위한 구조다. 다르지만 같은 이름이다. 그래서 쓸때와 읽을때, 이름은 같지만 다른 물리적인 공간에서 작업을 한다. 마치 램의 비트억세스 가능 영역의 주소번지와 램 전체의 주소번지가 같지만 명령어를 어떤 것을 쓰느냐에 따라서 번지수를 알아서 찾아가는 것과 마찬가지다.
SBUF 에 값을 써 넣으면, 시리얼포트(TXD핀)로 출력되고, 반대로 SBUF에 값을 읽으면 시리얼포트(RXD핀)로 받은 값을 가져온다.
SCON - Serial port CONtrol register (비트별 제어가능)
[ SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI ]
SM0, SM1 : 각각 0 1로 설정한다. 이는 모드1을 쓴다는 의미이다.
SM2 : 0 으로 설정, 모드 1에서는 사용하지 않는다.
REN : 수신 가능 비트, 1로 설정하면 수신 가능, 0으로 설정하면 수신 불가
TB8 : 0, 모드 1에서 사용하지 않음
RB8 : 0, 모드 1에서 수신된 스톱비트값.
TI : 전송 인터럽트 플래그, 모두 전동되면 1이 된다.
RI : 수신 인터럽트 플래그, 모두 수신되면 1이 된다.
PCON - Power CONtrol register (비트별제어 불가능)
[ SMOD | - | - | - | GF1 | GF0 | PD | IDL ]
SMOD : 1로 설정, baud rate 설정시 사용
- : 예약된 비트
GF1, GF0 : 일반목적 사용가능, 별로 사용하지 않음
PD : Power Down bit, 1로 설정하면 CPU가 파워다운 모드로 들어감
IDL : Idle Mode bit, 1로 설정하면 아이들모드로 들어감
SCON 과 PCON 이 어디에 있는지는 앞 강의자료를 참고하기 바람 ^^
## Baud Rate 설정
Baud Rate = ( 2^smod / 32 ) * (주파수 / (12*(256-TH1)))
TH1 = 256-((2^SMOD) * 주파수 )/(32*12*BaudRate)
TH1 = 243 : 9600 bps
위 식대로 계산하면 대충 9600 일때, TH1 이 243 정도가 나온다. 이걸 사용하면 되겠다.
자세하게 더 깊이 알고 싶다면 첨부한 문서를 살펴보기 바란다.
http://www.atmel.com/dyn/resources/prod_documents/doc4316.pdf
인텔에서 만든 8051 문서를 인터넷에 PDF 파일로 된것을 보았는데, 예전 자료를 그대로 스캔해서 올려둔 것이라 크기도 크고 약간 지저분하게 스캔이 되어 있었다. 그래서 그냥 하는 김에 ATMEL 자료를 찾아봤더니 이것이 보였다. 자료도 잘 나와있다. 다만 클래식한 8051 자료라기 보다는 아트멜쪽에서 나오는 8051 유사품들에 대한 선전이 조금 심한 것 같긴하다. 그래도 보고 이해하는데는 별 지장이 없으리란 생각에 링크걸어둔다. 한번 받아서 보도록 (프린트는 하지 않아도 된다. 꽤 큰 문서다..)
그러면 9600 bps 로 시리얼통신을 할때 타이머1을 초기화하면 다음과 같다.
SERIAL9600:
CLR ET1
MOV TMOD, #25H
MOV SCON, #52H
MOV PCON, #80H
MOV TH1, #0F3H
SETB TR1
RET
간단히 각 줄을 설명하면 다음과 같다.
SERIAL9600:
이것은 레이블이라고 한다. 이를테면 사용자가 프로그램시 보기 좋게 일종의 인덱스를 주는 것이라고 보면 되겠다. GOTO 명령 같은 것을 쓰는데 사용된다고 보면 된다.
CLR ET1
ET1 을 지우라는 명령이다. 그러니까 0으로 채우라는 것과 동일하다. ET1 이 0 이 되면 타이머1이 DISABLE 된다. 타이머1을 쓰지 않겠다는 것이다.
MOV TMOD, #25H
TMOD 에 0x25 를 넣으라는 명령이다. TMOD 는 앞 SFR 테이블을 살펴보면 거기 있다. 레지스터를 지금 조작하고 있는 것이다. 0x25 는 0010 0101 B 라는 이진수와 동일하다. 즉, 앞에서부터 세번째, 여섯번째, 여덟번째 비트를 각각 1로 만들라는 명령이다. 각각의 비트가 무엇을 의미하는 지는 역시 자료를 참고하기를...
앞에서 인터럽트를 말하면서 이부분은 아직 말하지 않았다. 그냥 한번 찾아봐라. 책을 가지고 있을테니 그 책을 뒤져봐도 된다. 타이머 설정에 관한 레지스터가 TIMER1 을 사용할때 자동재설정모드 COUNTER 로 사용하겠다는 의미이다. 이 부분, 타이머와 카운터를 다루는 인터럽트는 나중에 한번 더 살펴보도록 하자.
MOV SCON, #52H
마찬가지로 SCON 이라는 레지스트를 설정하는 명령
MOV PCON, #80H
PCON 은 첫번째 비트를 1로 두라고 앞에서 했다. BAUD RATE 설정을 위해 1로 둔다.
MOV TH1, #0F3H
TH1 에 계산된 값인 243 을 넣는다. 여기서는 16진수로 표시된 0F3H로 표시했다. 어셈블러에서 16진수 표현은 보통 뒤에 H 를 붙여 표현한다. 그러니까 0xF3 은 F3H와 같은데, 첫 시작이 A,B,C,D,E,F 로 시작될 경우 문자열과 혼동을 방지하기 위해 그 앞에 0을 덧붙여 써준다. 그래서 0F3H 가 되었고, 앞에 붙은 #은 이것이 번지수가 아닌 REAL NUMBER 임을 드러내는 표식이다. 만약 #을 붙이지 않으면 이 명령은 F3 이라는 번지에 있는 값을 PCON 에 집어넣고 만다.
SETB TR1
TR1을 1로 만든다. 그러므로 다시 TIMER1 이 시작된다.
RET
RETURN 명령이다. 서브루틴이었던 SERIAL9600 을 끝내고 호출전의 명령줄로 돌아간다.
8051에서 시리얼통신을 하기 위해서는 TI 값과 RI 값을 알아야 한다. RI 는 시리얼포트로 들어온 값이 SBUF 에 있게되면 자동적으로 1이 된다. 또 사용자가 시리얼통신을 통해 보낼 데이타를 SBUF 에 넣게 되면 TI 값이 1이 된다. 여기서 SBUF 는 RI 값과 TI 값 모두에 작용하는 듯 하지만, 실제적으로 SBUF 는 RI와 TI동작을 할때 전혀 다른 물리적 공간을 점유한다. 그러니까 시리얼포트로 들어온 값을 읽을때 RI 가 1인지 살피고 1이면 SBUF 에 있는 값을 읽어오면 된다. 그 다음 SBUF 가 비워져 있으니 다음 데이타를 넣어도 좋다는 신호로 RI 에 0을 넣어준다. 반대로 시리얼로 데이타를 보낼때는 TI 가 1이 되었는지 확인한 다음 1이면 SBUF 에 데이타가 비어있는 상태인것이니 TI 값을 0으로 만든다음 SBUF 에 값을 써넣는다. 그러면 SBUF 로 값이 들어가고 이 값은 자동으로 시리얼통신으로 전송되게 된다. 전송이 완료되면 자동으로 TI 값은 다시 1로 된다.
간단한 시리얼통신 입출력 루틴이다.
TXDATA:
JNB TI , $
CLR TI
MOV SBUF, A
RET
RXDATA:
JNB RI , $
MOV A , SBUF
CLR RI
RET
여기서 JNB 는 Jump If Direct Bit is set & Clear bit 로,
JNB TI , $
명령은 TI 값이 1이면 $로 점프하라는 명령이다. $는 PC Program Counter 가 제자리에서 계속 된다는 뜻이다.
CLR TI 는 TI 값을 0으로 만들라는 뜻이고, 나머지는 별 어려움이 없을 것이다.
[끝]
+------------------------------------------------------+
반응형