Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
ob:o7:debug [2018/05/24 10:41] shiryaev.a.v IWDG |
ob:o7:debug [2020/10/29 07:08] (текущий) |
||
---|---|---|---|
Строка 209: | Строка 209: | ||
===== Сторожевой таймер ===== | ===== Сторожевой таймер ===== | ||
- | < | + | Чтобы определить, |
- | MODULE MobxSTM32F4WWDG; | + | |
- | IMPORT SYSTEM, | + | Чтобы его использовать, сначала необходимо выполнить процедуру **Init**, и затем периодически вызывать процедуру **Update**. Тогда, при «зависании» микроконтроллера сработает **аварийная остановка с кодом 20**, и возможно определить место в программе, |
- | ARMv7M := MicroARMv7M, | + | |
- | Traps := MicroARMv7MTraps, | + | |
- | MCU := MicroSTM32F405; | + | |
- | CONST | + | Более универсальный сторожевой таймер не имеет |
- | SP = 13; | + | |
- | SR0 = 0; SR1 = 1; SR2 = 2; SR3 = 3; SR12 = 4; SLR = 5; SPC = 6; | + | |
- | + | ||
- | Int = MCU.WWDGInt; | + | |
- | int = Int MOD 32; | + | |
- | ISER = ARMv7M.NVICISER0 + (Int DIV 32) * 4; | + | |
- | ICER = ARMv7M.NVICICER0 + (Int DIV 32) * 4; | + | |
- | IPR = ARMv7M.NVICIPR0 + Int; | + | |
- | + | ||
- | PROCEDURE* InterruptsHandler; | + | |
- | CONST nLVars = 1; | + | |
- | VAR pc: INTEGER; | + | |
- | BEGIN | + | |
- | (* compiler-dependent *) | + | |
- | SYSTEM.GET(SYSTEM.REG(SP) + (SPC + nLVars + 1 + 8) * 4, pc); | + | |
- | Traps.trapHandler(0EX (* 14 *), pc, 0) | + | |
- | END InterruptsHandler; | + | |
- | + | ||
- | PROCEDURE Update*; | + | |
- | BEGIN | + | |
- | SYSTEM.PUT(MCU.WWDGCR, | + | |
- | END Update; | + | |
- | + | ||
- | PROCEDURE Init*; | + | |
- | CONST | + | |
- | (* RCCAPB1ENR bits: *) | + | |
- | WWDGEN = 11; | + | |
- | (* WWDGCR bits: *) | + | |
- | WDGA = 7; | + | |
- | (* WWDGCFR bits: *) | + | |
- | EWI = 9; | + | |
- | (* WWDGSR bits: *) | + | |
- | EWIF = 0; | + | |
- | VAR x: SET; | + | |
- | i: INTEGER; | + | |
- | BEGIN | + | |
- | SYSTEM.PUT(ICER, | + | |
- | + | ||
- | (* timeout = 4096 * 8 / PCLK1 * 64 = 52.4288 ms @ PCLK1 = 40 MHz *) | + | |
- | + | ||
- | SYSTEM.GET(MCU.RCCAPB1ENR, | + | |
- | SYSTEM.PUT(MCU.RCCAPB1ENR, | + | |
- | + | ||
- | SYSTEM.PUT(MCU.WWDGCFR, | + | |
- | + | ||
- | SYSTEM.PUT(Traps.vectorsOrg + (ARMv7M.ExternalInterrupt0 + Int) * 4, InterruptsHandler); | + | |
- | + | ||
- | (* decrease priority of all interrupts *) | + | |
- | i := 0; | + | |
- | WHILE i < 60 DO | + | |
- | SYSTEM.PUT(ARMv7M.NVICIPR0 + i, 80808080H); (* set priorities to 8 *) | + | |
- | INC(i) | + | |
- | END; | + | |
- | (* increase priority of WWDG interrupts *) | + | |
- | SYSTEM.PUT(IPR, | + | |
- | + | ||
- | SYSTEM.GET(MCU.WWDGSR, | + | |
- | SYSTEM.PUT(MCU.WWDGSR, | + | |
- | + | ||
- | SYSTEM.PUT(MCU.WWDGCR, | + | |
- | + | ||
- | SYSTEM.PUT(ISER, | + | |
- | END Init; | + | |
- | + | ||
- | END MobxSTM32F4WWDG. | + | |
- | </ | + | |
- | + | ||
- | Нужно периодически вызывать процедуру Update. | + | |
- | + | ||
- | При "зависании" | + | |
- | + | ||
- | + | ||
- | " | + | |
- | + | ||
- | < | + | |
- | MODULE MobxSTM32F4IWDG; | + | |
- | + | ||
- | IMPORT SYSTEM, MCU := MicroSTM32F405; | + | |
- | + | ||
- | PROCEDURE Update*; | + | |
- | BEGIN | + | |
- | SYSTEM.PUT(MCU.IWDGKR, | + | |
- | END Update; | + | |
- | + | ||
- | PROCEDURE Init*; | + | |
- | CONST | + | |
- | (* RCCCSR bits: *) | + | |
- | LSION = 0; LSIRDY = 1; | + | |
- | (* IWDGSR bits: *) | + | |
- | PVU = 0; RVU = 1; | + | |
- | VAR x: SET; | + | |
- | BEGIN | + | |
- | (* enable LSI *) | + | |
- | SYSTEM.GET(MCU.RCCCSR, x); | + | |
- | SYSTEM.PUT(MCU.RCCCSR, x + {LSION}); | + | |
- | REPEAT UNTIL SYSTEM.BIT(MCU.RCCCSR, | + | |
- | + | ||
- | (* set IWDG timeout to 32768 ms *) | + | |
- | + | ||
- | (* enable write access *) | + | |
- | SYSTEM.PUT(MCU.IWDGKR, | + | |
- | + | ||
- | (* setup PR *) | + | |
- | REPEAT UNTIL ~SYSTEM.BIT(MCU.IWDGSR, | + | |
- | SYSTEM.PUT(MCU.IWDGPR, | + | |
- | + | ||
- | (* setup RLR *) | + | |
- | REPEAT UNTIL ~SYSTEM.BIT(MCU.IWDGSR, | + | |
- | SYSTEM.PUT(MCU.IWDGRLR, | + | |
- | + | ||
- | (* reload IWDG *) | + | |
- | SYSTEM.PUT(MCU.IWDGKR, | + | |
- | + | ||
- | (* start IWDG *) | + | |
- | SYSTEM.PUT(MCU.IWDGKR, | + | |
- | END Init; | + | |
- | + | ||
- | END MobxSTM32F4IWDG. | + | |
- | </ | + | |