570 likes | 1.05k Views
References : -AVR ATmega128 정복 , Ohm 사 - 뻔뻔한 AVR 프로그래밍 The 6 th Lecture, 유명환 -ATmega128 Manual, ATMEL 사. KT-M128 Peripheral Device. USART 조 승훈. USART . USART Overview. USART (Universal Synchronous and Asynchronous Receiver and Transmitter)
E N D
References: -AVR ATmega128 정복, Ohm사 -뻔뻔한 AVR 프로그래밍 The 6th Lecture, 유명환 -ATmega128 Manual, ATMEL사 KT-M128 Peripheral Device USART 조 승훈
USART Overview • USART (Universal Synchronous and Asynchronous Receiver and Transmitter) • Parallel로 표현되는 Data를 Serial로 전송 및 수신하는 장치 CPU 0 UART 1 TX CPU Core 0 1 0 1 0 1 0 1 0 1 0 Bus RX 1 0 1 0 1 0 1 0 1 0 Data Stream 1 Parallel Serial START 0 1 2 3 4 [5] [6] [7] [8] [Parity] Stop1 [Stop2] Data Bit
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 비동기 통신 모드
USART Overview PORT F PORT A Receiver / Transfer PORT E PORT C PORT B PORT D Ext. Clock
USART Overview KT-M128 UART 회로도
UART 직렬통신 포토의 구성 블록도 Baud Rate Control REG. Transmitter Buffer REG. (Same REG) Receiver Buffer REG. (Same REG) I/O Pin 동기 모드 Slave를 위한 Ext. Clock UART Control REG. 3PART 모든 파트에서 공유
Clock Generator의 내부 구조 및 동작 과정 • USART Operation Mode • Asynchronous Mode : UCSRnC레지스터의 UMSELn Bit = 0 • Int. System Clock을 기본으로 하여 Baud Rate Clock 생성 • USCRnCREG : 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
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 출력
Transmitter의 동작 과정 Clock Generator Transmitter 송신 버퍼 Empty UDC(Transmit) : 송신 버퍼 1 Bit씩 Loading TRANSMIT SHIFT REGISTER : 한 Bit씩 송신 (Transmitting) Parity Generator TXD Receiver
Receiver의 동작 과정 Clock Generator Receiver Transmitter RXD 핀으로부터 1 Bit씩 수신 RECEIVE SHIFT REGISTER : 1 Bit씩 수신 버퍼에 저장 Parity Generator RXD Stop Bit : Data Bit 수신이 완료 됨 UDR (Receive) : 수신 버퍼 수신 버퍼 Full
전송 데이터 포맷 • Parity Bit를 사용하게 설정한 경우 • 데이터 수신 때 Parity를 계산하여 전송 에러 체크 • 첫 번째의 Stop Bit까지 Frame을 체크하여 Parity Bit가 low로 검출되면 프레임 에러 • 두 개의 Stop Bit를사용한 경우 • 두 번째 Stop Bit는 수신부에서 무시, 송신부를 Delay 시키는 효과만 있음 • St : Start Bit, Always low. • (n) : Data Bits, (0 to 8) • P : Parity Bit, Can be odd or even. • Sp : Stop Bit, Always high. • IDLE : No transfers on the communication line (RxD or TxD). An IDLE line must be high. [] = Can be remove Parity bit 계산법 Peven = dn – 1⊕ … ⊕ d3 ⊕ d2⊕ d1⊕ d0⊕ 0 Podd= dn – 1 ⊕ … ⊕ d3 ⊕ d2 ⊕ d1 ⊕ d0 ⊕ 1
USART REGISTER • USARTn I/O Data Register – UDRn • USARTn Port의 송수신 데이터 버퍼 기능을 수행 • 각 Port의 송수신 버퍼는 동일한 번지에 위치, 내부적으로 서로 다른 별개의 레지스터 • 송신 할 데이터를 UDRn에 쓰면, 송신 데이터 버퍼 TXBn에 저장 • 수신 된 데이터를 UDRn에서 읽으면, 수신 데이터 버퍼 RXBn에 수신되어 있는 값이 읽힘 • 전송 데이터 문자를 5-7Bit로 설정 시 • 송신 : 사용하지 않는 상위 Bit 무시 • 수신 : 이 상위 Bit를 수신부에서0으로 처리 • 수신 버퍼는 2단계의 FIFO로 된 이중 Buffering 구조를 가짐 • 읽을 때마다 상태가 변함 • SBI/CBI 명령, SBIS/SBIC 명령을 사용하지 않는 것이 좋음
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 됨
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 됨
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에 영향을 받지 않음
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 • USARTnPort의 수신부가 동작하도록 허용 • RXDn핀이 병렬 I/O Port가 아니라 Serial Data Receive Port로 동작하게 바꾸고, FEn, DORn, UPEn의 동작을 유효하게 함
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해야 함
USART REGISTER • USARTn Control & Status Register C – UCSRnC • USARTn Port의 송/수신 동작을 제어하는 기능을 수행 • Bit 6 (UMSELn) : USARTn Mode Select • 1 : Synchronous Operation • 0 : Asynchronous Operation • Bit 5-4 (UPMn1-0) : USARTn Parity Mode) • USARTn Port에서 Parity Mode를 설정 • Bit 3 (USBSn) : USARTn Stop Bit Select • 1 : USARTn Port에서 데이터 포맷을 구성하는 Stop Bit를 두 개로 설정 • 0 : USARTn Port에서 데이터 포맷을 구성하는 Stop Bit를 한 개로 설정 UPMn Bit Settings
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
USART REGISTER • USARTn Baud Rate Register – UBRRnH/L • UARTnPort의 송/수신 속도를 설정하는 기능을 수행 (Clock의 분주비 – Baud Rate 결정)
USART REGISTER • USARTn Baud Rate Register – UBRRnH/L (Cont’) USARTn Port에 대한 Baud Rate 설정 공식 Baud Rate에 따른 Error값 계산 공식 Baud Rate에 따른 UBRn레지스터의 설정
비동기 모드에서 1비트의 샘플링 동작 • ATmega128의 비동기 전송 모드에서는 수신 데이터의 정확한 검출을 위하여 16배의 주파수 혹은 8배의 주파수를 사용하여 데이터 샘플링을 함 • 일반 모드 : 데이터 샘플링에 사용되는 주파수를 Baud Rate의 16배의 주파수 사용 • 2배속 모드 : 데이터 샘플링에 사용되는 주파수를 Baud Rate의 8배의 주파수 사용 • 1 Bit의 데이터를 Sampling 시, Clock 주파수의 어느 정도 오차가 있어도 검출의 정확도를 높일 수 있음 • Start Bit Sampling (Clock Recovery Logic) • 전압 Spike 잡음에 의하여 데이터 수신 오류가 발생하는 것을 방지하기 위해 1Bit를 3차례 검출하는 방법을 사용 2차례 이상 검출 된 논리 신호를 검출 결과로. 함 Normal Mode Double Speed Mode
비동기 모드에서 1비트의 샘플링 동작 • Sampling of Data and Parity Bit (Data Recovery Logic) • Normal Mode : 16 state의 State Machine 사용 • Double Speed Mode : 8 state의 State Machine 사용 • Stop Bit Sampling and Next Start Bit Sampling 2차례 이상 검출 된 논리 신호를 검출 결과로. 함 Normal Mode 동기 된 Start 신호 or 이전 비트 Double Speed Mode STOP! 이후 Falling-Edge가 발생하면 START 신호로 간주 2차례 이상 검출 된 논리 신호를 검출 결과로. 함 Normal Mode Double Speed Mode
비동기 모드에서 1비트의 샘플링 동작 • Stop Bit Sampling and Next Start Bit Sampling(Cont’) • 전송속도에 비하여 수신부가 동작하는 속도가 너무 빠르거나 느리다면 올바른 데이터의 수신을 기대 할 수 없음 • 수신부의 동작에 비하여 허용 범위에서 가장 빠르게 입력되는 데이터의 전송 속도 비율 • 수신부의 동작에 비하여 허용 범위에서 가장 느리게 입력되는 데이터의 전송 속도 비율 • D Parity와 Data Bit의 합 (D = 5 to 10-bit) • S Samples per bit. Normal Mode – 16, Double Speed Mode - 8 • SF Bit를 검출하기 위해 Sampling하는 횟수의 첫 번째 순서 값 Normal Mode – 8, Double Speed Mode - 4 • SM Bit를 검출하기 위해 Sampling하는 횟수의중간 순서 값 Normal Mode – 9, Double Speed mode - 5
비동기 모드에서 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)
Multi-Processor Communication Mode • 1개의 Master Processor가 여러 개의 Slave Processor에게 특정한 Address를 전송함으로써 1개의 Slave만을 지정하여 Data를 전송하는 동작 모드 • Multi-Processor Communication Mode의 동작 순서 • Master인 송신측에서 1문자를 9-bit를 사용하는 Frame으로 설정, 여러 개의 Slave로 구성되는 수신측은9bit Frame을 사용하는 것은 물론 USCRnA REG의 MPCMn Bit를 1로 지정하여 Address Frame이 수신되기를 기다림 • 마스터는 8개의 Data Bit에 Address Frame과 9번째 Bit에 TXB8n = 1로 만든 Address Frame을 전송 • 모든 Slave는 Address Frame을 수신하여 자신에 해당하는 Address인지 확인 후, 그것에 해당하는 하나의 Slave만 MPCMn Bit를 0으로 Clear하여 이후에 전송 될 Data Frame을 수신 할 수 있도록 하고, 다른 Slave들은 계속해서 MPCMn Bit를 1로 유지 • Master의 Data Frame은 8개의 Data Bit와 9번째 Bit를 TXB8n = 0으로 하여 구성 되고, 선택 된 Slave는 모든 Data Frame을 수신하고, 이것이 완료되면 다시 MPCMn = 1로설정하여Address Fram의 수신 대기 상태로 들어 감
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
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, RS-485 임 Data Terminal Equipment Data Communications Equipment
RS-232C Spec • RS-232C의 전기적 사양 • RS-232C 규격에서는 25핀과 9킨 커넥터에 데이터 신호와 핸드세이킹 신호들을 지정하고 이들 신호명은 물론 각 신호들의 전기적인 사양까지 자세하게 규정하고 있음 • RS-232C 케이블 길이 • RS-232 규격의 케이블 길이는 약 150cm • 오른쪽 표 이상의 길이 이상의 케이블 사용의 • 경우 신호 증폭기나 Optical Isolator를 사용 Rs-232C 및 기타 통신 방식의 전기적인 사양 요약
RS-232C 신호의 기능 및 커넥터 구조 • RS-232C 커넥터 구조 • RS-232C에 표준으로 사양되는 D형 커넥터는 반드시 DTE측에 수컷을 사용하고, DCE측에 암컷을 사용해야 함 • DB-25 커넥터는 사실상 사용하지 않는 핀이 많고 부피가 크기 때문에, 대부분 DB-9라고 불리는 9핀 D형 커넥터를 사용 함 • RS-232C 신호의 기능 ※ I/O는 DTE측을 기준으로 하여 표현
RS-232C 신호선의 접속 • 컴퓨터 (DTE)와 모뎀 (DCE)을 접속할 경우 신호선의 접속 제어신호의 동작 (Half-Duplex)
RS-232C 신호선의 접속 • 컴퓨터 (DTE)와 컴퓨터 (DTE)를 직접 접속할 경우 • DTE 사이의 전송거리가 15m 이하로 짧아서 전화선 및 모뎀이 필요 없는 경우 핸드세이킹 기능을 사용하지도 않고 핸드세이킹 신호를 접속하지도 않는 경우. 마이크로 컨트롤러에서 가장 널리 사용하는 방식 제어논리에서는 핸드세이킹 기능을 사용하지만 실제로는 핸드세이킹신호선을 접속하지 않고 이에 필요한 제어신호를 루프백시켜 마치 상대측이 레디 상태에 있는 것처럼 처리해주는 경우 핸드세이킹 기능을 사용하며 하드웨어적으로 핸드세이킹신호선에 이에 맞도록 접속하는 경우
Program Pinout 특수 기능 ADC / Input 범용 포트 USART / InOut Address & Data Bus / Output Address Bus / Output LED / Output
Transmitter Source #define F_CPU 16000000 //Clock Frequency : to use util/delay.h #define EX_SS_DATA (*(volatile unsigned char *)0x8002) //7seg data #define EX_SS_SEL (*(volatile unsigned char *)0x8003) //7seg digit #define EX_SS_SW (*(volatile unsigned char *)0x0036) //Switch #define led_out (*(volatile unsigned char *)0x8008) #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; //1출력 0입력 to 7segment, led PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; DDRC = 0x0F; //Low 8bit output to 7segment, led PORTD = 0x00; DDRD = 0x00; PORTE = 0x00; DDRE = 0x02; //TX Pin, output to USART PORTF = 0x00; DDRF = 0x00; //PortF is Input from ADC PORTG = 0x00; DDRG = 0x00; } // 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 } // USART0 Transmit Complete Interrupt Service Routine ISR(USART0_TX_vect) { UDR0 = adc_value; }
Transmitter Source /******************************************************************** / UDR0 / - / UCSR0A / Bit 7 : RXC0 - Receive Complete (ReqRecive 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 - RX Complete INT Enable / Bit 6 : TXCIE0 - TX Complete INT Enable / Bit 5 : UDRIE0 - Data REG empty INT Enable / Bit 4 : RXEN0 - Receiver Enable / Bit 3 : TXEN0 - Transmitter Enable / Bit 2 : UCSZ0n - Character size 2 / Bit 1 : RXB80 - Receive Data Bit 8 (MSB) / Bit 0 : TXB80 - 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 }
Transmitter Source /********************************************************************* // ADCSRA // Bit 7 : ADEN - ADcENable // 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 - ADcPrescaler 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; }
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 = 0; break; case 2: sw = 1; break; case 4: sw = 2; break; case 8: sw = 3; break; } led_out = EX_SS_SW; } startConvertion(sw); //sw is ADC input Channel adc_value = readConvertData(); display_num[0] = (adc_value % 10000) / 1000; display_num[1] = (adc_value % 1000) / 100; display_num[2] = (adc_value % 100) / 10; display_num[3] = (adc_value % 10); _delay_ms(1000); } }return 0; }
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 }
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; } //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 } int main(void) { init_devices(); //Recieve Value print out while(1){ display_num[0] = (get_val % 10000) / 1000; display_num[1] = (get_val % 1000) / 100; display_num[2] = (get_val % 100) / 10; display_num[3] = (get_val % 10); _delay_ms(1000); } }
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 ecldi r24, 0xC6 ; 198 140: 86 b9 out 0x06, r24 ; 6 Interrupt Vector 0x0000_0000 ~ 0x0000_0088 ATmega128 Init_Funcs 0x0000_008C ~ 0x0000_00CA Port_init() 0x0000_00CE ~ 0x0000_00F8 Timer0_init() 0x0000_00FA ~ 0x0000_0106 ADC_init() 0x0000_0108 ~ 0x0000_0114 Usart0_init() 0x0000_0116 ~ 0x0000_012C ※ Init과 동시에 수행되는 함수들의 경우 이 곳에 Asm Code가 포함이 됨 (adc_init, timer0_init) 나머지는 call func_address의 형태를 가짐 (port_init, usart0_init) Init_devices() 0x0000_012E ~ 0x0000_015C Start_convert() 0x0000_015E ~ 0x0000_0168 readConvert Data() 0x0000_016A ~ 0x0000_018A ISR(TIMER0_OVF_VECT) 0x0000_018C ~ 0x0000_01FA Interrupt Vector 16 ISR(USART0_TX_VECT) Interrupt Vector 20 0x0000_01FC ~ 0x0000_0218 Main() 0x0000_021A ~ 0x0000_02FA Library_funcs 0x0000_02FC ~ 0x0000_0360 _exit() 0x0000_0362 ~ 0x0000_0362 _stop_program 0x0000_0364 ~ 0x0000_0364
Diagram TX_Complete_INT Interrupt Vector ISR(USART0_TX_VECT) SP Configuration Data Copy Etc. ATmega128 Init_Funcs Interrupt Occur Timer0_Ovf_INT Main() ISR(TIMER0_OVF_VECT) Init_devices() Port_init() ADC_init() R_TCNT0 (Timer0 Counter) R_UDR0 (Transmit buffer) Timer0_init() Usart0_init() Background Operation Timer0 Count USART0 Transmit ADC Converter If(Switch On) Change ADC Channel R_ADMUX (refVCC, Channel) R_ADCSRA (ADC Start) R_ADCL/H (ADC Result) Start_convert() R_ARCSRA (ADC_COMP INT) R_ADCL. ADCH (ADC Result) Wait ADC_Complete INT readConvert Data() ADC Complete Interrupt Occur 7Seg_data set Using 7Seg_data for 7seg Display _exit()
ADC Operation Time ADC Prescaler • KT-M128 Clock Speed : 16Mhz • 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 • 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) • 64 = 4us * 14.5 = 0.000,058s = 58us (832) • 128 = 8us * 14.5 = 0.000,116s = 116us (1664) ADC Operating Cycle ※ ADC에서 Sampling시 데이터의 손실이 발생하지 않기 위해서는 최대 128 * 13 Cycle (1664)이내에 ADC의결과를 가지고 하는 모든 연산을 끝내야 한다.
Program Timing Start Convert 7seg Display ADC Complete ADC_Complete 24.1875us 387 clk 2.125us 34 clk 0.4375us 7clk 7.1875us 115clk Next Convert Previous Convert 7.1875us 115 clk t Main Loop Get ADC Result Read Convert Data Get ADC Result If(SW_ON) Change Channel t Background ADC Complete Each 1ms Timer0 ovf Interrupt Each 1ms TX Comp Interrupt ADC START Each 1ms TX Comp Interrupt Timer0 ovf Interrupt USART Baud Rate : 9600 1 / 9600 = 0.0001sec 0.0001 * 10bit = 0.001 = 1ms 0.001(1ms) / 0.000 0000625 (16Mhz) = 16000 cycle