AVR 컨트롤러 - 7 Segment 카운터 만들기 2
학습목표
ATmega2560과 7segment 3개를 가지고 999까지의 카운터를 만들 수 있다.
99에서 100으로 넘어갈 때 십의 자리가 표시되지 않고 백의 자리는 1이 되어야 하는데 0으로 표시 되었다.
이것은 백의 자리 올림 조건이 99가 되어야 하는데 십의 자리 리셋 조건 9와 겹쳐서 99가 되지 않는 상황이 발생하였다.
하여 리셋조건을 없애고 나머지 값을 활용하여 간단하게 코드를 짰다.
/**** Main.c ****/
#include "SMART.h"
int main(void) { volatile unsigned int uiCnt; unsigned char cntD1=0, cntD2=0, cntD3=0; //카운팅을 위한 카운터 변수들 unsigned char FND[10] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x58, 0x00, 0x10};
DDRA = 0xFF; DDRB= 0x07; while(1)
{ /**** 출력 ****/ PORTA = FND[cntD1%10]; //PORTA에 FND배열에 cntD1을 넣어 출력 PORTB= 0x01; //3//1번째 자리 포트에만 불을 켜라 for(uiCnt=0; uiCnt <= 5000; ++uiCnt); PORTA = FND[cntD2%10]; //PORTA에 FND배열에 cntD2을 넣어 출력 PORTB= 0x02; //3//2번째 자리 포트에만 불을 켜라 for(uiCnt=0; uiCnt <= 5000; ++uiCnt);
PORTA = FND[cntD3%10]; //PORTA에 FND배열에 cntD3을 넣어 출력 PORTB= 0x04; //3//3번째 자리 포트에만 불을 켜라 for(uiCnt=0; uiCnt <= 5000; ++uiCnt);
/**** 올림 ****/ ++cntD3; if(cntD3%10==0) //9상태면 십의 자리에 올림을 해주어라 ++cntD2; if(cntD3%10==0&cntD2%10==0) //99상태면 백의 자리에 올림을 해주어라 ++cntD1;
} return 0;
}
|
/**** SMART.h ****/
#ifndef __SMART_H__ #define __SMART_H__
/**** General Purpose Register A - L ****/
#define PORTA (*((volatile unsigned char*)0x22)) #define DDRA (*((volatile unsigned char*)0x21)) #define PINA (*((volatile unsigned char*)0x20))
#define PORTB (*((volatile unsigned char*)0x25)) #define DDRB (*((volatile unsigned char*)0x24)) #define PINB (*((volatile unsigned char*)0x23))
#define PORTC (*((volatile unsigned char*)0x28)) #define DDRC (*((volatile unsigned char*)0x27)) #define PINC (*((volatile unsigned char*)0x26))
#define PORTD (*((volatile unsigned char*)0x2B)) #define DDRD (*((volatile unsigned char*)0x2A)) #define PIND (*((volatile unsigned char*)0x29))
#define PORTE (*((volatile unsigned char*)0x2E)) #define DDRE (*((volatile unsigned char*)0x2D)) #define PINE (*((volatile unsigned char*)0x2C))
#define PORTF (*((volatile unsigned char*)0x31)) #define DDRF (*((volatile unsigned char*)0x30)) #define PINF (*((volatile unsigned char*)0x2F))
#define PORTG (*((volatile unsigned char*)0x34)) #define DDRG (*((volatile unsigned char*)0x33)) #define PING (*((volatile unsigned char*)0x32))
#define PORTH (*((volatile unsigned char*)0x102)) #define DDRH (*((volatile unsigned char*)0x101)) #define PINH (*((volatile unsigned char*)0x100))
#define PORTJ (*((volatile unsigned char*)0x105)) #define DDRJ (*((volatile unsigned char*)0x104)) #define PINJ (*((volatile unsigned char*)0x103))
#define PORTK (*((volatile unsigned char*)0x108)) #define DDRK (*((volatile unsigned char*)0x107)) #define PINK (*((volatile unsigned char*)0x106))
#define PORTL (*((volatile unsigned char*)0x10B)) #define DDRL (*((volatile unsigned char*)0x10A)) #define PINL (*((volatile unsigned char*)0x109))
/* PORT 사용별 이름 지정 */
#define LCD_CTL PORTG #define LCD_BUS PORTA
#define LCD_CTL_DDR DDRG #define LCD_BUS_DDR DDRA
/* LCD PIN */
#define LCD_RS 0 #define LCD_RW 1 #define LCD_EN 2
/* CPU 동작시간을 맞춰주기 위한 Dealy문과 값 지정 */
#define Delay(x) for(uiCnt=0; uiCnt<(dNum1); ++uiCnt)
#define dNum1 50000 #define dNum2 300000 #define dNum3 10000000
/* LCD 제어 명령어 */
#define LCD_CLR 0x01; //화면 지우기, 커서홈 -0B 0000 0001 #define LCD_HOME 0x02; //커서 처음 위치로 이동 - OB 0000 001 #define LCD_ENR 0x06; //어드레스 자동증가/감소(I/D) = 1(증가), 표시 쉬프트(s)=1(표시) - 0B 0000 0111 #define LCD_DSP 0x0F; //디스플레이(D)=1(표시), 커서(C)=1(표시), 깜빡임(B) on/off=1(on) - 0B 0000 1111 #define LCD_CUR 0x14; //표시=1(표시), 커서 이동=1(오른쪽으로 쉬프트) - OB 0001 11-- #define LCD_FUNC 0x38; //인터페이스(DL) = 1(8비트), 라인수(N)=1(2라인), 문자폰트(F)=0(5*8) - OB 0011 10--
/* LCD Write mode 초기화 설정 */ // RS : High = data register, Low = Instruction Register // R/W : High = read, Low = write
#endif //__SMART_H__
|