9 .cal-form { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; padding: 1rem; border: 1px solid #e4e4e4; border-radius: 6px; } .cal-form select, input{ padding: .5rem; background: #ededed; border: none; } function generateCodeSnippet() { var timeInput = document.getElementById("time-input").value; var timeUnit = document.getElementById("time-unit").value; var timerModule = document.getElementById("timer-module").value; var prescalerOptions, maxTicksCount; if (timerModule === "Timer0" || timerModule === "Timer1") { prescalerOptions = [1, 8, 64, 256, 1024]; maxTicksCount = (timerModule === "Timer0") ? 256 : 65536; } else if (timerModule === "Timer2") { prescalerOptions = [1, 8, 32, 64, 128, 256, 1024]; maxTicksCount = 256; } var prescaler = 0; var ticksCount = 0; for (var i = 0; i < prescalerOptions.length; i++) { var currentPrescaler = prescalerOptions[i]; var currentTicksCount = Math.round((timeInput * 16000000) / (currentPrescaler * getTimeUnitMultiplier(timeUnit))); if (currentTicksCount <= maxTicksCount) { prescaler = currentPrescaler; ticksCount = currentTicksCount; break; } } if(ticksCount === 0 || prescaler === 0) { document.getElementById("mycode").rows = 2; document.getElementById("mycode").value = "Timer Will Overflow, Please Check Your Settings, Select Another Timer, or check the tutorial below for more information about timer overflow for long time-interval generation"; } else { var codeSnippet = generateSnippet(timerModule, ticksCount, prescaler); document.getElementById("mycode").rows = 26; document.getElementById("mycode").value = codeSnippet; var element = document.getElementById("mycode"); element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"}); } } function getTimeUnitMultiplier(timeUnit) { switch (timeUnit) { case "ns": return 1000000000; case "us": return 1000000; case "ms": return 1000; case "s": return 1; default: return 1; } } function generateSnippet(timerModule, ticksCount, prescaler) { var interruptType = document.getElementById("interrupt").value; if(interruptType === "COMPA") { var codeSnippet = "/*n"; codeSnippet += " * LAB Name: Arduino Timer Compare Match Interruptn"; codeSnippet += " * Author: Trương Công Lýn"; codeSnippet += " * For More Info Visit: www.truongcongly.comn"; codeSnippet += "*/nn"; codeSnippet += "ISR(" + getInterruptVector(timerModule) + ")n"; codeSnippet += "{n"; codeSnippet += " OCR" + getOCRRegister(timerModule) + " += " + ticksCount + "; // Advance The COMPA Registern"; codeSnippet += " // Handle The Timer Interruptn"; codeSnippet += " //...n"; codeSnippet += "}nn"; codeSnippet += "void setup()n"; codeSnippet += "{n"; codeSnippet += " TCCR" + getControlRegisterA(timerModule) + " = 0; // Init Timer" + getControlRegisterA(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " = 0; // Init Timer" + getControlRegisterB(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " |= " + getPrescalerBits(timerModule, prescaler) + "; // Prescaler = " + prescaler + "n"; codeSnippet += " OCR" + getOCRRegister(timerModule) + " = " + ticksCount + "; // Timer Compare" + getOCRRegister(timerModule) + " Registern"; codeSnippet += " " + getTimerInterruptMask(timerModule) + " |= " + getTimerInterruptBits(timerModule) + "; // Enable Timer COMPA Interruptn"; codeSnippet += "}nn"; codeSnippet += "void loop()n"; codeSnippet += "{n"; codeSnippet += " // Do Nothingn"; codeSnippet += "}"; } else if(interruptType === "COMPB") { var codeSnippet = "/*n"; codeSnippet += " * LAB Name: Arduino Timer Compare Match Interruptn"; codeSnippet += " * Author: Trương Công Lýn"; codeSnippet += " * For More Info Visit: www.truongcongly.comn"; codeSnippet += "*/nn"; codeSnippet += "ISR(" + getInterruptVector(timerModule) + ")n"; codeSnippet += "{n"; codeSnippet += " OCR" + getOCRRegister(timerModule) + " += " + ticksCount + "; // Advance The COMPB Registern"; codeSnippet += " // Handle The Timer Interruptn"; codeSnippet += " //...n"; codeSnippet += "}nn"; codeSnippet += "void setup()n"; codeSnippet += "{n"; codeSnippet += " TCCR" + getControlRegisterA(timerModule) + " = 0; // Init Timer" + getControlRegisterA(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " = 0; // Init Timer" + getControlRegisterB(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " |= " + getPrescalerBits(timerModule, prescaler) + "; // Prescaler = " + prescaler + "n"; codeSnippet += " OCR" + getOCRRegister(timerModule) + " = " + ticksCount + "; // Timer Compare" + getOCRRegister(timerModule) + " Registern"; codeSnippet += " " + getTimerInterruptMask(timerModule) + " |= " + getTimerInterruptBits(timerModule) + "; // Enable Timer COMPB Interruptn"; codeSnippet += "}nn"; codeSnippet += "void loop()n"; codeSnippet += "{n"; codeSnippet += " // Do Nothingn"; codeSnippet += "}"; } else if(interruptType === "OVF") { if (timerModule === "Timer0" || timerModule === "Timer2") { var preloadValue = 255 - ticksCount; } else { var preloadValue = 65535 - ticksCount; } var codeSnippet = "/*n"; codeSnippet += " * LAB Name: Arduino Timer Compare Match Interruptn"; codeSnippet += " * Author: Trương Công Lýn"; codeSnippet += " * For More Info Visit: www.truongcongly.comn"; codeSnippet += "*/nn"; codeSnippet += "ISR(" + getInterruptVector(timerModule) + ")n"; codeSnippet += "{n"; codeSnippet += " TCNT" + getCounterRegister(timerModule) + " = " + preloadValue + "; // Timer Preloadingn"; codeSnippet += " // Handle The Timer Overflow Interruptn"; codeSnippet += " //...n"; codeSnippet += "}nn"; codeSnippet += "void setup()n"; codeSnippet += "{n"; codeSnippet += " TCCR" + getControlRegisterA(timerModule) + " = 0; // Init Timer" + getControlRegisterA(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " = 0; // Init Timer" + getControlRegisterB(timerModule) + "n"; codeSnippet += " TCCR" + getControlRegisterB(timerModule) + " |= " + getPrescalerBits(timerModule, prescaler) + "; // Prescaler = " + prescaler + "n"; codeSnippet += " TCNT" + getCounterRegister(timerModule) + " = " + preloadValue + "; // Timer Preloadingn"; codeSnippet += " " + getTimerInterruptMask(timerModule) + " |= " + getTimerInterruptBits(timerModule) + "; // Enable Timer Overflow Interruptn"; codeSnippet += "}nn"; codeSnippet += "void loop()n"; codeSnippet += "{n"; codeSnippet += " // Do Nothingn"; codeSnippet += "}"; } return codeSnippet; } function getPrescalerBits(timerModule, prescaler) { if (timerModule === "Timer0" || timerModule === "Timer1") { switch (prescaler) { case 1: return "B00000001"; case 8: return "B00000010"; case 64: return "B00000011"; case 256: return "B00000100"; case 1024: return "B00000101"; default: return "B00000000"; } } else if (timerModule === "Timer2") { switch (prescaler) { case 1: return "B00000001"; case 8: return "B00000010"; case 32: return "B00000011"; case 64: return "B00000100"; case 128: return "B00000101"; case 256: return "B00000110"; case 1024: return "B00000111"; default: return "B00000000"; } } else { return "B00000000"; } } function getOCRRegister(timerModule) { var interruptType = document.getElementById("interrupt").value; if(interruptType === "COMPA") { switch (timerModule) { case "Timer0": return "0A"; case "Timer1": return "1A"; case "Timer2": return "2A"; default: return ""; } } else if(interruptType === "COMPB") { switch (timerModule) { case "Timer0": return "0B"; case "Timer1": return "1B"; case "Timer2": return "2B"; default: return ""; } } } function getControlRegisterA(timerModule) { switch (timerModule) { case "Timer0": return "0A"; case "Timer1": return "1A"; case "Timer2": return "2A"; default: return ""; } } function getCounterRegister(timerModule) { switch (timerModule) { case "Timer0": return "0"; case "Timer1": return "1"; case "Timer2": return "2"; default: return ""; } } function getControlRegisterB(timerModule) { switch (timerModule) { case "Timer0": return "0B"; case "Timer1": return "1B"; case "Timer2": return "2B"; default: return ""; } } function getInterruptVector(timerModule) { var interruptType = document.getElementById("interrupt").value; if(interruptType === "COMPA") { switch (timerModule) { case "Timer0": return "TIMER0_COMPA_vect"; case "Timer1": return "TIMER1_COMPA_vect"; case "Timer2": return "TIMER2_COMPA_vect"; default: return ""; } } else if(interruptType === "COMPB") { switch (timerModule) { case "Timer0": return "TIMER0_COMPB_vect"; case "Timer1": return "TIMER1_COMPB_vect"; case "Timer2": return "TIMER2_COMPB_vect"; default: return ""; } } else if(interruptType === "OVF") { switch (timerModule) { case "Timer0": return "TIMER0_OVF_vect"; case "Timer1": return "TIMER1_OVF_vect"; case "Timer2": return "TIMER2_OVF_vect"; default: return ""; } } } function getTimerInterruptMask(timerModule) { switch (timerModule) { case "Timer0": return "TIMSK0"; case "Timer1": return "TIMSK1"; case "Timer2": return "TIMSK2"; default: return ""; } } function getTimerInterruptBits(timerModule) { var interruptType = document.getElementById("interrupt").value; if(interruptType === "COMPA") { switch (timerModule) { case "Timer0": return "B00000010"; case "Timer1": return "B00000010"; case "Timer2": return "B00000010"; default: return ""; } } else if(interruptType === "COMPB") { switch (timerModule) { case "Timer0": return "B00000100"; case "Timer1": return "B00000100"; case "Timer2": return "B00000100"; default: return ""; } } else if(interruptType === "OVF") { switch (timerModule) { case "Timer0": return "B00000001"; case "Timer1": return "B00000001"; case "Timer2": return "B00000001"; default: return ""; } } }
Công cụ Arduino Timer Calculator & Code Generato này sẽ giúp bạn tự động hóa quá trình tính toán để chọn mô-đun hẹn giờ phù hợp để tạo ra các ngắt hẹn giờ với Arduino (Atmega328p).
ns μs ms s
Timer0 Timer1 Timer2
COMPA COMPB OVF
Arduino Code:

