반응형

마이크로컨트롤러에서 사용할 수 있는 범용 입출력 핀의 수는 많지 않으므로 직렬 통신이 사용된다.

직렬 통신은 1개의 입출력 핀을 통해 8개 비트를 8번에 나누어 전송하는 방식이다.

직렬 통신 중 가장 흔히 사용되는 UART로 진행한다.

UART 통신은 전이중 통신으로 송신과 수신을 동시에 진행할 수 있으며 이를 위해서 2개의 범용 입출력 핀이 필요하다.

ATMega328(아두이노 우노 칩에서 사용되는)에서는 PD0 핀과 PD1 핀이 사용된다. (아두이노 우노는 0, 1핀이다.)

/*
 * UART_TEST.c
 *
 * Created: 2023-06-20 오후 8:46:56
 * Author : Yoon
 */ 
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>

void UART_INIT(void)
{
	UCSR0A |= (1 << U2X0);   // 2배속 모드
	
	UBRR0H = 0x00;           // 9600bps
	UBRR0L = 207;          
	
	UCSR0C |= 0x06;          // 비동기, 8bit 데이터, 1bit start, 1bit stop, no parity
	
	UCSR0B |= (1 << RXEN0);  // 수신 가능
	UCSR0B |= (1 << TXEN0);  // 송신 가능
}

unsigned char UART_receive(void)
{
	while(!(UCSR0A & (1 << RXC0)));  // 데이터 수신 대기
	return UDR0;
}

void UART_transmit(unsigned char data)
{
	while(!(UCSR0A & (1 << UDRE0)));  // 송신 가능 대기
	UDR0 = data;                      // 데이터 전송
}

int main(void)
{
	unsigned char data;
	
	UART_INIT();             // UART 통신 초기화
    while (1) 
    {
		data = UART_receive();   // 데이터 수신
		UART_transmit(data);     // 수신된 문자를 에코백
    }
	
	return 0;
}

UART 결과

1. UCSR0A(USART Control and Status Register 0A) 레지스터 : UART 통신의 제어와 상태 체크

UX20 : 비동기 전송모드에서만 사용되며, 2배속 모드이면 1, 1배속 모드이면 0의 값을 가진다.

RXC0 : 수신 버퍼(UDR0)에 읽지 않은 문자가 있을 때는 1이 되고, 버파가 비어 있을 때는 0이 된다. UCSR0B 레지스터의 RXCIE0 비트와 함께 사용되어 수신 완료 인터럽트를 발생시킬 수 있다.

UDRE0 : 송신 버퍼(UDR0)가 비어 있어 데이터를 받을 준비가 되어 있을 때 1이 된다. UCSR0B 레지스터의 UDRIE0 비트와 함께 사용되어 송신 데이터 레지스터 준비 완료 인터럽트를 발생시킬 수 있다.

2. UCSR0B

RXCIE0 : 수신 완료 인터럽트를 발생을 허용한다.

TXCIE0 : 송신 완료 인터럽트를 발생을 허용한다.

RXEN0 : UART 수신기의 수신 기능을 활성화한다.

TXEN0 송신기의 송신 기능을 활성화한다.

3. UCSR0C : 데이터 형식 및 통신 방법을 결정한다.

4. UBRR0H, HBRR0L : 보율을 12비트로 표현한다.

5. UDR0 : 송수신된 데이터가 저장되는 버퍼 레지스터

 

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.7.374\include\avr

 

#include <stdio.h>
#include <stdint.h>

void printBinary(uint8_t value) {
  for (int i = 7; i >= 0; i--) {
    if ((value >> i) & 1)
      printf("1");
    else
      printf("0");
  }
  printf("\n");
}

int main(void) {
  uint8_t UCSR0A = 0b00000000;
  uint8_t U2X0 = 1;
  uint8_t RXC0 = 7;
  uint8_t UDRE0 = 5;
  
  printf("UCSR0A in binary: ");
  printBinary(UCSR0A);

  UCSR0A |= (1 << U2X0);
  printf("[init] UCSR0A in binary: ");
  printBinary(UCSR0A);

  UCSR0A = !(UCSR0A & (1 << RXC0));
  printf("[RX] UCSR0A in binary: ");
  printBinary(UCSR0A);

  UCSR0A = !(UCSR0A & (1 << UDRE0));
  printf("[TX] UCSR0A in binary: ");
  printBinary(UCSR0A);

  UCSR0A = UCSR0A & (1 << RXC0);
  printf("[RX] UCSR0A in binary: ");
  printBinary(UCSR0A);

  UCSR0A = UCSR0A & (1 << UDRE0);
  printf("[TX] UCSR0A in binary: ");
  printBinary(UCSR0A);
  
  return 0;
}

728x90
반응형
반응형

아두이노 우노에 USB-Serail 대신 ISP 장치를 이용해 업로드를 할 예정임.

ISP 방식은 ISP 장치가 별도로 필요하며, C 스타일 프로그래밍으로 레지스터를 직접 제어할 수 있음.

리셋 핀으로 직접 연결하여 SP 통신 방식을 사용함.

아두이노는 ATmega328을 기본으로 만들어진 보드로, 8bit CPU를 포함하고 있으며, 핀 8개를 묶어서 포트 단위로 입출력이 행해짐.

ATMega328은 1MHz 내부 클럭이지만, 아두이노 우노 보드는 외부 클럭 16MHz 크리스털을 사용함.

보드 : 아두이노 우노 

프로그래머 :  AVRISP MKII 

ISP 장치는 AVRISP MKII를 사용함.

ISP장치로 업로드할 경우, USB-Serial 방식을 사용할 수 없으므로 주의할 것.

(다시 아두이노 방식을 사용하기 위해선 부트로더를 다시 올려야 함.)

728x90
반응형

'임베디드 > AVR' 카테고리의 다른 글

[AVR] 아두이노 우노 UART 통신하기  (0) 2023.06.20
아트멜 스튜디오 시작하기.  (0) 2023.06.18

+ Recent posts