안녕하세요. 그 동안 계속 저의 무식한 질문에 성실히 답변해 주셔서 너무 감사합니다.
이전에 가르쳐 주신 방법의 적용을 하고 싶었지만, 조금 힘들어 isr에 죄다 집어넣었습니다.
그래서 결과는 일단 6개의 fnd도 잘 나오고, 16개의 LED도 잘 뜨고, 스위치 입력시 원하는 LED가
깜빡깜빡 잘 거립니다. 그런데, 앞으로 main()에서 rs485통신과 운전 모드등을 추가하려면 해당되는
operation에 많은 타이머가 필요한데, 계속 isr에 타이머들을 덧붙이면 시스템 부하가 커질 까봐,
현재의 isr에 있는 fnd업데이트,led 업데이트, 스위치 스캔 을 최대한 main()의 while문으로 빼고 싶은데요..
그런데, 무작정 while문으로 뺄 수도 없는 것이, while문에 시간딜레이가 있는 것이 들어갑니다. 온도값을 받아오는
ad7705 16BIT-ADC 칩을 읽어 올때마다 calibration 하고 읽어와야만 하기 때문에 약 100m초 이상 의 딜레이가
항상 생깁니다. 그래서, 현재의 isr 루틴을 복귀 타이머 3ms로 해서 while문으로 빼면 fnd도 led도 약 1,5초마다 그냥 껌뻑껌뻑 거
리기만 합니다.
어떻게 하면, 효율적으로 현재의 isr 루틴을 main()의 while문으로 효율적으로 분배할 수 있을까요?...
-현재 isr과 관련 함수들이 있는 c파일 내용 첨부합니다.
volatile unsigned int disp_timer,LED_timer;
volatile unsigned char fnd_data[8], sw_input;
volatile unsigned char Led_one, Led_two;
volatile unsigned char LEDS[13];
const unsigned char fnd_pattern[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xa7,0x86,0xaf,0xc7,0x92,0x87,0xa3,0xbf};
//{0~9,c,E,r,L,S,t,o,-}
static unsigned char icounter=0,blink_flag=0;//kyein=0,kyein_flag=0,kyein_counter=0;
#pragma vector = TIMER1_COMPA_vect //2ms interrupt isr
__interrupt void timer1_compare_isr(void)
{ sw_input = KEYM;
//kyein = KEYM;
if(disp_timer>0) disp_timer--;
if(icounter == 8) {icounter = 0;}
DIGM = 1<<icounter;
////////////////////////////
if(icounter == 3){
if(blink_flag >0 && blink_flag < 9){
if(LED_timer<250){
Led_one = Led_one | (1<<(blink_flag-1));//OFF
SEGM = Led_one;}
else {
Led_one = Led_one & ~(1<<(blink_flag-1));//ON
SEGM = Led_one;}
}
else {
SEGM = Led_one; }
}
//////////////////////////////
else if(icounter == 7){
if(blink_flag >8){
if(LED_timer<250){
Led_two = Led_two | (1<<(blink_flag-9));//off
SEGM = Led_two;}
else {
Led_two = Led_two & ~(1<<(blink_flag-9));//on
SEGM = Led_two;}
}
else {
SEGM = Led_two; }
}
////////////////////////////////
else{SEGM =fnd_data[icounter];}
++icounter;
LED_timer++;
if(LED_timer >= 500){
LED_timer =0; }
}
oid FndDisp(unsigned char numb,unsigned char datafnd, unsigned char dotp){
if(dotp == 1) {fnd_data[numb]=(0x7f & fnd_pattern[datafnd]);}
else {fnd_data[numb] = fnd_pattern[datafnd];}
}
void LedDisp(unsigned char Lnum, unsigned char Ldata){
switch(Ldata) {
case 0: //off
LEDS[Lnum] =0;
if(Lnum <8) {
Led_one = (Led_one | (1<<Lnum)); }//clear
else {
Led_two = (Led_two | (1<<(Lnum-8))); }
blink_flag =0;
break;
case 1://on
LEDS[Lnum] =1;
if(Lnum <8) {
Led_one = (Led_one & ~(1<<Lnum)); }//set
else {
Led_two = (Led_two & ~(1<<(Lnum-8))); }
blink_flag =0;
break;
case 2://blink
//LEDS[Lnum] = LEDS[Lnum];
blink_flag = 1+Lnum;
break;
}
}
unsigned char SwInput(void){
unsigned char inmode;
if(sw_input == 0x77) return 0;
switch(sw_input){
case 0xfe: inmode=1; break;//설정 key
case 0xfd: inmode=2; break;//운전,up key
case 0xfb: inmode=3; break;//정지,down key
case 0xf7: inmode=4; break;//선택 key
case 0xfc: inmode=5; break;//설정 + 운전 key
}
sw_input=0x77; //키가 눌리지 않았음을 판단하기 위한 매직값.
return inmode;
}
-- 그리고 main에서의 while은 대략 이렇습니다.
while(1) {
adc_sint_B_1[0] = read_adc_value_B(1);//read Ch1 of A, 여기서 아주 짧은 딜레이가 생깁니다.
switch (SwInput()) {
case 1: LedDisp(0,2);
if(SwInput()==1) LedDisp(0,1);
break;
case 2: LedDisp(1,2);
if(SwInput()==2) LedDisp(1,1);
break;
case 3: LedDisp(2,2);
if(SwInput()==3) LedDisp(2,1);
break;
case 4: LedDisp(3,2);
if(SwInput()==4) LedDisp(3,1);
break;
case 5: LedDisp(4,2);
if(SwInput()==5) LedDisp(4,1);
break; }
}
참고해서 수정해 보세요.^^.
지금이라도 전체 구조를 변경하셔야 할듯합니다ㅡㅡ;