일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- verilog
- i2c 통신
- uart 통신
- BASYS3
- soc 설계
- behavioral modeling
- dataflow modeling
- atmega 128a
- vivado
- stop watch
- FND
- Edge Detector
- Recursion
- java
- prescaling
- half adder
- KEYPAD
- Pspice
- D Flip Flop
- structural modeling
- DHT11
- ring counter
- gpio
- ATMEGA128A
- Linked List
- hc-sr04
- Algorithm
- pwm
- LED
- test bench
- Today
- Total
거북이처럼 천천히
GPIO - LED control (2) 본문
1) 환경 : Microchip studio
2.) 목표 : 0핀 -> 3핀 -> 0핀, 7핀 -> 4핀 -> 7핀 LED를 Shift하여 출력
3) Source code
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define TIME 150
int main(void) {
// PORTD의 8핀을 출력으로 설정
// PORTD = 1111 1111
DDRD = 0xff;
while(1) {
for(uint8_t i=0; i<4; i++) {
// 7번째 핀과 0번째 핀에서부터 시작해서
// 7번쩨 핀은 Left Shift, 0 번째 핀은 Right Shift
// OR 연산을 통해 서로 다른 Binary을 합쳐 동시에 출력을 발생시키게 만든다.
PORTD = (PORTD1<<i) | (0x80>>i);
_delay_ms(TIME);
}
// i의 값을 1 ~ 3으로 설정한 이유
// 0 ~ 4까지로 설정할 경우, 0, 3, 4, 7핀이 중복해서 불이 들어오기 때문에
// 이를 방지하기 위해 1 ~ 3으로 설정
for(uint8_t i=1; i<3; i++) {
// 4번째 핀과 3번째 핀에 도착하면 방향 전환을 하여 다시 시작점으로 돌아가기.
PORTD = (0x10<<i) | (0x08>>i);
_delay_ms(TIME);
}
}
}
4) 구현
2.) 목표 : 0핀 -> 3핀 -> 0핀, 7핀 -> 4핀 -> 7핀 LED를 Shift하여 출력하는데, Shift 하는 비트를 제외하고,
나머지 비트에서만 불이 들어오도록 설계
3) Source code
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define TIME 150
int main(void) {
// PORTD의 모든 핀을 출력으로 설정
DDRD = 0xff;
while(1) {
// ~, NOT 연산자를 통해 특정 비트의 값을 0, 나머지 비트 값들을 1로 만들어 줌으로서
// 특정 비트만 LED가 안나오고, 나머지 비트에서는 LED가 나오도록 설계
for(int i=0; i<8; i++) {
PORTD = ~(PORTD1<<i);
_delay_ms(TIME);
}
for(int i=1; i<7; i++) {
PORTD = ~(0x80>>i);
_delay_ms(TIME);
}
}
}
※ ~ (NOT 연산자)를 이용하여 반전을 발생시킬 수 있다.
4) 구현
2.) 목표 : 0핀 -> 3핀 -> 0핀, 7핀 -> 4핀 -> 7핀 LED를 Shift하여 출력하는데, Shift 비트에서는 LED가 들어오지 않고, 나머지 비트에서만 LED가 출력되어야 한다.
3) Source code
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#define TIME 150
int main(void) {
// PORTD의 8핀 전부를 출력으로 설정
DDRD = 0xff;
while(1) {
// 0번째핀은 Right Shift, 7번째 핀은 Left Shift연산 수행
for(int i=0; i<4; i++) {
// Shift 연산자가 OR Bit 연산자보다 우선순위가 높다.
PORTD = ~(PORTD1<<i | 0x80>>i);
_delay_ms(TIME);
}
// 4번째핀은 Left Shift, 3번째 핀은 Right Shift연산 수행
for(int i=1; i<3; i++) {
PORTD = ~(0x10<<i | 0x08>>i);
_delay_ms(TIME);
}
}
}
4) 구현
2.) 목표 : 0핀 -> 3핀으로 Shift할 때는 일반적인 출력이 나오지만, 4핀 -> 7핀으로 Shift할 때는 반전 출력이 나온다.7핀 -> 4핀으로 Shift할 때는 반전 출력이 나오지만, 3핀 -> 0핀으로 Shift할 때는 일반적인 출력이 나온다.
3) Source code (Pointer + separate compilation으로 구현)
#include "personal.h"
int main(void) {
// Initialization Data Direction Register.
init_DDR();
// Define start point.
uint8_t data = PORTD0;
while(1) {
// Left Shift
for(uint8_t i=0; i<8; i++)
left_shift(&data, i);
// Right Shift
for(uint8_t i=1; i<7; i++)
right_shift(&data, i);
}
}
#include "personal.h"
// Initialization DDR(Data Direction Register)
void init_DDR() {
LED_DDR = 0xff;
}
// GPIO Output
void GPIO_Output(uint8_t data) {
LED_PORT = data;
_delay_ms(TIME);
}
// Left Shift
void left_shift(uint8_t *data, uint8_t index_shift) {
if(PORTD0<=index_shift && index_shift<PORTD4) *data = (*data>>PORTD7 | PORTD1<<index_shift);
else *data = (*data<<PORTD7 | (~(PORTD1<<index_shift) & (0xf0)));
GPIO_Output(*data);
}
// Right Shift
void right_shift(uint8_t *data, uint8_t index_shift) {
if(PORTD0<=index_shift && index_shift<PORTD4) *data = (*data<<PORTD7 | (~(0x80>>index_shift) & (0xf0)));
else *data = (*data<<PORTD7 | 0x80>>index_shift);
GPIO_Output(*data);
}
#ifndef COMMON_H_
#define COMMON_H_
// re-substitute CLK & include library file.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#endif /* COMMON_H_ */
#ifndef PERSONAL_H_
#define PERSONAL_H_
// Include common header file.
#include "common.h"
// Substitute constant
#define LED_DDR DDRD
#define LED_PORT PORTD
#define TIME 200
// Function prototype
void init_DDR();
void GPIO_Output(uint8_t data);
void left_shift(uint8_t *data, uint8_t index_shift);
void right_shift(uint8_t *data, uint8_t index_shift);
#endif /* PERSONAL_H_ */
4) 구현
※ 기타
1) 경기인력개발원에서 수업중 필기 했던 코드
→ 두 번째 구현과 유사한 코드이지만, 큰 차이 없음
→ 나중을 대비하여 Source code 첨부
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
// F포트를 출력으로 사용하겠다는 것을 표현하기 위해 1로 설정
// 만약 D포트를 출력으로 사용하겠다고 선언하고 싶으면 DDRD = 0xff;라고 선언
DDRF = 0xff; //0b11111111; F포트 전체를 출력으로 설정
while (1)
{
// F포트에서 몇번째 단자(비트)에 어떤 출력(High level? Low level? 어떤 단자에 어떤 출력을 줄 것인지?)
// PORTF = 0xff; 는 F포트 전체 출력으로 High level로 주겠다는 의미
PORTF = 0xff; // 8비트 전체를 출력(High)
_delay_ms(500); // 0.5초 동안 정지.
// PORTF = 0x00; 는 F포트 전체 출력으로 Low level로 주겠다는 의미
PORTF = 0x00; // 8비트 전체를 끔(Low)
_delay_ms(500); // 0.5초 동안 정지.
}
}
2) Atmega128a Datasheet에서 DDRD, PORTD
'Embedded Programming (AVR) > Atmega 128A (실습)' 카테고리의 다른 글
궁금증 정리 노트 - Atmega128A (0) | 2024.05.25 |
---|---|
Pointer (0) | 2024.05.25 |
Separate Compilation (0) | 2024.05.25 |
Atmega128a의 변수 정리 (0) | 2024.05.25 |
GPIO - LED control (1) (0) | 2024.05.25 |