49일차
-----------------------
ATMega128 직렬통신
-----------------------
- PIN 당 몇 가지 기능을 가지고 있음.
![](https://t1.daumcdn.net/cfile/tistory/23766C3F5358809422)
1번 핀은 1가지 기능
2, 3번 핀은 3가지 기능
15, 16번 핀은 2가지 기능
한가지 기능을 사용 중이면 다른 기능은 사용할 수 없다.
- 시리얼 통신 RS-232 (UART 표준)
3선 - Tx (Transmitter 송신부)
- Rx (Receiver 수신부)
- G (Ground)
![](https://t1.daumcdn.net/cfile/tistory/267EA85053589E862F)
RS-232방식을 사용하는 장비와 통신할 때
다른 방식으로 작동하는 장비는 꼭 변환기를 거쳐야
장비에 손상을 주지 않고 통신할 수 있다
![](https://t1.daumcdn.net/cfile/tistory/25133E3853589D991A)
ATMega128의 경우
동기직렬통신(USART)도 가능하게 했다.
동기 통신의 경우 선이 더 추가되니 비용이 비싸지지만
속도가 빠르다.
비동기 통신의 경우 비용이 싸지지만 패리티bit(오류검출용)와
시작 신호, 끝 신호를 함께 보내기 때문에 속도도 느리다.
- USART 블럭 구조
![](https://t1.daumcdn.net/cfile/tistory/2749903E5358A2AF27)
- XCK 는 동기 통신할 경우 사용하는 신호선
- PARITY bit는 H의 갯수가 짝수로 맞출지 홀수로 맞출지에 따라서
그 갯수를 맞춰서 오류 검출용으로 사용하는 bit이다.
ex) 0110 1011로 정보를 보냈는데 parity를 짝수로 맞췄다면
parity bit에 1을 넣어주고
홀수로 맞췄다면 parity bit에 0을 넣어줘서
이 정보가 중간에 바뀌지 않았는지 오류 검출할 수 있다.
그러나 이것도 한 bit만 바뀌었을 경우 오류 판별할 수 있으나
두 bit이상 바뀌었을 경우 오류 판별은 힘들어진다.
- 소스 분할
각각 관련된 것끼리 분할하여 관리하기 더 쉽게 나눴다.
smart.h
#ifndef _SMART_H_
#define _SMART_H_
#define DDRA (*((volatile unsigned char *)0x3A))
#define PORTA (*((volatile unsigned char *)0x3B))
#define DDRC (*((volatile unsigned char *)0x34))
#define PORTC (*((volatile unsigned char *)0x35))
#define DELAY(x) for(uiCnt = 0; (x) > uiCnt; ++uiCnt)
#endif //_SMART_H_
Lcd.h
#ifndef _LCD_H_
#define _LCD_H_
#include "smart.h"
#define PIN_RS 0 // Register selection (Data : 1, Instruction : 0)
#define PIN_RW 1 // Read/Write selection (Read : 1, write : 0)
#define PIN_E 2 // Enable signal for LCD
#define INST_CLEAR 0x01 // Clear
#define INST_RETURN 0x02 // Return
#define INST_ENTRY 0x06 // I/D = 1(2 Increase 1, Decrease 0), S = 0
#define INST_FUNCTION 0x3C // 8bit, 2Line, 5x11
#define INST_SET_CGRAM 0x40 //
#define INST_SET_DDRAM 0x80 //
#define INST_CURSOR 0x14 // Cursor SET, Moving right.
#define INST_DISPLAY 0x0F // Display light ON, cursor ON, blinking of cursor ON
#define DNUM1 119
#define DNUM2 235
void LCD_Inst(unsigned char ucInst);
void LCD_Init(void);
void LCD_Data(unsigned char ucData);
void LCD_Str(const unsigned char * cString);
void LCD_Num(unsigned char ucNum);
#endif // _LCD_H_
Lcd.c
#include "Lcd.h"
void LCD_Inst(unsigned char ucInst)
{
volatile unsigned int uiCnt;
DDRA = (1<<PIN_RS) | (1<<PIN_RW) | (1<<PIN_E); // RS, RW, E Port initialize output.
DDRC = 0xFF; // all port initialize output.
PORTA = (0<<PIN_RS) | (0<<PIN_RW) | (0<<PIN_E); // A
DELAY(DNUM1);
PORTA = PORTA | (1<<PIN_E); // B
DELAY(DNUM2);
PORTC = ucInst; // Instruction
DELAY(DNUM1);
PORTA = PORTA & ~(1<<PIN_E); // D
DELAY(DNUM2);
return;
}
void LCD_Init(void)
{
volatile unsigned int uiCnt;
DELAY(500);
LCD_Inst(INST_FUNCTION);
LCD_Inst(INST_ENTRY);
LCD_Inst(INST_CURSOR);
LCD_Inst(INST_DISPLAY);
LCD_Inst(INST_CLEAR);
LCD_Inst(INST_RETURN);
}
void LCD_Data(unsigned char ucData)
{
volatile unsigned int uiCnt;
DDRA = (1<<PIN_RS) | (1<<PIN_RW) | (1<<PIN_E); // RS, RW, E Port initialize output.
DDRC = 0xFF; // all port initialize output.
PORTA = (1<<PIN_RS) | (0<<PIN_RW) | (0<<PIN_E); // A
DELAY(DNUM1);
PORTA = PORTA | (1<<PIN_E); // B
DELAY(DNUM2);
PORTC = ucData; // charactor.
DELAY(DNUM1);
PORTA = PORTA & ~(1<<PIN_E); // D
DELAY(DNUM2);
return;
}
void LCD_Str(const unsigned char * cString)
{
while(0 != *cString)
{
LCD_Data(*cString);
++cString;
}
}
void LCD_Num(unsigned char ucNum)
{
static unsigned char ucBuff[] = "123"; // 3자리 확보 보기 쉽게
ucBuff[0] = '0' + (ucNum / 100);
ucBuff[1] = '0' + ( (ucNum % 100) / 10);
ucBuff[2] = '0' + ( (ucNum % 100) % 10);
LCD_Str(ucBuff);
}
Usart.h
#ifndef _USART_H_
#define _USART_H_
#include "smart.h"
//UART Reg
#define UDR0 0x2C
#define UCSR0A 0x2B
#define UCSR0B 0x2A
#define UCSR0C 0x95
#define UBRR0L 0x29
#define UBRR0H 0x90
#define UDR1 0x9C
#define UCSR1A 0x9B
#define UCSR1B 0x9A
#define UCSR1C 0x9D
#define UBRR1L 0x99
#define UBRR1H 0x98
#endif // _USART_H_
Usart.c
main.c
#include "smart.h"
#include "Lcd.h"
#include "Usart.h"
int main(void)
{
volatile unsigned int uiCnt;
LCD_Init();
LCD_Inst(INST_SET_DDRAM | 0x00);
LCD_Str("abcd");
LCD_Inst(INST_SET_DDRAM | 0x40);
LCD_Str("1234");
while(1);
return 0;
}
makefile
....
# Target file name (without extension).
TARGET = main
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c Lcd.c Usart.c
.....
추가된 부분으로, 컴파일할 소스를 추가할 수 있다.
makefile은 스크립트 파일로
# 은 주석
L-value는 변수
R-value는 값
이다.
- C
------------------------
파일 입출력
------------------------
- fopen, fclose
파일을 열고 닫는 함수이다.
stdin, stdout, stderr도 일종에 파일로 인식한다.
ex) 소스
#include <stdio.h>
int main()
{
fclose(stdout);
fprintf(stdout, "This is first test.\n");
return 0;
}
출력화면을 보면 아무것도 안나온다.
원래라면 화면에 출력되어야 하는데
fclose로 표준출력(stdout)을 닫아 버렸기 때문이다.
이번에는 텍스트 파일에 출력을 해보자
ex) 소스
#include <stdio.h>
int main()
{
FILE * fp;
fp = fopen("test.txt", "w");
fprintf(fp, "This is first test.\n");
fclose(fp);
return 0;
}
출력 화면엔 아무것도 안나오고
"test.txt" 파일을 열어봤다
![](https://t1.daumcdn.net/cfile/tistory/2308E83F5358CB1835)