#include <AT89X51.h>
code unsigned char SEGMENT[10] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90}; //0-9까지 값
unsigned char temp; // 인터럽트 상태 저장 전역 변수
// 외부 인터럽트 0 처리 루틴
int seg_num=0;
void EX0_INT(void) interrupt 0
{
if(seg_num < 3)
seg_num++;
}
// 외부 인터럽트 1 처리 루틴
void EX1_INT(void) interrupt 1
{
if(set_num > 1)
seg_num--;
}
// 일정 시간 지연 함수
void delay (unsigned int i)
{
while (i--);
}
// 메인
void main(void)
{
unsigned char i;
P1 = 0xff; // 포트 초기 설정
P2 = 0xef;
IT0 = 1; // 외부 인터럽트 0 엣지모드
EX0 = 1; // 외부 인터럽트 0 인에이블
IT1 = 1; // 외부 인터럽트 1 엣지모드
EX1 = 1; // 외부 인터럽트 1 인에이블
EA = 1; // 인터럽트 모두 인에이블
i = 0; // 포인터 초기 값
while(1)
{
switch(seg_num)
{
case 0:
P2 = 0x8F; // Q3세그먼트 작동 TR에 H값 인가
break;
case 1:
P2 = 0x4F; // Q2세그먼트 작동 TR에 H값 인가
break;
case 2:
P2 = 0x2F; // Q1세그먼트 작동 TR에 H값 인가
break;
case 3:
P2 = 0x1F; // Q0세그먼트 작동 TR에 H값 인가
break;
}
// 0~9까지 값을 루프하면서 세그먼트에 값 출력
for(i=0; i<10; i++)
{
P1 = SEGMENT[i]; //포트1에 세그먼트 출력
delay(10000); //딜레이함수
}
}
}
PORT1에서 4개의 세그먼트에 동일한 값을 출력하구요
P2에서 Q1,Q2등이 어떤 세그먼트를 동작시켜줄지(전압을 인가할지)결정합니다.
그러므로 세그먼트는 동작하고 있는 상태에서 Q1,Q2등을 제어해주기면 하면 됩니다.
스위치부분에 콘덴서를 달으셨는지요? 안달았다면 채터링 현상이 나올테니...
소프트웨어적으로 처리해주시거나 스위치 부분에 콘덴서를 달아 주는게 좋습니다.
흐름도 같은게 없이 말로만 듣다 보니 님이 원하시는 정확한 기능을 몰라 제 나름대로 정리했구요..
저도 노트북이라 컴파일러가 안깔려서 컴파일은 못해봤네요.
약간의 에러 있어도 이해해주시길..
컴파일해보니 중간에 seg 를 set라고 쓰신거 빼곤 틀린건 없는데요.
세그먼트 3개에서 동시에 작동하고 인터럽트는 먹지도 않네요;;
이찌된일지..;; 에궁 고생하셧는데;; 제가 더 미안하네여;;;
다시한번 설명해드리면 먼저 전원을 인가하면 Q3에 0-9 디스플레이되다가 인터럽트 스위치를 누르면 Q3는 꺼지고 Q2에 0-9까지 디스플레이됩니다. 또누르면 Q2꺼지고 Q1에디스플레이되고 이런식으로Q0까지 가고 이번에 다른 인터럽트 스위치를 누르면 거꾸로 9876543210 이렇게 디스플레이되면서 이번에 반대쪽으로 Q0에서 켜졋으면 Q1으로 이동하고 이렇게 되는 구조입니다;
프로그램은 님이 말씀한대로 구현된거 같군요..
인터럽트 부분은 님이 제어를 하셔야 할것 같습니다.
// 외부 인터럽트 1 처리 루틴
void EX1_INT(void) interrupt 1
{
if(set_num > 1)
seg_num--;
}
여기 인터럽트 함수로 빠지는지 안빠지는지 알아내야합니다.
아마 인터럽트가 제대로 동작 안한다면
IT0 = 1; // 외부 인터럽트 0 엣지모드
EX0 = 1; // 외부 인터럽트 0 인에이블
IT1 = 1; // 외부 인터럽트 1 엣지모드
EX1 = 1; // 외부 인터럽트 1 인에이블
EA = 1; // 인터럽트 모두 인에이블
여기 세팅 부분이 틀렸을 수있습니다.(8051 한지가 오래되서 레지스터는 기억이 잘 안나네요)
함수로 빠지게 되면 인터럽트가 작동하는거구요..
인터럽트만 동작하면 잘 작동할듯 보입니다..
인터럽트만 따로 예제를 만들어서 회로랑 테스트 해보세요..
인터럽트 들어오면 led가 켜진다던지...(회로는 직접 납땜하셨는지요??)
그것이 최우선 과제일듯합니다.
7시 정도에 다시 접속^^
처음 전원인가하면 세그먼트 3개에 동시에 0-9까지 디스플레이되는건 왜그런거죠?
아 회로를 잘못봤군요... NPN TR이 아니라 PNP군요
그 말은 h값일때 켜지는게 아니라 L값일때 켜지는군요
switch(seg_num)
{
case 0:
P2 = 0x8F; // Q3세그먼트 작동 TR에 H값 인가
break;
case 1:
P2 = 0x4F; // Q2세그먼트 작동 TR에 H값 인가
break;
case 2:
P2 = 0x2F; // Q1세그먼트 작동 TR에 H값 인가
break;
case 3:
P2 = 0x1F; // Q0세그먼트 작동 TR에 H값 인가
break;
}
여기서 0X8F 값은 반대로 0x7F;
0X4F는 0xBF 이런식으로 0과 1을 반대로 바꿔주면 한개만 켜지겠지요^^
네 pnp 맞아요- 근데 8F 를 반대로하면 7F 인가여?;;
맞네여 한개켜지기는한데 휴 역시 인터럽트가 문제네여;;
님께서는 그냥 스위치를 구현하셨다고 하셨고
저 인터럽트는 엣지모드로 세팅하셨다고하셨는데..
정확히 스위치를 어떻게 구현했는지 모르겟네요.
결국 H 액티브냐 L 액티브냐 이걸 일단 알고 그다음에 레지스터를 세팅하는게 맞는데요
님께서 하신 부분은 이 부분이 애매모호하군요..
스위치 구조는 저기 리셋 스위치와 같이 구현되어있어요 저항 하나 들어가고 커패시터 하나 들어가고.
커패시터 종류는 틀리지만 어쨋든 구조는 저렇게 되어잇구요..
IT0 = 1; // 외부 인터럽트 0 엣지모드
EX0 = 1; // 외부 인터럽트 0 인에이블
IT1 = 1; // 외부 인터럽트 1 엣지모드
EX1 = 1; // 외부 인터럽트 1 인에이블
EA = 1; // 인터럽트 모두 인에이블
이 부분은 같이 수업하는 다른 아이들도 이렇게 구현했구요,, 책에 있는대로 햇거든요;
제 생각은
code unsigned char SEGMENT[10] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90}; //0-9까지 값
unsigned char temp; // 인터럽트 상태 저장 전역 변수
// 외부 인터럽트 0 처리 루틴
int seg_num=0;
void EX0_INT(void) interrupt 0
{
if(seg_num < 3)
seg_num++;
}
// 외부 인터럽트 1 처리 루틴
void EX1_INT(void) interrupt 1
{
if(set_num > 1)
seg_num--;
}
// 일정 시간 지연 함수
void delay (unsigned int i)
{
while (i--);
}
이부분이 좀 이상한거 같아요;; seg_num 이란게 뭔가여?
다른아이들은 업카운드 다운카운트 이런걸 말하든데..
인터럽트가 안되시면 임의로 이 변수를 바꿔서 소스 테스트 해보시고
인터럽트 확인해보시길 바랍니다.