본문 바로가기
코스웨어/14년 스마트컨트롤러

2014년 4월 25일 양태영 [출석번호 16번]

by 알 수 없는 사용자 2014. 4. 25.
728x90
반응형

------------------------

ATMega128 UART

------------------------





----- UART 통신


UART 통신을 하기 위해


속도

데이터 사이즈

패리티

정지 비트

흐름 제어


등을 설정해야 한다.




----- UBRR Reg값으로 속도 설정

   속도를 입력하는 방법은 두 가지가 있는데

   첫번째로는 표에 명시된 속도를 구하는 공식이 있다.

        fosc : 동작주파수 (16Mhz)

        BAUD : 전송 속도 (115200 bps 사용 예정)


우리는 비동기 일반 모드를 사용할 계획이니

UBRR = ( fosc / ( 16 * baud ) ) -1 공식을 사용한다.




공식을 사용하지 않고는

표를 참고하여 UBRR의 값을 알아낼 수도 있습니다.

속도 115200 bps(115.2 kbps)를 사용할 예정이니 일반모드에

UBRR의 값은 8입니다.




※ 전송 속도를 115200 bps로 쓰는 이유는

우리가 통신을 하려는 PC에 직렬통신의 속도 목록이다.

시작 -> 모든프로그램 -> 보조프로그램 -> 통신 -> 하이퍼터미널 

실행시키면 확인할 수 있습니다.



이런 속도를 낼 수 있는데


 

PC와 ATMega간에 Hub 역할을 하는 변환기 (밑에 그림)



요놈의 속도 최대치가 115200 bps라서 115200 bps를 사용하기로 한다.






- 이제 소스로 돌아가서 소스코드 작성

UBRR Reg 에 값을 넣는 방법 2가지 중 하나를 택하여 코딩.

1안은 속도에 따라 UBRR의 값이 명시된 값을 바로 넣고

2안은 속도에 따라 UBRR의 값을 계산하여 넣는 방식.

UBRR에 8을 넣는다.


- Usart.h

 ....

// 2안

#define BAUD    115200    // bps speed
#define UBRR    (((F_OSC)/((BAUD)*16)) - 1)  // 공식

 ....


- Usart.c

#include "Usart.h"

void USART_Init(void)
{
/* 1안
  UBRR0H = 0x00;  // 115200bps를 맞춘값
  UBRR0L = 0x08;
  */


// 2안
  UBRR0H = UBRR>>8;  // 12bit를 쓰는데 하위 8비트를 버리고 상위 4bit 저장.
  UBRR0L = UBRR;
}


UBRR0H, UBRR0L로 나뉜것은


UBRR Reg가 12bit를 사용하는데

ATMega128은 8bit이므로

8bit인 Reg 두개를 합쳐서

상위비트와 하위비트로 나눠서 사용한다.

15~12는 예약비트로 사용하지 않는다.


8을 12비트 2진수로 바꾸면

0000 0000 1000 이다

앞에 0000        은  UBRR0H

뒤에 0000 1000 은  UBRR0L


뒤에 0000 1000을 지우기 위해

" >>8 " 왼쪽으로 8번 비트를 움직여서 없애고

앞에 0000만 UBRR0H에 들어간다.







----- 데이터 크기, 패리티, 정지 비트, 흐름 제어

설정을 하기위해

UCSRA, UCSRB, UCSRC Reg 사용한다.





----- UCSRA




- 7번 비트

수신 완료 비트

데이터가 수신되면 1로 바뀐다.


- 6번 비트

전송 완료 비트

전송이 완료 되었을 때 1로 바뀐다.


- 5번 비트

데이타 Reg(UDR)가 비었을 때 1로 바뀐다.

처음에 시작했을 땐 아무 값도 없으니 초기값이 1.


- 4번 비트

프레임 에러

송수신 데이터가 에러 났을 때 1로 바뀜.


- 3번 비트

데이타 오버런

데이터가 처리되지 않았는데

다음 데이터가 와서 덮어써졌을 때

1로 바뀜


- 2번 비트

패리티 비트

패리티 비트 오류가 났을 때 1로 바뀜


- 1번 비트

1이 들어가 있으면 속도 두배.


- 0번 비트

병렬처리

멀티모드

atmega끼리 연결할 때

최대속도가 2mega 속도가 난다.



이 중 프로그래머가 쓰기할 수 있는 곳은

6, 1, 0비트

다 0을 초기값으로 준다.







----- UCSRB



- 7, 6, 5번 비트

인터럽트 활성화

활성화시 1 넣음

우리는 인터럽트 아직 모르고

안쓸거니 0을 넣음


- 4번 비트

수신기 활성화

활성화시 1넣음

활성화 해야하니 1넣음.


- 3번 비트

송신기 활성화

활성화시 1넣음

활성해야 하니 1넣음.



- 2번 비트

Character size

한번에 몇 비트(데이터비트)씩 보낼지 결정.

5~9bit까지 사용 가능.

