====== 타이머 만들기 ====== 앞서 만든 기초 소스에 타이머를 추가해 보겠습니다. 타이머는 자동화 현장에서 매우 자주 사용됩니다. ===== On Timer ====== 일정 시간 신호가 들어왔을때, 비로소 출력을 하는 가장 기본적인 타이머입니다. 2개의 타이머 관련 배열이 필요합니다. #define timerMaxLimit 20 uint8_t Tstat[timerMaxLimit]; // Timer status uint32_t Tvalue[timerMaxLimit]; // Timer Current Value 이 예에서는 총 20개의 타이머만 사용하였습니다. 위 20이라는 숫자를 바꾸면 타이머 갯수를 조정할 수 있습니다. * Tstat배열 : 타이머의 상태를 저장합니다. 1이면 On, 0이면 Off라는 뜻입니다. * Tvalue배열 : 타이머의 증가 감소 값을 저장하는 배열입니다. OnTimer가 어떻게 동작하는지 보겠습니다. {{ :modularfaduino:timerprogram:ontimer1.png?nolink |}} 입력(Input)이 들어오면 지정한 시간(Time)이 경과된 뒤 비로소 출력(Tstat)가 켜집니다. #include "CFMEGA.h" CFNET cfnet; uint8_t X[128]; // Input Coil uint8_t Y[128]; // Output Coil void distribute_value(uint16_t val, uint8_t where) { for (int i = 0; i < 16; i++) { X[where++] = val & 0x01; val >>= 1; } } void input_proc() { for (int i = 0; i < 8; i++) { distribute_value(cfnet.digitalRead(i), i * 16); } } uint16_t collect_value(uint8_t where) { uint16_t tempV = 0; for (int i = 0; i < 16; i++) { tempV |= Y[where++] << i; } return tempV; } void output_proc() { for (int i = 0; i < 8; i++) { cfnet.digitalWrite(i, collect_value(i * 16)); } } ISR(TIMER5_OVF_vect) { TCNT5 = 198; // for 20mS sei(); // Start Gloval Interrupt timertn_proc(); input_proc(); logic_proc(); output_proc(); tick_flag = 0; } // Timer uint16_t system_timer=0, tick_flag=0; #define timerMaxLimit 20 uint8_t Tstat[timerMaxLimit]; // Timer status uint32_t Tvalue[timerMaxLimit]; // Timer Current Value void timertn_proc() { system_timer++; if (system_timer == 5) { tick_flag = 1; // Turn On every 100mS system_timer=0; } } void onTimer(uint8_t inputValue, uint8_t timerIndex, uint16_t timerInitValue) { if (tick_flag) { if (inputValue) { if (Tvalue[timerIndex] < timerInitValue) { Tvalue[timerIndex]++; if (Tvalue[timerIndex] == timerInitValue) { Tstat[timerIndex] = 1; } } } else { Tvalue[timerIndex] = 0; Tstat[timerIndex] = 0; } } } // // User Source // void setup() { TCCR5B = 5; // Clock source from system clock/1024 TIMSK5 |= 1; //TOV interrupt set. sei(); // Start Gloval Interrupt // Clear Timer array for (int _i=0; _i < timerMaxLimit; _i++) { Tstat[_i] = 0; Tvalue[_i] = 0; } } void loop() { } // Run every 20mS void logic_proc() { Y[0] = X[0]; // Main Logic Program onTimer(X[0],0,8); // 800mS On Timer Y[1] = Tstat[0]; // Watch Tvalue } ====== onTimer ====== 이 소스에서 맨밑 logic_proc를 보면 onTimer를 사용한 부분이 보입니다. ''void onTimer(입력소스, 타이머 번호, 경과시간) '' | 입력 소스 : 여기에서는 X[0] 입력을 사용하였습니다. | | 타이머 번호 : 여기에서는 0번 타이머를 사용하였습니다. | | 경과시간 : 타이머 값입니다. 여기에서는 8 즉, 0.8S를 뜻합니다. 이 타이머는 0.1초 단위입니다. | 따라서, 위 소스가 실행되면, X[0]이 입력되었을때, 0.8초후에 타이머0이 출력됩니다. 그 결과를 Y[1]에서 보실 수 있습니다. ==== 주의 ==== 시간 지연이 필요할때 초보자분들은 delay함수를 사용하는데, 이 경우 delay를 하는 동안 다른 신호를 처리할 수 없기 때문에, 정상적인 흐름이 불가능합니다. [[modularfaduino:index|Modular FADUINO]]