2023. 5. 31. 23:42ㆍEmbedded/마이크로프로세서
- LED 1
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 16000000UL
void Initial_set(void)
{
DDRA = 0xFF;
PORTA = 0xFE;
DDRC = DDRC & ~(1<<DDC0);
PORTC = PORTC | 1<<PC0;
}
int main(void)
{
unsigned char led = 0xFE;
Initial_set();
while(1){
if(!(PINC & 1<<PC0)){
do{
PORTA = led;
_delay_ms(500);
led <<= 1;
led |= 0x01;
}while(led != 0x7f);
do{
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
}while(led != 0xfe);
}
else PORTA = 0xfe;
}
return 0;
}
- 코드설명
DDRA = 0xFF; //포트A의 DDA7~DDA0까지 전부 입력을 받는다
PORTA = 0xFE; //포트A의 DDA0번만을 출력으로 받는다
포트A의 입출력 상태를 나타낸다.
DDRC = DDRC & ~(1<<DDC0); //포트C의 DDC0번만 입력으로 받는다.
PORTC = PORTC | 1<<PC0; //PC0번에만 1을 받는다.
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
DDRC | DDR7 | DDR6 | DDR5 | DDR4 | DDR3 | DDR2 | DDR1 | DDR0 |
X | X | X | X | X | X | X | 0 | |
PORTC | PC7 | PC6 | PC5 | PC4 | PC3 | PC2 | PC1 | PC0 |
X | X | X | X | X | X | X | 1 |
DDRC에서 DDRC & ~(1<<DDC0)코드는 0xFE와는 다른 코드이다. 이 코드는 DDC7~DDC1까지는 1로 받는게 아니라 포트자체를 쓰지 않는다는 의미 이다. PORTC | 1<<PC0 이 코드 또한 PC7~PC1까지는 포트자체를 쓰지 않겠다는 의미이다.
do{
PORTA = led;
_delay_ms(500);
led <<= 1;
led |= 0x01;
}while(led != 0x7f);
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
led | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
led<<=1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
led|=0x01 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
led | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
Led값이 1111 1110에서 1111 1101로 자리이동 한다. 이때 do while반복문 안에 있으므로 led값이 1111 1110, 1111 1101, 1111 1011...0111 1111이 될 때까지 반복한다.
do{
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
}while(led != 0xfe);
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
led | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
led>>=1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
led|=0x80 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
led | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
이 반복문도 0111 1111, 1011 1111, 1101 1111...의 순으로 진행하며 1111 1110이 될 때까지 반복한다.
if(!(PINC & 1<<PC0))
이때 1<<PC0을 받아 0000 0001이 되고
PINC & 1<<PC0으로 0000 000PINC0이 된다.
!(PINC & 1<<PC0)이기 때문에 PINC0이 0이되면 1이 되고 1이 되면 0이 된다. 그러므로 PINC0의 기능을 하는 스위치1번을 올리면 IF문을 반복하고 내리면 반복을 멈춘다.
- LED 2
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 16000000UL
unsigned char led[8]={0xFE,0xFD, 0xFB, 0xF7,0xEF, 0xDF, 0xBF, 0x7F};
void Initial_set(void)
{
DDRA = 0xFF ;
PORTA = 0xFE ;
DDRC = DDRC & ~(1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3);
PORTC = PORTC | 1<<PC0 | 1<<PC1 | 1<<PC2 | 1<<PC3;
}
void Left_4led(void)
{ PORTA = ~(led[0] & led[1] & led[2] & led[3]); }
void Right_4led(void)
{ PORTA = (led[0] & led[1] & led[2] & led[3]); }
void Odd_led(void)
{ PORTA = (led[1] & led[3] & led[5] &led[7]); }
void Even_led(void)
{ PORTA = ~(led[1] & led[3] & led[5] &led[7]); }
void Shift_left(void){
for(int i = 0; i<8; i++){
if(i==8){
i = 0;
}
PORTA = led[i];
_delay_ms(1000);
}
}
void Shift_right(void){
for(int i=7; i>0; i--){
if(i==-1){
i=7;
}
PORTA = led[i];
_delay_ms(1000);
}
}
void Off_led(void){
PORTA = ~(led[0] & led[1] & led[2] & led[3] & led[4] & led[5] & led[6] &led[7]); }
int main(void)
{
unsigned char keyin; // 입력데이터를 받아 저장할 메모리 확보
Initial_set();
while(1){
keyin= PINC & 0x0F; // 상위 4비트는 0으로 mask, 하위 4비트를 조사
switch(keyin){
case 0x0E :
Left_4led();
break;
case 0x0D:
Right_4led();
break;
case 0x0B:
Odd_led();
break;
case 0x07:
Even_led();
break;
case 0x0C:
Shift_left();
break;
case 0x09:
Shift_right();
break;
case 0x03:
Off_led();
break;
default :
PORT
A = 0xFE;
break; }
}
return 0;
}
- 코드설명
DDRC = DDRC & ~(1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3);
PORTC = PORTC | 1<<PC0 | 1<<PC1 | 1<<PC2 | 1<<PC3;
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
DDRC | DDA7 | DDA7 | DDA7 | DDA7 | DDA7 | DDA7 | DDA7 | DDA7 |
X | X | X | X | 0 | 0 | 0 | 0 | |
PORTC | PA7 | PA7 | PA7 | PA7 | PA7 | PA7 | PA7 | PA7 |
X | X | X | X | 1 | 1 | 1 | 1 |
DDRC에선 0~3번까지만 입력을 받고 PORTC도 0~3번까지만 출력을 하게 한다. 이번실험에선 스위치가 PINC에 해당하므로 1,2,3,4의 스위치를 입출력 받게 설정한다.
void Left_4led(void)
{ PORTA = ~(led[0] & led[1] & led[2] & led[3]); }
void Right_4led(void)
{ PORTA = (led[0] & led[1] & led[2] & led[3]); }
void Odd_led(void)
{ PORTA = (led[1] & led[3] & led[5] &led[7]); }
void Even_led(void)
{ PORTA = ~(led[1] & led[3] & led[5] &led[7]); }
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Left_4led | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
Right_4led | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
Odd_led | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
Even_led | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
각 함수들은 위의 표와 같이 Led가 출력된다.
void Shift_left(void){
for(int i = 0; i<8; i++){
if(i==8){
i = 0; }
PORTA = led[i];
_delay_ms(1000); }
}
이 함수는 for문을 이용하여 초기상태에서 좌측으로 자리이동을 나타내는 함수이다.
void Shift_right(void){
for(int i=7; i>0; i--){
if(i==-1){
i=7;
}
PORTA = led[i];
_delay_ms(1000);
}
}
이 함수는 for문을 이용하여 초기상태에서 우측으로 자리이동을 나타내는 함수이다.
void Off_led(void){
PORTA = ~(led[0] & led[1] & led[2] & led[3] & led[4] & led[5] & led[6] &led[7]); }
Led의 출력을 나타내는 PORTA에 led[0]~led[7]의 코드를 이용해 모든 Led를 점등하게 한 후 NOT기호를 사용하여 모든 Led를 소등하게 한다.
switch(keyin){
case 0x0E :
Left_4led();
break;
case 0x0D:
Right_4led();
break;
case 0x0B:
Odd_led();
break;
case 0x07:
Even_led();
break;
case 0x0C:
Shift_left();
break;
case 0x09:
Shift_right();
break;
case 0x03:
Off_led();
break;
default :
PORT
A = 0xFE;
break; }
이 코드는 switch문을 사용하여 스위치를 올렸을시 사용되게 하는 코드를 설정한 코드이다. 만약 스위치가 모두 내려갔으면 default문을 통해 Led가 초기상태인 0xFE상태로 바뀌게 해준다.
'Embedded > 마이크로프로세서' 카테고리의 다른 글
ATMEGA128 포토인터럽트 제어 실험 (0) | 2023.06.01 |
---|---|
ATMEGA128 Roullette 모형 제어 (0) | 2023.06.01 |
ATMEGA128 Motor 제어 실험 (0) | 2023.06.01 |
ATMEGA128 RELAY 제어 실험 (0) | 2023.06.01 |
ATMEGA128 FND제어 실험 (0) | 2023.06.01 |