UCSZn2 역할.

UCSRC Reg 1, 0비트와 같이 씀

우리는 8bit 쓸 것이니 0으로 넣는다.




- 1번 비트

데이터비트 크기를 9bit로 사용할 경우

1bit가 모자라니 그 모자라는 8번째 bit로

Receive Data bit 8번으로 사용.


- 0번 비트

데이터비트 크기를 9bit로 사용할 경우

1bit가 모자라니 그 모자라는 8번째 bit로

Transmit Data bit 8번으로 사용.





----- UCSRC

는 다음 시간에.....



방금했던 Reg, bit에 기능을 Usart.h, Usart.c 파일에

정리한 소스.


- Usart.h

#ifndef _USART_H_
#define _USART_H_

#include "smart.h"

//UART Reg
#define UDR0      (*((volatile unsigned char *)0x2C))
#define UCSR0A  (*((volatile unsigned char *)0x2B))
#define UCSR0B  (*((volatile unsigned char *)0x2A))
#define UCSR0C  (*((volatile unsigned char *)0x95))
#define UBRR0L  (*((volatile unsigned char *)0x29))
#define UBRR0H  (*((volatile unsigned char *)0x90))
#define UDR1      (*((volatile unsigned char *)0x9C))
#define UCSR1A  (*((volatile unsigned char *)0x9B))
#define UCSR1B  (*((volatile unsigned char *)0x9A))
#define UCSR1C  (*((volatile unsigned char *)0x9D))
#define UBRR1L  (*((volatile unsigned char *)0x99))
#define UBRR1H  (*((volatile unsigned char *)0x98))

#define BAUD  115200    // bps speed
#define UBRR  (((F_OSC)/((BAUD)*16)) - 1)  // 공식

//UCSRA Reg bit
#define RXC      7
#define TXC      6
#define UDRE    5
#define FE        4
#define DOR      3
#define UPE      2
#define U2X      1
#define MPCM  0

//UCSRB Reg bit
#define RXCIE     7
#define TXCIE     6
#define UDRIE     5
#define RXEN      4
#define TXEN      3
#define UCSZ2    2
#define RXB8      1
#define TXB8      0

//UCSRC Reg bit
#define UMSEL  6
#define UPM1    5
#define UPM0    4
#define USBS    3
#define UCSZ1  2
#define UCSZ0  1
#define UCPOL  0

void USART_Init(void);

#endif // _USART_H_


- Usart.c

#include "Usart.h"

void USART_Init(void)
{
  UBRR0H = UBRR>>8;
  UBRR0L = UBRR;

  UCSR0A = (0<<TXC) | (0<<U2X) | (0<<MPCM);
  UCSR0B = (0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) |
        (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2);
  UCSR0C = ;
}












- C

--------------

파일 입출력

--------------




----- 파일 입출력 모드

fopen(위치, 모드) 함수의 인자 중에 두번째 인자값

모드에 따라 파일을 사용하는 방법이 달라진다



또 텍스트 모드와 바이너리 모드가 있는데

이 두 모드의 차이점은 개행처리가 다르다.

운영체제마다 개행문자가 다른데

- \n (c언어)

- \r\n (ms-dos)

- \r (Mac)

- \n (Unix 계열)


텍스트 모드로 저장할 시 개행을 그 운영체제에 맞게

바꿔서 저장해 준다.


바이너리 모드로 저장할 시 C언어 약속으로 \n

저장한다.


아래 예제로 텍스트 모드와 바이너리 모드 차이를 확인.


- 먼저 바이너리 모드

#include <stdio.h>

int main()
{
  int iNum = 321;
  FILE * fp = fopen("test.bin""w+b");

  fprintf(fp, "%d\n", iNum);

  fclose(fp);

  return 0;
}


test.bin 파일 내용 확인

(비주얼 스튜디오로 확인)




- 텍스트 모드

#include <stdio.h>

int main()
{
  int iNum = 321;
  FILE * fp = fopen("test.bin""w+t");

  fprintf(fp, "%d\n", iNum);

  fclose(fp);

  return 0;
}


test.bin 파일 내용 확인

(비주얼 스튜디오로 확인)




이런식으로 텍스트 모드와 바이너리 모드가

개행처리를 다르게 한다.


또 한 가지 사실은 출력된 문자, 숫자들은 아스키코드 값으로

바뀌어 저장이 된다는 것이다.






----- feof


파일을 쓸 때에 화면과 마찬가지로

다음 출력 위치를 나타내는 커서 같은 것이 있다.




이 커서(파일 포인터)가 파일 맨 마지막에 도달 시

EOF (End Of File)을 가리킴.


feof 함수는 이 커서가 끝에 도달 했는지 안했는지 알아보는 함수이다.


원형은

#include <stdio.h>

int feof(FILE * );


파일 끝에 도달하지 못 했을 때 0(실패)을 반환.

파일 끝에 도달했을 때 0이 아닌 값을 반환.



728x90