[Embedded Software] 경희대 임베디드 소프트웨어 과제1 - LED
on Study
개발 환경
- 개발보드 : JKIT-128-1
- MUC : ATmega128
- IDE : AVR Studio 4
- Compiler : WinAVR
실습 1
1.1 LED 모두 켜기/끄기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// LED 8개가 A포트에 연결되어 있다.
// 따라서 A포트의 DDR을 모두 사용으로 선언한다.
DDRA = 0xFF;
while(1) {
// LED는 Output으로 사용되기 때문에 PORT를 사용한다.
PORTA= 0xFF;
_delay_ms(1000);
PORTA= 0x00;
_delay_ms(1000);
}
}
1.2 첫번째(2, 3, …, 8번째) LED만 켜기/끄기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// unsigned로 선언한 이유는 singed bit(부호 비트)를 제거하여 사용하기 위함이다.
// 이렇게 선언함으로써 음수를 사용할 수는 없지만,
// 저장 가능한 양수의 범위가 두배로 늘어난다.
// 지금처럼 음수가 나오지 않을 경우에 사용하면 좋다.
unsigned char value = 1;
DDRA = 0xFF;
while(1) {
PORTA = value;
_delay_ms(10000);
// LED의 배열이 2비트 단위로 나열되어 있기 때문에 2를 곱했다.
value *= 2;
}
}
1.3 LED 하나씩 건너서 켜기/끄기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
DDRA = 0xFF;
while(1) {
PORTA = 0xAA;
_delay_ms(10000);
PORTA = 0x55;
_delay_ms(10000);
}
}
1.4 LED 2개씩 짝지어 켜기/끄기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
DDRA = 0xFF;
// 끝의 2개 비트의 LED를 킨다.
PORTA = 0x03;
_delay_ms(10000);
while(1) {
// 한 칸씩 left shift 시켜준다.
// A <<= 1 라는 코드는
// A = A << 1 과 같다.
PORTA <<= 1;
_delay_ms(10000);
}
}
1.5 양쪽 끝 한개만 LED 켜기/끄기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
DDRA = 0xFF;
PORTA = 0x81;
}
실습 2
2.1 2진 카운터 표현하기 (0~255, up)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
int i;
DDRA = 0xFF;
while(1) {
PORTA = 0x00;
for(i = 0; i < 0xFF; i++) {
PORTA += 0x01;
_delay_ms(10000);
}
}
}
2.2 링 카운터 표현하기(1개, 오른쪽으로 계속 이동)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// 오른쪽으로 이동하기 위해 MSB(Most Significant Bit) LED를 키는 것으로 초기화한다.
unsigned char value = 128;
DDRA = 0xFF;
while(1) {
PORTA = value;
_delay_ms(500);
// 한 칸씩 right shift 한다.
value >>= 1;
// LSB까지 이동을 하였으면 다시 MSB로 초기화하여 무한 루프를 돌게 한다.
if(value == 0) {
value = 128;
}
}
}
2.3 좌우로 왔다갔다 표현하기(1개씩)
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define LEFT 0
#define RIGHT 1
int main() {
// LSB에서 MSB로 left shift 하는 것으로 초기화한다.
unsigned char value = 1;
int direction = LEFT;
DDRA = 0xFF;
value = 128;
while(1) {
// left shift 하는 도중 MSB까지 도달하였을 경우
// right shift로 변경한다.
// value 값이 64인 이유는 오른쪽으로 한 비트 가기 위함이다.
if(direction == LEFT && value == 128) {
value = 64;
direction = RIGHT;
}
// left shift 를 하고 있지만 아직 MSB에 도달하지 못한 경우
else if(direction == LEFT && value != 128){
value <<= 1;
}
// right shift 하는 도중 LSB까지 도달하였을 경우
// left shift로 변경한다.
// value 값이 2인 이유는 왼쪽으로 한 비트 가기 위함이다.
else if(direction == RIGHT && value == 1) {
value == 2;
direction = LEFT;
}
// 나머지 경우
// right shift 를 하고 있지만 아직 LSB에 도달하지 못한 경우
else {
value >>= 1;
}
PORTA = value;
_delay_ms(500);
}
}
2.4 스피커 볼륨 표현하기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define INCREASE 1
#define DECREASE 0
int main() {
// 볼륨 스펙트럼이 증가하는 것처럼 보이기 위해,
// LSB에서 MSB로 left shift 하는 것으로 초기화 한다.
unsigned char value = 1;
int direction = INCREASE;
DDRA = 0xFF;
while(1) {
PORTA = value;
_delay_ms(500);
// left shift 하는 경우
if(direction == INCREASE) {
// MSB까지 도달한 경우
if(value == 255) {
direction = DECREASE;
value = 127;
}
// 아직 MSB까지 도달을 못한 경우
// LED를 누적해서 키기 위해 2의 배수의 +1 로 계산한다.
else {
value = value * 2 + 1;
}
}
// right shift 하는 경우
else {
// LSB까지 도달한 경우
if(value == 0) {
direction = INCREASE;
value = 1;
}
// 아직 LSB까지 도달을 못한 경우
else {
value = value / 2;
}
}
}
}
2.5 X-mas 트리(Random) 표현하기
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 160000000UL
int main() {
unsigned int a=17, b=49, c=103;
unsigned int value;
DDRA = 0xff;
while(1) {
value = (a++) * (b++) + (c++);
PORTA = value;
_delay_ms(1000);
}
}
실습 응용
문제: LED의 왼쪽에서부터 오른쪽까지를 ‘도레미파솔라시도’의 8음계라고 가정하고, 간단한 동요를 LED로 표현하는 프로그램을 작성하라.
노래: 작은별
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main() {
// '작은별' 의 노트를 배열 형태로 미리 작성했다.
// '작은별' 은 총 42개의 음으로 이루어져 있으며, 각 음의 길이는 일정하나
// 7번째의 음마다 나머지 음 보다 음의 길이가 두 배 이상 길어진다.
unsigned int song[ ] = {0x80, 0x80, 0x08, 0x08, 0x04, 0x04, 0x08,
0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80,
0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40,
0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40,
0x80, 0x80, 0x08, 0x08, 0x04, 0x04, 0x08,
0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80};
unsigned int i;
DDRA = 0xff;
for(i = 0; i < 42; i++) {
// 7번째 음마다 음의 길이를 길게 하기 위한 조건문
if((i % 7) == 6) {
PORTA = song[i];
_delay_ms(300);
}
PORTA = song[i];
_delay_ms(500);
PORTA = 0x00;
_delay_ms(500);
}
}