일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- behavioral modeling
- pwm
- D Flip Flop
- stop watch
- gpio
- Recursion
- hc-sr04
- ring counter
- verilog
- DHT11
- half adder
- Pspice
- vivado
- test bench
- uart 통신
- dataflow modeling
- KEYPAD
- java
- atmega 128a
- BASYS3
- LED
- Edge Detector
- Linked List
- soc 설계
- Algorithm
- ATMEGA128A
- FND
- prescaling
- structural modeling
- i2c 통신
- Today
- Total
거북이처럼 천천히
Separate Compilation 본문
1. Separate compilation이란?
- 분할 컴파일은 프로그램 설계하는 과정에서 유사한 함수 및 기능끼리 묶어 별개의 파일로 만들어 개발하는 방법을 의미
2. Separate Compilation의 장점
- 코드의 가독성이 좋음.
- 유지 보수 측면에서 효율적
- 수정 작업이 이루어진 코드에 대해서만 컴파일하기 때문에 불필요한 시간 없어짐
- 아래 예시를 통해 Separate Complication의 장점을 살펴보자.
※ 아래 코드들은 다음과 같은 기능을 수행한다.
※ 0번 비트 -> 3번 비트로 Left Shift하고, 7번 비트 -> 4번 비트로 Right Shift 하는 동시에 반전 출력
※ 3번 비트 -> 0번 비트로 Right Shift하는 동시에 반전 출력하고, 4번 비트 -> 7번 비트로 Left Shift
3. 예시 1. Main 함수안에 모든 기능을 구현한 경우
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
// Time Constant
#define TIME 1000
int main(void) {
// PORTD의 모든 핀을 출력으로 설정
// PORTD = 1111 1111
DDRD = 0xff;
while(1) {
// 0핀 -> 3핀으로 Left shift
// 7핀 -> 4핀으로 Right shift하는데, 반전 출력
for(int i=0; i<4; i++) {
PORTD = (~(PORTD1<<(3-i))<<4)|(PORTD1<<i);
_delay_ms(TIME);
}
// 3핀 -> 0핀으로 Right Shift하는데, 반전 출력
// 4핀 -> 7핀으로 Left Shift
for(int i=0; i<4; i++) {
PORTD = ((PORTD1<<i)<<4) | (~(PORTD1<<(3-i)) & (0x0f));
_delay_ms(TIME);
}
}
}
※ 소스 코드가 짧아 보이지만, 가독성과 유지 보수가 어렵다.
※ 소스 코드의 일부분을 수정하더라도 전체를 Build해야 한다.
4. 예시 2. 비슷한 기능끼리 묶어서 함수로 구현한 경우
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
// Time Constant
#define TIME 1000
// Function prototype.
void initDDR();
void move_inwards();
void move_outwards();
void control_LED();
void GPIO_Output(uint8_t data);
// Main method.
int main(void) {
initDDR();
while(1) {
control_LED();
}
}
// Control LED.
void control_LED() {
move_inwards();
move_outwards();
}
// Initialization for Data Direction Register
void initDDR() {
// PORTD의 8핀 모두를 출력으로 사용 설정
// PORTD = 1111 1111
DDRD = 0xff;
}
// Function that the LED bits to move inwards.
void move_inwards() {
for(int i=0; i<4; i++) {
// 왜 해당 data의 값이 아래와 같이 나왔는지 궁금하면 비트 단위로 그려보며 생각하기.
uint8_t data = (~(PORTD1<<(3-i))<<4)|(PORTD1<<i);
// 데이터 값 출력
GPIO_Output(data);
_delay_ms(TIME);
}
}
// Function that the LED bits to move outward.
void move_outwards() {
for(int i=0; i<4; i++) {
uint8_t data = ((PORTD1<<i)<<4) | (~(PORTD1<<(3-i)) & (0x0f));
// 데이터 값 출력
GPIO_Output(data);
_delay_ms(TIME);
}
}
// GPIO Output
void GPIO_Output(uint8_t data) {
PORTD = data;
}
※ main 함수에 모든 것을 구현한 경우보다 가독성과 유지 보수 측면에서 상대적으로 효율적이다.
※ 그러나 여전히 코드 일부분을 수정하면 전체를 Build 해야한다.
5. 에시 3. 비슷한 기능끼리 묶어 파일 단위로 분할하여 구현한 경우
- main.c
- controlLED.c (LED를 컨트롤을 위한 함수들을 묶은 파일)
- commonHeader.h (기본적으로 제공하는 라이브러리 파일을 include한 명령어를 묶은 파일)
- PersonalHeader.h (함수 원형 선언, 상수 선언 등을 묶은 파일)
// Include Common header file
#include "PersonalHeader.h"
// Main method.
int main(void) {
initDDR();
while(1) {
control_LED();
}
}
#include "PersonalHeader.h"
// Control LED.
void control_LED() {
move_inwards();
move_outwards();
}
// Initialization for Data Direction Register
void initDDR() {
// PORTD의 8핀 모두를 출력으로 사용 설정
// PORTD = 1111 1111
DDRD = 0xff;
}
// Function that the LED bits to move inwards.
void move_inwards() {
for(int i=0; i<4; i++) {
// 왜 해당 data의 값이 아래와 같이 나왔는지 궁금하면 비트 단위로 그려보며 생각하기.
uint8_t data = (~(PORTD1<<(3-i))<<4)|(PORTD1<<i);
// 데이터 값 출력
GPIO_Output(data);
_delay_ms(TIME);
}
}
// Function that the LED bits to move outward.
void move_outwards() {
for(int i=0; i<4; i++) {
uint8_t data = ((PORTD1<<i)<<4) | (~(PORTD1<<(3-i)) & (0x0f));
// 데이터 값 출력
GPIO_Output(data);
_delay_ms(TIME);
}
}
// GPIO Output
void GPIO_Output(uint8_t data) {
PORTD = data;
}
#ifndef COMMONHEADER_H_
#define COMMONHEADER_H_
// Preprocessor
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#endif
#ifndef PERSONALHEADER_H_
#define PERSONALHEADER_H_
// Time Constant
#define TIME 1000
// include CommonHeader file.
#include "commonHeader.h"
// Function prototype.
void initDDR();
void move_inwards();
void move_outwards();
void control_LED();
void GPIO_Output(uint8_t data);
#endif /* PERSONALHEADER_H_ */
구현 영상
'Embedded Programming (AVR) > Atmega 128A (실습)' 카테고리의 다른 글
궁금증 정리 노트 - Atmega128A (0) | 2024.05.25 |
---|---|
Pointer (0) | 2024.05.25 |
Atmega128a의 변수 정리 (0) | 2024.05.25 |
GPIO - LED control (2) (0) | 2024.05.25 |
GPIO - LED control (1) (0) | 2024.05.25 |