Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия Следующая версия Следующая версия справа и слева | ||
ob:o7:debug [2018/05/24 10:34] shiryaev.a.v |
ob:o7:debug [2018/05/26 07:00] иван_денисов [Сторожевой таймер] |
||
---|---|---|---|
Строка 209: | Строка 209: | ||
===== Сторожевой таймер ===== | ===== Сторожевой таймер ===== | ||
- | < | + | Чтобы определить, |
- | MODULE MobxSTM32F4WWDG; | + | |
- | IMPORT SYSTEM, | + | Чтобы его использовать, сначала необходимо выполнить процедуру **Init**, и затем периодически вызывать процедуру **Update**. Тогда, при «зависании» микроконтроллера сработает **аварийная остановка с кодом 20**, и можно определить место в программе, |
- | ARMv7M := MicroARMv7M, | + | |
- | Traps := MicroARMv7MTraps, | + | |
- | MCU := MicroSTM32F405; | + | |
- | CONST | + | Более универсальный сторожевой таймер для любых типов микроконтроллеров STM32F* не имеет возможности определения места остановки: |
- | 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. | ||
- | |||
- | При " | ||
---- | ---- |