ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20140425 (UART Reg setting, c언어 파일 입출력, feof)
    부산IT학원/스마트컨트롤러 2014. 4. 25. 11:17

    50일차









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

    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이 아닌 값을 반환.






Designed by Tistory.