버스 방식으로 LED 16개를 구동하고 있습니다.
약 3ms 주기의 간격의 타이머 인터럽트 루틴을 사용해 main()
에서 수정하면 업데이트해서 뿌려 주는 방식을 사용하고 있습니다.
워낙, 속도와 no delay가 요구되는 프로젝트라서요.. 그런데, 큰...!! 문제가 생겼습니다.
저는 이제까지 값을 뿌려주는 것만 알았는데, 스위치 입력 받으면 특정의 LED가 깜빡깜빡 1초간격으로
거려야 한다는 것입니다. 그리고 다시 해당 스위치 누르면 꺼지거나 다시 점등되구요...
아래는 제가 지금 작성하여 사용하고 있는 인터럽트 서비스 루틴입니다. (6개짜리 FND도 같이 업데이트 시켜 주고 있습니다.)
#pragma vector = TIMER1_COMPA_vect //3ms interrupt isr 비교 인터럽트
__interrupt void timer1_compare_isr(void)
{
kyein = KEYM;
if(icounter == 8) {icounter = 0;}
DIGM = 1<<icounter; //fnd 및 led 선택 디바이스 콘트롤
if(icounter == 3){SEGM = Led_one;} //첫번째 8개의 led 업데이트
if(icounter == 7){SEGM = Led_two;} //두번째 8개의 led 업데이트
else {SEGM =fnd_data[icounter];} //6개의 fnd를 업데이트
++icounter;
//스위치 입력 디바운싱을 위한 스캔
if(++kyein_counter==6 && kyein == 0xff) {
kyein_flag=0;
kyein_counter=0;
}
else if(++kyein_counter==6 && kyein_flag==0) {
kyein_flag =1;
kyein_counter=0;
sw_input=kyein;
}
여기서 깜빡깜빡 거리는 것은 어떻게 해야 될지 모르겠습니다.
LED 관련함수에서는 일정 시간이 되면 일을 하게 하는 방법은 어떨까요?
일단 몇가지 변수를 추가하고요.
byte g_byteLEDOperMode; // 0 : LED off
// 1: LED ON
// 2: LED BLINK
UINT16 g_uiOperatingOutLEDTimer;
UINT16 g_uiOperatingOutLEDStatus;
메인에서
OperatingOutLED() 함수를 루프로 호출하고
main(){
while(1) {
OperatingOutLED();
}
}
void OperatingOutLED(){
// 일정시간이 되지 않았으면 리턴
if(g_uiOperatingOutLEDTimer >0) return;
// 일정시간이 되면 실행하겠다.
if(2==g_byteLEDOperMode){
// blink 모드이다.
g_uiOperatingOutLEDTimer=1000; // 다음에 1000이 경과된 후에 OperatingOutLED() 들어와라
if(0==g_uiOperatingOutLEDStatus){
// LED OFF
g_uiOperatingOutLEDStatus = 1;
}
}else if(1==g_uiOperatingOutLEDStatus){
// LED ON
g_uiOperatingOutLEDStatus = 0;
}
}
}
타이머인터럽트 에서
if(g_uiOperatingOutLEDTimer >0) g_uiOperatingOutLEDTimer--; // 감소시켜 주고.
이 방법이 처음에는 어려워 보일수 있으나 확장성이 좋고, 프로그램이해가 쉬운 방법입니다.
제가 사용한 소스를 보여드릴테니 참고하세요.^^