2010.08.20_ADC_CODE_UART

Report
References:
-AVR ATmega128 정복, Ohm사
-뻔뻔한 AVR 프로그래밍 The 6th Lecture, 유명환
-ATmega128 Manual, ATMEL사
KT-M128 Peripheral Device
USART
조 승훈
USART
USART Overview
• USART (Universal Synchronous and Asynchronous Receiver and Transmitter)
– Parallel로 표현되는 Data를 Serial로 전송 및 수신하는 장치
CPU
CPU
Core
Bus
0
1
0
1
0
1
0
1
TX
0
1
0
1
0
1
0
1
RX
0
1
0
1
0
1
0
1
UART
Data Stream
Parallel
START
0
1
2
3
Serial
4
[5]
[6]
[7]
[8]
[Parity]
Stop1
[Stop2]
Data Bit
3
USART Overview
• ATmega128 UART의 특징
– 두 개의 UART 내장
– 동기 및 비동기 전송 모드 지원
• 동기 모드 – master : 전송속도를 결정하는데 내부 Clock 사용
•
“
slave : XCKn 단자로 입력되는 외부 Clock 사용
• 비동기 모드 – 항상 내부의 System Clock 사용
•
Normal Mode, Double Speed Mode로 나뉨
–
–
–
–
–
–
–
–
–
–
항상 Full-Duplex 통신
Multi-Processor 통신 가능
높은 정밀도의 Baud Rate Generator 내장
5-9 Bit의 Data 전송 가능
1-2 Bit의 Stop Bit 설정 가능
하드웨어에 의한 홀수 및 짝수의 Parity Bit 설정 가능 (생략 가능)
수신 동작에서 Parity Error, Overrun Error, Frame Error 검출 가능
Tx Complete, Tx Data Register Empty, RX Complete Interrupt 사용 가능
Noise Filtering을 포함한 False Start Bit 검출 및 Digital Low Pass Filter
Double Speed 비동기 통신 모드
4
USART Overview
Receiver / Transfer
Ext. Clock
5
USART Overview
KT-M128 UART 회로도
6
UART 직렬통신 포토의 구성 블록도
Baud Rate Control
REG.
Transmitter Buffer
REG. (Same REG)
Receiver Buffer
REG. (Same REG)
I/O Pin
UART Control REG.
동기 모드 Slave를 위한
Ext. Clock
3 PART
모든 파트에서 공유
7
Clock Generator의 내부 구조 및 동작 과정
• USART Operation Mode
– Asynchronous Mode : UCSRnC레지스터의 UMSELn Bit = 0
• Int. System Clock을 기본으로 하여 Baud Rate Clock 생성
• USCRnC REG : U2Xn Bit = 0 - Normal Mode, U2Xn Bit = 1 – Double Speed Mode
– Synchronous Mode : UCSRnC레지스터의 UMSELn Bit = 1
•
•
•
•
XCKn 단자를 이용하여 Baud Rate Clock 생성
Master Mode : XCKn 단자를 이용하여 외부 Slave에 전송, 출력 단자
Slave Mode : XCKn 단자를 외부 Master로 부터 수신, 입력 단자
DDRx의 해당 Bit를 적절한 In / Out으로 설정해야 함
USART
Synchronous
Asynchronous
ATmega128 USART Modes
Master
Slave
Normal
Double
Speed
8
Clock Generator의 내부 구조 및 동작 과정
9
Clock Generator의 Timing
• 동기 모드의 Timing
– XCKn 단자로 입./출력되는 Clock 신호는 UCSRnC레지스터의 UCPOLn Bit에 의해 동작
Edge가 결정 됨
– 동기 Slave Mode에서 외부로부터 입력되는 CXKn Clock 신호는 동기 레지스터와 에지
검출기를 거치면서 2 System Clock만큼 지원, 이 Clock의 주파수는 System Clock의
¼ 이하여야 함
Falling Edge – Receive Data 출력
Rising Edge – Transmit Data 샘플링
Falling Edge – Transmit Data 샘플링
Rising Edge – Receive Data 출력
10
Transmitter의 동작 과정
Clock Generator
Transmitter
송신 버퍼 Empty
UDC(Transmit) : 송신 버퍼
1 Bit씩 Loading
TRANSMIT SHIFT REGISTER
: 한 Bit씩 송신 (Transmitting)
Parity
Generator
TXD
Receiver
11
Receiver의 동작 과정
Clock Generator
Receiver
RXD 핀으로부터 1 Bit씩 수신
RECEIVE SHIFT REGISTER : 1 Bit씩 수신 버퍼에 저장
Transmitter
Parity
Generator
RXD
Stop Bit :
Data Bit 수신이 완료 됨
UDR (Receive) : 수신 버퍼
수신 버퍼 Full
12
전송 데이터 포맷
• Parity Bit를 사용하게 설정한 경우
– 데이터 수신 때 Parity를 계산하여 전송 에러 체크
– 첫 번째의 Stop Bit까지 Frame을 체크하여 Parity Bit가 low로 검출되면 프레임 에러
• 두 개의 Stop Bit를 사용한 경우
– 두 번째 Stop Bit는 수신부에서 무시, 송신부를 Delay 시키는 효과만 있음
[] = Can be remove
•
•
•
•
•
St
(n)
P
Sp
IDLE
:
:
:
:
:
Start Bit, Always low.
Data Bits, (0 to 8)
bit 계산법
Parity Bit, Can be odd or even. Parity
Peven = dn – 1 ⊕ … ⊕ d3 ⊕ d2 ⊕ d1 ⊕ d0 ⊕ 0
Podd = dn – 1 ⊕ … ⊕ d3 ⊕ d2 ⊕ d1 ⊕ d0 ⊕ 1
Stop Bit, Always high.
No transfers on the communication line (RxD or TxD).
An IDLE line must be high.
13
USART REGISTER
• USARTn I/O Data Register – UDRn
– USARTn Port의 송수신 데이터 버퍼 기능을 수행
– 각 Port의 송수신 버퍼는 동일한 번지에 위치, 내부적으로 서로 다른 별개의 레지스터
• 송신 할 데이터를 UDRn에 쓰면, 송신 데이터 버퍼 TXBn에 저장
• 수신 된 데이터를 UDRn에서 읽으면, 수신 데이터 버퍼 RXBn에 수신되어 있는 값이 읽힘
• 전송 데이터 문자를 5-7 Bit로 설정 시
– 송신 : 사용하지 않는 상위 Bit 무시
– 수신 : 이 상위 Bit를 수신부에서 0으로 처리
• 수신 버퍼는 2단계의 FIFO로 된 이중 Buffering 구조를 가짐
– 읽을 때마다 상태가 변함
– SBI/CBI 명령, SBIS/SBIC 명령을 사용하지 않는 것이 좋음
14
USART REGISTER
• USARTn Control & Status Register A – USCRnA
– USARTn Port의 송수신 동작 제어, 송수신 상태를 저장하는 기능을 수행
– Bit 7 (RXCn) : USARTn Receive Complete
• 수신 버퍼에 읽혀지지 않은 문자가 있으면 1로 Set, 수신 버퍼가 비어 있으면 0으로 Set
• 이 비트가 1이면 Receive Complete Interrupt를 요청, 수신 버퍼를 읽으면 0으로 Clear
– Bit 6 (TXCn) : USARTn Transmit Complete
• 송신 시프트 레지스터에 있는 데이터가 모두 송신되고, 송신 버퍼에 새로운 데이터가 Write되지
않으면 1로 Set되는 상태 Flag.
• 이 비트가 1이면 Transmit Complete Interrupt를 요청, Interrupt가 처리되면 자동 Clear
– Bit 5 (UDREn) : USARTn Data Register Empty
• UDRn의 송신 버퍼가 비어 있어 새로운 송신 데이터를 받을 준비가 되면 1로 Set
• 이 비트가 1이면 Data Register Empty Interrupt를 요청, 송신 버퍼에 새로운 데이터를 Write
하면 이 비트는 Clear 됨
15
USART REGISTER
• USARTn Control & Status Register A – USCRnA (Cont’)
– Bit 4 (FEn) : USARTn Frame Error
• UDRn의 수신 버퍼에 저장되어 있는 데이터를 수신하는 동안 Frame Error가 발생
• Frame Error : 수신 문자의 첫 번째 Stop Bit가 0으로 검출되면 발생
• 수신 버퍼 UDRn을 읽을 때까지 유효, UCSRnA를 Write하면 무조건 0으로 Clear 됨
– Bit 3 (DORn) : USARTn Data Overrun Error
• UDRn의 수신 과정에서 Overrun Error가 발생했음을 나타내는 상태 플랙
• Overrun Error : 수신 버퍼에 현재 읽지 않은 데이터가 있는 상태에서, 수신 시프트 레지스터에
새로운 데이터 문자가 수신 완료되고, 다시 그 다음 수신 데이터의 Start Bit가 검출되면 발생
• 수신 버퍼 UDRn을 읽을 때까지 유효, UCSRnA를 Write하면 무조건 0으로 Clear 됨
– Bit 2 (UPEn) : USARTn Parity Error
• 수신 버퍼에 현재 저장되어 있는 데이터를 수신하는 동안 Parity Error가 발생했음을 나타 냄
• 수신 버퍼 UDRn을 읽을 때까지 유효, UCSRnA를 Write하면 무조건 0으로 Clear 됨
16
USART REGISTER
• USARTn Control & Status Register A – USCRnA (Cont’)
– Bit 1 (U2Xn) : Double the USARTn Transmission Speed)
• 비동기 모드에서만 유효
• USARTn Port의 클록 분주비를 16에서 8로 절반만큼 낮추어 전송속도를 2배 높이는 기능을 수행
– Bit 0 (MPCMn) : USARTn Multi-Processor Communication Mode)
• USARTn을 Multi-Processor Communication Mode로 설정
• Multi-Processor Communication Mode에서는 Address 정보를 포함하지 않는 모든 수신 데이
터는 수신부에서 무시 됨
• 송신부는 이 Bit에 영향을 받지 않음
17
USART REGISTER
• USARTn Control & Status Register B – UCSRnB
– USARTn Port의 송수신 동작을 제어하거나, 전송 데이터를 9Bit로 설정한 경우 전송 데이
터의 9번째 Bit값을 저장하는 기능
– Bit 7 (RXCIEn) : USARTn RX Complete Interrupt Enable
• Receive Complete Interrupt를 개별적으로 허용하는 Bit
– Bit 6 (TXCIEn) : USARTn TX Complete Interrupt Enable
• Transmit Complete Interrupt를 개별적으로 허용하는 Bit
– Bit 5 (UDRIEn) : USARTn Data Register Empty Interrupt Enable
• Data Register Empty Interrupt(송신에서만 발생)를 개별적으로 허용하는 Bit
– Bit 4 (RXENn) : USARTn Receiver Enable
• USARTn Port의 수신부가 동작하도록 허용
• RXDn 핀이 병렬 I/O Port가 아니라 Serial Data Receive Port로 동작하게 바꾸고, FEn,
DORn, UPEn의 동작을 유효하게 함
18
USART REGISTER
• USARTn Control & Status Register B – UCSRnB
– Bit 3 (TXENn) : USARTn Transmitter Enable
• USARTn Port의 송신부가 동작하도록 허용
• RXDn 핀이 병렬 I/O Port가 아니라 Serial Data Transmit Port로 동작하도록 설정하지만,
이 Bit를 0으로 설정하더라도 송신 시프트 레지스터에 데이터가 남아 있을 경우 이것이 전송
완료 될 때까지 유효하지 않음
– Bit 2 (UCSZn2) : USARTn Character Size
• UCSRnC 레지스터의 UCSZn1-0비트와 함께 전송 문자의 데이터 Bit수를 설정하는데 사용
– Bit 1 (RXB8n) : USARTn Receive Data Bit 8
• 전송 문자가 9Bit로 설정 된 경우 수신된 문자의 9번째 Bit (MSB)를 저장
• 반드시 UDRn 레지스터보다 먼저 읽혀져야 함
– Bit0 (TXB8n) : USARTn Transmit Data Bit 8
• 송산할 문자의 9번째 Bit (MSB)를 저장, 반드시 UDRn 레지스터보다 먼저 Write해야 함
19
USART REGISTER
• USARTn Control & Status Register C – UCSRnC
– USARTn Port의 송/수신 동작을 제어하는 기능을 수행
UPMn Bit Settings
– Bit 6 (UMSELn) : USARTn Mode Select
• 1 : Synchronous Operation
• 0 : Asynchronous Operation
– Bit 5-4 (UPMn1-0) : USARTn Parity Mode)
UPMn1
UPMn0
Parity Mode
0
0
Disabled
0
1
(Reserved)
1
0
Enabled,
Even Parity
1
1
Enabled,
Odd Parity
• USARTn Port에서 Parity Mode를 설정
– Bit 3 (USBSn) : USARTn Stop Bit Select
• 1 : USARTn Port에서 데이터 포맷을 구성하는 Stop Bit를 두 개로 설정
• 0 : USARTn Port에서 데이터 포맷을 구성하는 Stop Bit를 한 개로 설정
20
USART REGISTER
• USARTn Control & Status Register C – UCSRnC (Cont’)
– Bit 2-1 (UCSZn1-0) : (USARTn Character Size)
• UCSRnB 레지스터의 UCSZn2와 함께 전송 문자의 데이터 비트수를 설정
– Bit 0 (UCPOLn) : USARTn Clock Polarity)
• 동기 모드에서 송/수신의 동작 Edge를 결정
UCSZn Bit Settings
UCPOLn (Bit 0) Bit Settings
UCPOLn
Transmitted Data Changed
Received Data Sampled
0
Rising XCKn Edge
Falling XCKn Edge
1
Falling XCKn Edge
Rising XCKn Edge
UCSZn2
UCSZn1
UCSZn0
Character
Size
0
0
0
5 Bit
0
0
1
6 Bit
0
1
0
7 Bit
0
1
1
Reserved
1
0
0
Reserved
1
0
1
Reserved
1
1
0
Reserved
1
1
1
9 Bit
21
USART REGISTER
• USARTn Baud Rate Register – UBRRnH/L
– UARTn Port의 송/수신 속도를 설정하는 기능을 수행 (Clock의 분주비 – Baud Rate 결정)
22
USART REGISTER
• USARTn Baud Rate Register – UBRRnH/L (Cont’)
USARTn Port에 대한 Baud Rate 설정 공식
동작 모드
보레이트를 결정하는 공식
UBRR값을 결정하는 공식
비동기 일반 모드
(U2Xn = 0)
비동기 2배속 모드
(U2Xn = 1)
동기 마스터 모드
Baud Rate에 따른 UBRn 레지스터의 설정
Baud Rate에 따른 Error값 계산 공식
23
비동기 모드에서 1비트의 샘플링 동작
• ATmega128의 비동기 전송 모드에서는 수신 데이터의 정확한 검출을 위하여 16배의
주파수 혹은 8배의 주파수를 사용하여 데이터 샘플링을 함
– 일반 모드 : 데이터 샘플링에 사용되는 주파수를 Baud Rate의 16배의 주파수 사용
– 2배속 모드 : 데이터 샘플링에 사용되는 주파수를 Baud Rate의 8배의 주파수 사용
– 1 Bit의 데이터를 Sampling 시, Clock 주파수의 어느 정도 오차가 있어도 검출의 정확도를
높일 수 있음
• Start Bit Sampling (Clock Recovery Logic)
– 전압 Spike 잡음에 의하여 데이터 수신 오류가 발생하는 것을 방지하기 위해 1Bit를
3차례 검출하는 방법을 사용
Normal
Mode
2차례 이상 검출 된
논리 신호를 검출 결과로.
함
Double
Speed
Mode
24
비동기 모드에서 1비트의 샘플링 동작
• Sampling of Data and Parity Bit (Data Recovery Logic)
– Normal Mode : 16 state의 State Machine 사용
– Double Speed Mode : 8 state의 State Machine 사용
2차례 이상 검출 된
논리 신호를 검출 결과로.
함
Normal
Mode
동기 된
Start
신호
or
이전
비트
Double
Speed
Mode
• Stop Bit Sampling and Next Start Bit Sampling
Normal
Mode
Double
Speed
Mode
STOP! 이후 FallingEdge가 발생하면
START 신호로 간주
2차례 이상 검출 된
논리 신호를 검출 결과로.
함
25
비동기 모드에서 1비트의 샘플링 동작
• Stop Bit Sampling and Next Start Bit Sampling (Cont’)
– 전송속도에 비하여 수신부가 동작하는 속도가 너무 빠르거나 느리다면 올바른 데이터의 수신
을 기대 할 수 없음
– 수신부의 동작에 비하여 허용 범위에서 가장 빠르게 입력되는 데이터의 전송 속도 비율
– 수신부의 동작에 비하여 허용 범위에서 가장 느리게 입력되는 데이터의 전송 속도 비율
• D
• S
• SF
• SM
Parity와 Data Bit의 합 (D = 5 to 10-bit)
Samples per bit.
Normal Mode – 16, Double Speed Mode - 8
Bit를 검출하기 위해 Sampling하는 횟수의 첫 번째 순서 값
Normal Mode – 8, Double Speed Mode - 4
Bit를 검출하기 위해 Sampling하는 횟수의 중간 순서 값
Normal Mode – 9, Double Speed mode - 5
26
비동기 모드에서 1비트의 샘플링 동작
• Stop Bit Sampling and Next Start Bit Sampling (Cont’)
– 직렬통신 포트의 전송 속도를 설정 할 경우에 올바른 전송이 보장되려면 아래 표에 제시 된
권장 허용 오차 범위 이내로 설정하는 것이 바람직
– 비동기 직렬 통신 방식은 송신측과 수신측의 Clock 주파수에 다소 차이가 있더라도 무난하
게 통신이 수행된다는 것이 가장 큰 장점
Recommended Maximum Receiver Baud Rate Error for Normal Speed Mode (U2X = 0)
Recommended Maximum Receiver Baud Rate Error for Double Speed Mode (U2X = 1)
27
Multi-Processor Communication Mode
• 1개의 Master Processor가 여러 개의 Slave Processor에게 특정한 Address를
전송함으로써 1개의 Slave만을 지정하여 Data를 전송하는 동작 모드
• Multi-Processor Communication Mode의 동작 순서
1. Master인 송신측에서 1문자를 9-bit를 사용하는 Frame으로 설정, 여러 개의 Slave로
구성되는 수신측은 9bit Frame을 사용하는 것은 물론 USCRnA REG의 MPCMn Bit를 1로
지정하여 Address Frame이 수신되기를 기다림
2. 마스터는 8개의 Data Bit에 Address Frame과 9번째 Bit에 TXB8n = 1로 만든
Address Frame을 전송
3. 모든 Slave는 Address Frame을 수신하여 자신에 해당하는 Address인지 확인 후, 그것에
해당하는 하나의 Slave만 MPCMn Bit를 0으로 Clear하여 이후에 전송 될 Data Frame을
수신 할 수 있도록 하고, 다른 Slave들은 계속해서 MPCMn Bit를 1로 유지
4. Master의 Data Frame은 8개의 Data Bit와 9번째 Bit를 TXB8n = 0으로 하여 구성 되
고, 선택 된 Slave는 모든 Data Frame을 수신하고, 이것이 완료되면 다시 MPCMn = 1로
설정하여 Address Fram의 수신 대기 상태로 들어 감
28
ETC
Baud rate와 bps의 차이
• Baud rate (프랑스의 과학자 Jean Maurice Emile Baudot의 이름에서 유래)
– 신호의 변조율
– 데이터 통신의 초기에는 bps = Baud (1번 변하는 신호에 1번의 전송)
– 짧은 시간에 많은 데이터를 전송하기 위해, 신호가 한번 변할 때 여러 Bit를 전송하게끔
(신호가 한번 바뀔 때, 두 Bit 이상을 표현하게 됨)
– 현재는 bps > Baud rate (항상 큰 것은 아니나 bps가 커야 성능면에서 의미가 있음)
– Baud = 1/T (신호 요소의 시간)
• bps (Bit Per Second)
– 초당 전송되는 비트 수를 나타냄
– Bps = baud * number of bits per baud
– Ex) 9600bps = 1초 동안 9,600개의 bit를 전송
• Example (맨체스터 코딩)
– 신호 요소 시간 = 0.5ms
– 변조 속도 = 1 / 0.5ms = 2Kbaud / sec
– 전송 속도 = bps = 2Kbaud * 0.5 number of bits per baud = 1Kbps
30
RS-232C Serial Communication
RS-232C Overview
• RS-232C (Recommend Standard number 232 C)
– 디지털 데이터 통신회선으로 전화선을 사용하기 위해 1962년 EIA에서 DTE와
DCR 사이에 데이터 전송용으로 제정한 통신 권고규격
• RS-232C의 필요성
• USART 직렬 통신 포트를 거쳐 직렬 데이터로 변환 되어도 TTL 로직 레벨의 신호
• 이 TTL 신호를 입력 받아 잡음에 강하고 멀리 갈 수 있게 해주는 인터페이스가 필요
• 이 인터페이스를 Line Driver / Receiver라 부르며, 대표적인 것이 RS-232C, RS-422A, RS485 임
Data Terminal Equipment
Data Communications Equipment
32
RS-232C Spec
• RS-232C의 전기적 사양
– RS-232C 규격에서는 25핀과 9킨 커넥터에 데이터 신호와 핸드세이킹 신호들을 지정하고
이들 신호명은 물론 각 신호들의 전기적인 사양까지 자세하게 규정하고 있음
Rs-232C 및 기타 통신 방식의 전기적인 사양 요약
Specification
RS232C
RS423
RS422
RS485
동작 모드
Single-Ended
Single-Ended
Differential
Differential
최대 Driver/Receiver 수
1 Driver
1 Receiver
1 Driver
10 Receivers
1 Driver
32 Receivers
32 Drivers
32 Receivers
최대 통달거리
약 15 m
약 1.2 km
약 1.2 km
약 1.2 km
최고 통신속도
20 Kb/s
100 Kb/s
10 Mb/s
10 Mb/s
지원 전송방식
Full Duplex
Full Duplex
Full Duplex
Half Duplex
최대 출력전압
±25V
±6V
-0.25V to +6V
-7V to +12V
최대 입력전압
±15V
±12V
-7V to +7V
-7V to +12V
• RS-232C 케이블 길이
– RS-232 규격의 케이블 길이는 약 150cm
– 오른쪽 표 이상의 길이 이상의 케이블 사용의
– 경우 신호 증폭기나 Optical Isolator를 사용
Baud Rate
Shielded Cable
Non Shielded Cable
110
1500m
300m
300
1200m
300m
1200
900m
150m
2400
600m
150m
4800
150m
75m
9600
75m
30m
33
RS-232C 신호의 기능 및 커넥터 구조
• RS-232C 커넥터 구조
– RS-232C에 표준으로 사양되는 D형 커넥터는 반드시 DTE측에 수컷을 사용하고, DCE측에
암컷을 사용해야 함
– DB-25 커넥터는 사실상 사용하지 않는 핀이 많고 부피가 크기 때문에, 대부분 DB-9라고
불리는 9핀 D형 커넥터를 사용 함
• RS-232C 신호의 기능
신호 이름
I/O
기 능
TxD
O
Transmitter Data : DTE에서 직렬로 송신하는 출력 데이터 신호
RxD
I
Receiver Data : DTE에서 직렬로 수신하는 입력 데이터 신호
DTR
O
Data Terminal Ready : DTE가 송수신이 가능한 Ready 상태에 있음을 DCE에게 알려주는 신
호. 이를 L상태로 하면 모뎀이 회선과 접속되고, H상태로 하면 모뎀이 회선과 단절 됨
DSR
I
Data Set Ready : DCE가 동작 가능한 상태에 있음을 DTE에게 알려주는 신호. 즉, DTR 신호에
의하여 모뎀을 회선과 접속하고 DTE에게 응답하는 신호임
RTS
O
Request To Send : DTE가 DCE에 대하여 송신할 데이터가 있음을 알려주는 신호. 이 신호가
L상태인 동안에만 DCE는 회선에 캐리어를 출력
CTS
I
Clear to Send : DCE가 RTS 신호를 받고 회선에 캐리어를 출력하여 데이터를 송신 할 수 있
는 상태에 있음을 DTE에 알려주는 신호. 즉, 이는 RTS 신호에 의하여 회선에 캐리어를 출력하
기 시작하고 DTE에게 응답하는 신호
DCD
I
Carrier Detect : 상대방에서 송신되어 오는 캐리어를 검출하였음을 나타내는 신호. 실제로 데
이터를 수신하는 것은 이 신호가 L상태로 된 이후 임
RI
I
Ring Indicator : DCE가 회선에서 호출 신호를 받으면 액티브 되는 신호
※ I/O는 DTE측을 기준으로 하여 표현
34
RS-232C 신호선의 접속
• 컴퓨터 (DTE)와 모뎀 (DCE)을 접속할 경우
신호선의 접속
제어신호의 동작 (Half-Duplex)
35
RS-232C 신호선의 접속
• 컴퓨터 (DTE)와 컴퓨터 (DTE)를 직접 접속할 경우
– DTE 사이의 전송거리가 15m 이하로 짧아서 전화선 및 모뎀이 필요 없는 경우
핸드세이킹 기능을 사용하지도 않고 핸드세이킹 신호를 접속하지도 않는 경우.
마이크로 컨트롤러에서 가장 널리 사용하는 방식
제어논리에서는 핸드세이킹 기능을 사용하지만
실제로는 핸드세이킹 신호선을 접속하지 않고 이에 필요한
제어신호를 루프백시켜 마치 상대측이 레디 상태에
있는 것처럼 처리해주는 경우
핸드세이킹 기능을 사용하며 하드웨어적으로
핸드세이킹 신호선에 이에 맞도록 접속하는 경우
36
USART Source Code
Program Pinout
특수 기능
범용 포트
38
Transmitter Source
#define
#define
#define
#define
#define
F_CPU 16000000
//Clock Frequency : to use
EX_SS_DATA (*(volatile unsigned char *)0x8002)
EX_SS_SEL (*(volatile unsigned char *)0x8003)
EX_SS_SW
(*(volatile unsigned char *)0x0036)
led_out
(*(volatile unsigned char *)0x8008)
util/delay.h
//7seg data
//7seg digit
//Switch
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
const char segment_data[10] = {63, 6,91,79,102,109,125,39,127,103};
unsigned char display_num[4]={0,0,0,0}; //7segment digit
unsigned char digit_num=0;
volatile unsigned char adc_value = 0;
//ADC Converted Value
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x0F;
PORTD = 0x00;
DDRD = 0x00;
PORTE = 0x00;
DDRE = 0x02;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x00;
DDRG = 0x00;
}
//1출력 0입력 to 7segment, led
// TIMER0 initialize : prescale:64
// WGM: Normal Mode
// desired Clock : 1KHz
// actual value : 1ms
void timer0_init(void)
{
ASSR = 0x00; //set async mode
TCNT0 = 0x06; //set count for 6 to 255
OCR0 = 0x00;
TCCR0 = 0x04; //prescale 64
}
// Timer0 Overflow Interrupt Service Routine
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x06; //reload counter value
digit_num++;
digit_num = digit_num % 4; //get Digit Selection Number
EX_SS_DATA = segment_data[display_num[digit_num]];
//get segment data
EX_SS_SEL = ~(0x01 << digit_num); //Digit Selection
}
//Low 8bit output to 7segment, led
//TX Pin, output to USART
// USART0 Transmit Complete Interrupt Service Routine
ISR(USART0_TX_vect)
{
UDR0 = adc_value;
}
//PortF is Input from ADC
39
Transmitter Source
/********************************************************************
/ UDR0
/ / UCSR0A
/ Bit 7 : RXC0 - Receive Complete (Req Recive Complete INT)
/ Bit 6 : TXC0 - Transmit Complete (Req Transmit Complete INT)
/ Bit 5 : UDRE0 - Data Register Empty (trabsmit buffer empty INT)
/ Bit 4 : FE0 - Fame Error
/ Bit 3 : DOR0 - Data Overrun Error
/ Bit 2 : UPE0 - Parity Error
/ Bit 1 : U2X0 - Double Speed Mode
/ Bit 0 : MPCM0 - Multi-Processor Communication Mode
/
/
/
/
/
/
/
/
/
UCSR0B
Bit 7 : RXCIE0
Bit 6 : TXCIE0
Bit 5 : UDRIE0
Bit 4 : RXEN0
Bit 3 : TXEN0
Bit 2 : UCSZ0n
Bit 1 : RXB80
Bit 0 : TXB80
- RX Complete INT Enable
- TX Complete INT Enable
- Data REG empty INT Enable
- Receiver Enable
- Transmitter Enable
- Character size 2
- Receive Data Bit 8 (MSB)
- Transmit Data Bit 8 (MSB)
/
/
/
/
/
/
/
/
/
UCSR0C
Bit 7 : Reserved
Bit 6 : UMSEL0 - Mode Select (1 - Sync, 0 - Async)
Bit 5 : UPM0 - Parity Mode (00 - Disable, 01 - reserved)
Bit 4 :
(10 - even , 10 - odd
)
Bit 3 : USBS0 - Stop Bit Select (0 - 1, 1 - 2)
Bit 2 : UCSZ0n - Character size (000 - 5bit,001 - 6bit,010 - 7bit)
Bit 1 :
(011 - 8bit,111 - 9bit,etc - reve)
Bit 0 : UCPOL0 - Clock Plarity (in Sync mode)
/ UBRR0H/L
/ ********************************************************************/
//USART0 initialize function
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void usart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00; //INT clear, Error clear, Non 2speed & MPCM
UCSR0C = 0x06; //8bit char size, 0000_0110
UBRR0H = 0x00; //set baud rate hi, must be post write high byte
UBRR0L = 0x67; //set baud rate lo, 103 dec = 9600 baud rate
UCSR0B = 0x48; //TX enable, TX INT enable : 0100_1000
}
40
Transmitter Source
/*********************************************************************
// ADCSRA
// Bit 7 : ADEN - ADc ENable
// Bit 6 : ADSC - ADc Start Conversion
// Bit 5 : ADFR - ADc Free-Running selection
// Bit 4 : ADIF - ADc Interrupt Flag
// Bit 3 : ADIE - ADc Interrupt Enable
// Bit 2 : ADPS - ADc Prescaler Select
// Bit 0 : 2 to 0
// ADMUX
// Bit 7 : REFS - Reference Selection (default 01 - Ext. AVCC)
// Bit 6 : 7 to 6
// Bit 5 : ADLAR - ADc Left Adjust Result
// Bit 4 : MUX - Analog Channel and Gain Selection (default 00xxx)
// Bit 0 : 4 to 0
**********************************************************************/
void adc_init(void)
{
ADCSRA = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR = 0x80; //set Analog Comparator disable
ADCSRA = 0xC6; //set ADCSRA 1100_0110
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
asm("cli"); //disable all interrupts
port_init();
adc_init();
timer0_init();
usart0_init();
MCUCR = 0x80; //enable int
TIMSK = 0x01; //timer interrupt sources (MASK) T/C0 Ovf flag
asm("sei"); //re-enable interrupts
}
void startConvertion(unsigned char ch)
{
ADMUX = 0x60 | ch;
//Channel Selection
ADCSRA = ADCSRA | 0xc0; //Enable ADC & Start ADC
}
unsigned char readConvertData(void)
{
volatile unsigned char temp = 0;
while((ADCSRA & 0x10)==0); //wait ADC Complete INT
temp = ADCL;
//ignore Lower 2-bit
temp = ADCH;
//get Upper 8-bit
return temp;
}
41
Transmitter Source
int main()
{
volatile unsigned char sw;
init_devices();
EX_SS_SW = 0;
UDR0 = 0xFF;
while(1)
{
if(EX_SS_SW & 0xF)
{
switch(EX_SS_SW)
{
case 1: sw =
case 2: sw =
case 4: sw =
case 8: sw =
}
led_out = EX_SS_SW;
}
startConvertion(sw);
//sw is ADC
adc_value = readConvertData();
display_num[0] =
display_num[1] =
display_num[2] =
display_num[3] =
_delay_ms(1000);
(adc_value
(adc_value
(adc_value
(adc_value
%
%
%
%
0;
1;
2;
3;
break;
break;
break;
break;
input Channel
10000) / 1000;
1000) / 100;
100) / 10;
10);
}
}return 0;
}
42
Receiver Source
#define F_CPU 16000000
//Clock Frequency : to use util/delay.h
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
const char segment_data[10] = {63, 6,91,79,102,109,125,39,127,103};
unsigned char display_num[4]={0,0,0,0}; // Seven segment 4자리 숫자 출력 버퍼
unsigned char digit_num=0;
volatile unsigned char get_val = 0;
//usart0 receive value
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF; //7SEG Data, output
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x0F; //7SEG Digit Select, output
PORTD = 0x00;
DDRD = 0x00;
PORTE = 0x00;
DDRE = 0x00; //USART0 RX pin is input
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x00;
DDRG = 0x00;
}
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1KHz
// actual value: 1.000KHz
void timer0_init(void)
{
TCCR0 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT0 = 0x06; //set count
OCR0 = 0x00;
TCCR0 = 0x04; //prescaler /64
}
void usart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00; //INT clear, Error clear, Non 2speed & MPCM
UCSR0C = 0x06; //8bit char size, 0000_0110
UBRR0H = 0x00; //set baud rate hi, must be write high byte
UBRR0L = 0x67; //set baud rate lo, 103 dec = 9600 baud rate
UCSR0B = 0x90; //RX enable 1001_0000
}
43
Receiver Source
//timer0 ovf interrupt service routine
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x06; //reload counter value
digit_num++;
digit_num = digit_num%4;
PORTC = 0x0f;
PORTA = segment_data[display_num[digit_num]];
PORTC = ~(0x01 << digit_num);
}
//receive complete interrupt service routine
ISR(USART0_RX_vect)
{
get_val = UDR0;
}
int main(void)
{
init_devices();
//Recieve Value print out
while(1){
display_num[0] = (get_val
display_num[1] = (get_val
display_num[2] = (get_val
display_num[3] = (get_val
_delay_ms(1000);
}
%
%
%
%
10000) / 1000;
1000) / 100;
100) / 10;
10);
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
asm("cli"); //disable all interrupts
port_init();
timer0_init();
usart0_init();
MCUCR = 0x00;
TIMSK = 0x01; //timer interrupt sources
asm("sei"); //re-enable interrupts
//all peripherals are now initialized
}
44
Memory Map
Memory Map
132:
0e 94 67 00
call
0xce
; 0xce <port_init>
// Bit 4 : MUX - Analog Channel and Gain Selection (default 00xxx)
// Bit 0 : 4 to 0
**********************************************************************/
void adc_init(void)
{
ADCSRA = 0x00; //disable adc
136:
16 b8
out
0x06, r1
; 6
ADMUX = 0x00; //select adc input 0
138:
17 b8
out
0x07, r1
; 7
ACSR = 0x80; //set Analog Comparator disable
13a:
10 e8
ldi
r17, 0x80
; 128
13c:
18 b9
out
0x08, r17
; 8
ADCSRA = 0xC6; //set 1100_0110
//더미 수행.
13e:
86 ec
ldi
r24, 0xC6
; 198
140:
86 b9
out
0x06, r24
; 6
0x0000_0000 ~ 0x0000_0088
Interrupt
Vector
0x0000_008C ~ 0x0000_00CA
ATmega128
Init_Funcs
0x0000_00CE ~ 0x0000_00F8
Port_init()
0x0000_00FA ~ 0x0000_0106
Timer0_init()
0x0000_0108 ~ 0x0000_0114
ADC_init()
0x0000_0116 ~ 0x0000_012C
Usart0_init()
0x0000_012E ~ 0x0000_015C
Init_devices()
0x0000_015E ~ 0x0000_0168
Start_convert
()
0x0000_016A ~ 0x0000_018A
readConvert
Data()
0x0000_018C ~ 0x0000_01FA
ISR(TIMER0_
OVF_VECT)
Interrupt Vector 16
0x0000_01FC ~ 0x0000_0218
ISR(USART0_
TX_VECT)
Interrupt Vector 20
0x0000_021A ~ 0x0000_02FA
Main()
0x0000_02FC ~ 0x0000_0360
Library_funcs
0x0000_0362 ~ 0x0000_0362
_exit()
0x0000_0364 ~ 0x0000_0364
_stop_progra
m
※ Init과 동시에 수행되는 함수들의 경우 이 곳에 Asm Code가 포함이 됨 (adc_init, timer0_init)
나머지는 call func_address의 형태를 가짐 (port_init, usart0_init)
46
Test
Diagram
SP Configuration
Data Copy
Etc.
TX_Complete_INT
Interrupt
Vector
ATmega128
Init_Funcs
Interrupt Occur
Timer0_Ovf_INT
Main()
Init_devices()
Port_init()
ADC_init()
Timer0_init()
Usart0_init()
If(Switch On)
Change ADC
Channel
R_ADMUX
(refVCC, Channel)
R_ADCSRA
(ADC Start)
R_TCNT0
(Timer0 Counter)
readConvert
Data()
ISR(TIMER0_
OVF_VECT)
R_UDR0
(Transmit buffer)
Background Operation
Timer0
Count
USART0
Transmit
ADC
Converter
R_ADCL/H
(ADC Result)
Start_convert
()
7Seg_data
set
ISR(USART0_
TX_VECT)
Wait
ADC_Complete
INT
R_ARCSRA
(ADC_COMP INT)
R_ADCL. ADCH
(ADC Result)
ADC Complete Interrupt Occur
Using 7Seg_data for 7seg Display
_exit()
48
ADC Operation Time
• KT-M128 Clock Speed : 16Mhz
ADC Prescaler
– 1 / 16,000,000 = 0.000 000 0625s = 0.0625us
– 각 프리스케일러별 Clcok 주기
•
•
•
•
•
•
2 = 0.000,000,125s = 125ns = 0.125us (8Mhz)
8 = 0.0,000,005s = 0.5us (2Mhz)
16 = 0.000,001s = 1us (1Mhz)
32 = 0.000,002s = 2us (0.5Mhz)
64 = 0.000,004s = 4us (0.25Mhz)
128 = 0.000,008s = 8us (0.125Mhz)
• Total Operating Time
ADC Operating Cycle
– Normal Conversions, single ended = 14.5 Clock
– 각 프리스케일러별 ADC 연산에 필요한 총 소모 시간 (() : Cycle)
•
•
•
•
•
•
2 = 125ns * 14.5 = 0.0,000,018,125s = 1812.5ns = 1.8125us (26)
8 = 0.5us * 14.5 = 0.000,007,25s = 7.25us (104)
16 = 1us * 14.5 = 0.000,014,5s = 14.5us (208)
32 = 2us * 14.5 = 0.000,029,0s = 29.0us (416) ※ ADC에서 Sampling시 데이터의 손실이 발생하지 않기 위해서는
최대 128 * 13 Cycle (1664)이내에
ADC의 결과를 가지고 하는 모든 연산을 끝내야 한다.
64 = 4us * 14.5 = 0.000,058s = 58us (832)
49
128 = 8us * 14.5 = 0.000,116s = 116us (1664)
Program Timing
ADC
Complete
Start
Convert
7seg
Display
24.1875us
387 clk
Previous Convert
2.125us
34 clk
ADC_Complete
0.4375us
7 clk
7.1875us
115 clk
Next Convert
t
7.1875us
115 clk
Get ADC Result
If(SW_ON)
Change Channel
Read Convert Data
Get ADC Result
Main Loop
t
Each 1ms
Timer0 ovf
Interrupt
Each 1ms
TX Comp
Interrupt
0.001(1ms) / 0.000 0000625 (16Mhz) = 16000 cycle
Timer0 ovf
Interrupt
ADC
START
Each 1ms
TX Comp
Interrupt
ADC
Complete
Background
USART Baud Rate : 9600
1 / 9600 = 0.0001sec
0.0001 * 10bit = 0.001 = 1ms
50
모듈 별 소모 Clock
ATmega128
Init_Funcs
Interrupt
Vector
약 (45)
TX_Complete_INT
ISR(USART0_
TX_VECT)(13)
Timer0_Ovf_INT
ISR(TIMER0_
OVF_VECT)(83)
Main() (751)
Init_devices() (31 + (25) + (15)) = 71
Port_init()
(25)
ADC_init()
(10)
Timer0_init()
(10)
Usart0_init()
(15)
(33)
If(Switch On)
Change ADC
Channel (34)
※ Main loop 및 ISR 소비 클럭
654 + 83 + 13 = 750
※ 프리스케일러별 샘플링 주기
2 : 26
8 : 104
16 : 208
32 : 416
64 : 832
128 : 1664
(654)
Interrupt Occur
Background
Timer0
Count
USART0
Transmit
ADC
Converter
Start_convert
()
(7)
Wait
ADC_Complete
INT
(5 * X)
readConvert
Data() (33)
7Seg_data
set
Pre-scaler : 64
832(sampling time)
– 654 (Main loop)
– 96(ISRs)
= 82 / 5 = 16.4
(387)
_exit()
51
결론
• ADC의 샘플링 주기를 위해 ADC의 프리스케일러는 64 이상으로 설정해야 함
• USART의 전송속도가 ADC Convert 속도보다 느림
– Baud Rate를 9600의 1.5 배 이상으로 설정해야 함
– 혹은 ADC의 프리스케일러를 128로 설정 (시간이 조금씩 밀리긴 함)
프리스케일러별 샘플링 주기 (cycle)
2 : 26
8 : 104
16 : 208
32 : 416
64 : 832
128 : 1664
USART Baud Rate : 9600
1 / 9600 = 0.0001sec
0.0001 * 10bit = 0.001 = 1ms
0.001(1ms) / 0.000 0000625 (16Mhz) = 16000 cycle
52
Optimize Option
• Project -> Configuration Options -> Optimization
53
Optimize Option
Optimization : -O0
No Optimization
Optimization : -O2
The compiler does not perform
loop Unrolling or function inling.
Optimization : -O1
Reduce code size and execute time, without performing any optimization
Optimization : -Os
Optimize for Code size.
-Os enables all –O2 optimizations
that do not typically increase code size.
Reference : C:\WinAVR-20100110\doc\gcc\HTML\gcc-4.3.2\gcc\Optimize-Options
54
환경 설정
56
57

similar documents