BASIC4MCU | 질문게시판 | atmega128 7segment 에 딜레이 주기
페이지 정보
작성자 리리스몬 작성일2019-06-03 13:38 조회6,252회 댓글0건본문
자판기 동작을 나타낸 마이크로프로세서
// PA : 7segment Data
// PB : LED I/O
// PC : LCD Data
// PD : LCD Control
// PE : Switch Intrrupt
// PF : 7segment Scan#include <avr/io.h>
#include <avr/interrupt.h>#define WRITE_COMMAND (PORTD &= ~0x10)
#define WRITE_DATA (PORTD |= 0x10)
#define ENABLE_LCD (PORTD |= 0x40)
#define DISABLE_LCD (PORTD &= ~0x40)// Variable Set
unsigned char SegDEC[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned char SegData[4] = {0xC0,0xC0,0xC0,0xC0};
unsigned char CntScan = 0;
unsigned int CntSeg4 = 0;
unsigned int CntSeg5 = 0;
unsigned int CntSeg6 = 0;
int led_status1 = 0;
int led_status2 = 0;
int led_status3 = 0;
int status_linked = 0;
int lcd_status = 0;
int lcd_delete = 0;// Delay Set
void delay_us(unsigned char time_us) {
register unsigned char a;
for(a=0; a<time_us; a++) {
asm volatile("PUSH R0 ");
asm volatile("POP R0 ");
asm volatile("PUSH R0 ");
asm volatile("POP R0 ");
asm volatile("PUSH R0 ");
asm volatile("POP R0 ");
}
}void delay_ms(unsigned int time_ms) {
register unsigned int a;
for(a=0; a<time_ms; a++) {
delay_us(250);
delay_us(250);
delay_us(250);
delay_us(250);
}
}// T/C Register Set
void init_timer0(void) {OCR0 = 124; // 8usec*(1+124) = 1.0msec Period
TCCR0 = 0x0D; // 00001101 : 0(FOC0) 0(WGM00) 00(COM01,00) 1(WGM01) 101(CS02,01,00)
// WGM01,WGM00 = 10 : CTC Mode
// COM01,COM00 = 00 : Disable OC Output
// CS02,CS01,CS00 = 101 : CK(16MHz)/128 = 125kHz: 8usec
TIMSK |= 0x02; // BIT1(OCIE0) = 1: T/C0 Output Compare Match Interrupt Enable
}// Interrupt Register Set
void init_ext_int4_5_6(void) {EICRB |= 0x2A; // ISC61,60,51,50,41,40 : 00101010 (PE6, PE5, PE4 Falling Edge)
EIMSK |= 0x70; // INT6,5,4 : Interrupt Enable
EIFR = 0x70; // INTF6,5,4 : Interrupt Flag Clear
}//7segment, LCD Port Initialization
void init_port(void) {// LCD Data
PORTC = 0x00;
DDRC = 0xFF;// LCD Control(PD4: RS, PD5: R/W, PD6: E)
PORTD &= ~0x70;
DDRD |= 0x70;
// 7segment Data
PORTA = 0xFF;
DDRA = 0xFF;// 7segment Scan
PORTF |= 0x0F;
DDRF |= 0x0F;
}// 7segment Dynamic Scan
ISR(TIMER0_COMP_vect) {PORTF |= 0x0F;
PORTA = SegData[CntScan];
PORTF &= ~(1 << CntScan);if(++CntScan > 3) CntScan = 0;
}// LCD Set
void init_LCD(void)
{
delay_ms(100); // 15msec delayWRITE_COMMAND;
PORTC = 0x30; // 8bit interface
ENABLE_LCD;
DISABLE_LCD;delay_ms(10); // 4.1msec delay
WRITE_COMMAND;
PORTC = 0x30; // 8bit interface
ENABLE_LCD;
DISABLE_LCD;delay_ms(1); // 100usec delay
WRITE_COMMAND;
PORTC = 0x30; // 8bit interface
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);WRITE_COMMAND;
PORTC = 0x38; // Function Set(2 lines, 5*7 dots)
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);WRITE_COMMAND;
PORTC = 0x0C; // Display On/Off Control(Display On)
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);WRITE_COMMAND;
PORTC = 0x01; // Clear Display
ENABLE_LCD;
DISABLE_LCD;
delay_ms(10);WRITE_COMMAND;
PORTC = 0x06; // Entry Mode Set(Increment Cursor Position, No Display Shift)
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);
}void gotoxy_LCD(unsigned char x, unsigned char y)
{
WRITE_COMMAND;
PORTC = 0x80 + x + 0x40*y;
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);
}void putchar_LCD(unsigned char data)
{
WRITE_DATA;
PORTC = data;
ENABLE_LCD;
DISABLE_LCD;
delay_ms(1);
}// INT4 Service Routine
void disp_seg4_DEC(unsigned int data) {
SegData[0] = SegDEC[data];
SegData[1] = SegDEC[0];
SegData[2] = SegDEC[0];
SegData[3] = SegDEC[0];}
ISR(INT4_vect) {
if(++CntSeg4 == 1) {
disp_seg4_DEC(CntSeg4);
CntSeg4 = 0;
led_status1 = 1;
lcd_status = 1;
lcd_delete = 1;
}
}// INT5 Service Routine
void disp_seg5_DEC(unsigned int data) {
SegData[0] = SegDEC[0];
SegData[1] = SegDEC[data*4];
SegData[2] = SegDEC[0];
SegData[3] = SegDEC[0];}
ISR(INT5_vect) {
if(++CntSeg5 == 1) {
disp_seg5_DEC(CntSeg5);
CntSeg5 = 0;
led_status2 = 1;
lcd_status = 2;
lcd_delete = 2;
}
}// INT6 Service routine
void disp_seg6_DEC(unsigned int data) {SegData[0] = SegDEC[0];
SegData[1] = SegDEC[0];
SegData[2] = SegDEC[0];
SegData[3] = SegDEC[0];}
ISR(INT6_vect) {
if(++CntSeg6 == 1) {
disp_seg6_DEC(CntSeg6);
CntSeg6 = 0;
led_status3 = 1;
lcd_status = 3;
lcd_delete = 3;
}
}int main() {
init_port();
init_LCD();
init_timer0();
init_ext_int4_5_6();//Call interruptSREG |= 0x80; // Global Interrupt Enable
PORTB = 0xFF; // LED Port Initialization
DDRB = 0xFF;unsigned int i;
// LCD, LED Movement
while(1) {
// Not Charged Status
if(led_status1 == 0) {
while(1) {
gotoxy_LCD(0,0);
putchar_LCD('W');
putchar_LCD('e');
putchar_LCD('l');
putchar_LCD('c');
putchar_LCD('o');
putchar_LCD('m');
putchar_LCD('e');
putchar_LCD(' ');
putchar_LCD('B');
putchar_LCD('r');
putchar_LCD('o');
putchar_LCD(' ');
putchar_LCD('!');gotoxy_LCD(0,1);
putchar_LCD('O');
putchar_LCD('n');
putchar_LCD(' ');
putchar_LCD('S');
putchar_LCD('a');
putchar_LCD('l');
putchar_LCD('e');
putchar_LCD(' ');
putchar_LCD('.');
putchar_LCD(' ');
putchar_LCD('.');for(i=0; i<5; i++) {
PORTB = 0xFF;
PORTB >>= i*2;
PORTB <<= i;
delay_ms(300);
}for(i=3; i>0; i--) {
PORTB = 0xFF;
PORTB >>= i*2;
PORTB <<= i;
delay_ms(300);
}if(led_status1 == 1) {
status_linked = 1;
break;
}
}
}// INT4 Occured (1000\ Charged Status)
else if(status_linked == 1) {
while(1) {
PORTB = 0x00;
if(led_status2 == 1) {
status_linked = 2;
break;
}else if(lcd_status == 1) {
if(lcd_delete == 1) {
WRITE_COMMAND;
PORTC = 0x01;
ENABLE_LCD;
DISABLE_LCD;
delay_ms(10);
lcd_delete = 0;
}gotoxy_LCD(0,0);
putchar_LCD('H');
putchar_LCD('e');
putchar_LCD('y');
putchar_LCD(' ');
putchar_LCD('b');
putchar_LCD('r');
putchar_LCD('o');gotoxy_LCD(0,1);
putchar_LCD('1');
putchar_LCD('0');
putchar_LCD('0');
putchar_LCD('0');
putchar_LCD('W');
putchar_LCD('o');
putchar_LCD('n');
putchar_LCD(' ');
putchar_LCD('t');
putchar_LCD('h');
putchar_LCD('a');
putchar_LCD('n');
putchar_LCD('k');
putchar_LCD('s');
putchar_LCD(' ');
putchar_LCD('!');
}
}
}// INT5 Occured (600\ Paid Status)
else if(status_linked == 2) {
while(1) {
PORTB = 0xFF;
if(led_status3 == 1) {
status_linked = 3;
break;
}else if(lcd_status == 2) {
if(lcd_delete == 2) {
WRITE_COMMAND;
PORTC = 0x01;
ENABLE_LCD;
DISABLE_LCD;
delay_ms(10);
lcd_delete = 0;
}gotoxy_LCD(0,0);
putchar_LCD('4');
putchar_LCD('0');
putchar_LCD('0');
putchar_LCD('W');
putchar_LCD('o');
putchar_LCD('n');
putchar_LCD(' ');
putchar_LCD('l');
putchar_LCD('e');
putchar_LCD('f');
putchar_LCD('t');
putchar_LCD(' ');
putchar_LCD('.');
putchar_LCD(' ');
putchar_LCD('.');gotoxy_LCD(0,1);
putchar_LCD('T');
putchar_LCD('a');
putchar_LCD('k');
putchar_LCD('e');
putchar_LCD(' ');
putchar_LCD('t');
putchar_LCD('h');
putchar_LCD('e');
putchar_LCD(' ');
putchar_LCD('c');
putchar_LCD('h');
putchar_LCD('a');
putchar_LCD('r');
putchar_LCD('g');
putchar_LCD('e');
putchar_LCD('?');
}
}
}// INT6 Occured (400\ Returned Status)
else if(status_linked == 3) {
led_status1 = 0;
led_status2 = 0;
led_status3 = 0;
status_linked = 0;while(1) {
if(lcd_delete == 3) {
WRITE_COMMAND;
PORTC = 0x01;
ENABLE_LCD;
DISABLE_LCD;
delay_ms(10);//delay 10 m second ..repeat
lcd_delete = 0;
}gotoxy_LCD(0,0);
putchar_LCD('T');
putchar_LCD('h');
putchar_LCD('a');
putchar_LCD('n');
putchar_LCD('k');
putchar_LCD(' ');
putchar_LCD('y');
putchar_LCD('o');
putchar_LCD('u');
putchar_LCD(' ');
putchar_LCD('f');
putchar_LCD('o');
putchar_LCD('r');gotoxy_LCD(0,1);
putchar_LCD('y');
putchar_LCD('o');
putchar_LCD('u');
putchar_LCD('r');
putchar_LCD(' ');
putchar_LCD('s');
putchar_LCD('e');
putchar_LCD('r');
putchar_LCD('v');
putchar_LCD('i');
putchar_LCD('c');
putchar_LCD('e');
putchar_LCD(' ');
putchar_LCD('!');for(i=0; i<5; i++) {
PORTB = 0xFF;
PORTB >>= i*2;
PORTB <<= i;
delay_ms(300);
}for(i=3; i>0; i--) {
PORTB = 0xFF;
PORTB >>= i*2;
PORTB <<= i;
delay_ms(300);
}
}
}
}return 0;
}
이런 코드에서, 잔돈이 빠져 나가는 부분의 7세그먼트 코딩 내용 중 이 부분을 수정하려고하는데요
(이 글 맨 밑에 수정하려는 부분이 있습니다.)
지금 이 상태는 스위치를 누르면 7세그먼트에 0000이 뜨도록 한 것입니다.
이 것을 1000, 900, 800, 700 이렇게 순서대로 바뀌면서 잔돈이 빠져나가는 것을 표현하려고 했는데
for문을 사용해도, delay를 써봐도 제대로 작동하지 않고있습니다.
이상하게도 7segment에서만 딜레이가 제대로 작동하지 않네요.
다른 기기들로도 해봤지만 똑같이 중간에 숫자부분들은 생략되고 0들이 뜨지 않다가 마지막에 결과값만 출력되네요.
물론 그런 퍼포먼스가 없더라도 완성되었긴 하지만, 욕심이 나네요. 해결방법이 없을가요?
// INT6 Service routine
void disp_seg6_DEC(unsigned int data) {SegData[0] = SegDEC[0];
SegData[1] = SegDEC[0];
SegData[2] = SegDEC[0];
SegData[3] = SegDEC[0];
댓글 0
조회수 6,252등록된 댓글이 없습니다.