DWT, full name is the debug Watchpoint and Trace (DWT) unit, for system debugging and tracking, detailed introduction can refer to ARM official documents: Armv7-m Architecture Reference Manual. This article will enable it to implement a system's delay function.
1. Register Simple Introduction
To implement the delay function, a total of three registers are involved: DEMCR, Dwt_ctrl, dwt_cyccnt, respectively, to open the DWT function, turn on the cyccnt and get the system clock count value.
Demcr
Its official manual is described below, where we only need to focus on its 24th pin Trcena.
The Trcena position bit of the register allows the DWT function to be
Dwt_ctrl Register
It contains many functions, and here we only turn on its loop count function.
CYCCNT Register
The register address is described below:
When the Cyccntena position bit of the DWT, the value of the register is kept in sync with the system cycle count value, we can use its value to implement a delay function.
2. Delay Program Writing
Directly on the code:
Delay function Source file:
#include "DWTDelay.h"//0XE000EDFC DEMCR RW Debug Exception and Monitor Control Register. #define DEMCR (* (Unsig Ned int *) 0XE000EDFC) #define Trcena (0x01 <<)//DEMCR DWT Enable bit//0xe0001000 Dwt_ctrl RW the Debug Watch Point and Trace (DWT) unit#define Dwt_ctrl (* (unsigned int *) 0xe0001000) #define Cyccntena (0x01 << 0 )//DWT syccnt Enable bit//0xe0001004 dwt_cyccnt RW Cycle Count Register, #define DWT_CYCCNT (* (unsigned int *) 0xe0001004 )//Display or set the cycle count value of the processor//#define DWT_DELAY_MS (MSEC) Dwt_delay_us (msec*1000) static int sysclk = 0;; void Dwt_init (int sys_clk) {DEMCR |= Trcena; Dwt_ctrl |= Cyccntena; SYSCLK = SYS_CLK; Saves the current system's clock cycle, eg. 72,000,000 (72MHz). }//microsecond delay void dwt_delay_us (int uSec) {int Ticks_start, ticks_end, Ticks_delay; Ticks_start = dwt_cyccnt; if (! SYSCLK) Dwt_init (MY_MCU_SYSCLK); Ticks_delay = (USEC * (SYSCLK/(1000*1000))); Convert microseconds to tick count Ticks_end = Ticks_start + ticks_delay; if (TiCks_end > Ticks_start) {while (dwt_cyccnt < ticks_end); } else//Count overflow, flip {while (dwt_cyccnt >= ticks_end);//The value after flipping is no smaller than ticks_end while (dwt_cyccnt < ticks_end); }}
Delay Function Header file:
#ifndef _dwtdelay_h_#define _dwtdelay_h_//Modified by the MCU # define MY_MCU_SYSCLK (72000000) void dwt_init (int sys_clk);// microsecond delay void Dwt_delay_us (int uSec); #define Dwt_delay_ms (MSEC) Dwt_delay_us (msec*1000) #endif//_dwtdelay_h_
At this point, simple, easy-to-use, accurate and non-occupied CPU other peripheral resources of the delay function is realized.
Using DWT to implement system delay