/* 外部调用:
delay_init(72); //系统主频, 单位为MHZ, 仅对 SYSTICK_DELAY 有效
delay_ms(1000);
*/
#include 'stm32f10x.h'
//#define SOFT_DELAY //纯软件延时
//#define SYSTICK_DELAY //系统定时器延时
#define TIMER_DELAY //定时器延时
#ifdef TIMER_DELAY
#define TIMER_DELAY TIM4
#define TIMER_DELAY_PERIOD 1000
#define TIMER_DELAY_PRESCALER 72
#define TIMER_DELAY_CLOCK RCC_APB1Periph_TIM4
#define TIMER_DELAY_IRQ_HANDLER TIM4_IRQHandler
#define TIMER_DELAY_PREEMPTION_PRIORITY 2
#define TIMER_DELAY_SUB_PRIORITY 2
#define TIMER_DELAY_IRQ_CHANNEL TIM4_IRQn
static __IO u16 counter_delay_ms;
#endif
//-----------------------------------------------------------------
#ifdef SOFT_DELAY
void delay_init(u8 SYSCLK)
{}
#if 1
void delay_us(u32 Number)
{
u32 i=0;
while(Number--){
i=12; while(i--);
}
}
void delay_ms(u16 Number)
{
u32 i;
while(Number--){
i=12000; while(i--);
}
}
#else
unsigned char MULTIPLE8M = 9;
void delay_us(u32 usNum)
{
unsigned short kk, i;
for(i=usNum; i>0; i--)
{
kk = 2*MULTIPLE8M - 1; //0x080003AA 4C06 LDR r4,[pc,#24] ; @0x080003C4 2clk
do
{ //0x080003AC BF00 NOP 1clk
kk--; //0x080003AE 1E64 SUBS r4,r4,#1 1clk
} while(kk); //0x080003B0 2C00 CMP r4,#0x00 1clk
//0x080003B2 D1FC BNE 0x080003AE jump:2clk, no jump:1clk
}
}
void delay_ms(u16 usNum)
{
unsigned short kk, i;
for(i=usNum; i>0; i--)
{
if (i % 100 == 0) {
//FEEDDOG;
}
kk = 2000*MULTIPLE8M - 1; //0x080003AA 4C06 LDR r4,[pc,#24] ; @0x080003C4 2clk
do
{ //0x080003AC BF00 NOP 1clk
kk--; //0x080003AE 1E64 SUBS r4,r4,#1 1clk
} while(kk); //0x080003B0 2C00 CMP r4,#0x00 1clk
//0x080003B2 D1FC BNE 0x080003AE jump:2clk, no jump:1clk
}
}
#endif
#endif
//---------------------------------------------------------------------------
#ifdef SYSTICK_DELAY
//参考原子的代码. 修正了中断中调用出现死循环的错误, 防止延时不准确,采用do
static u8 fac_us = 0; //us延时倍乘数
static u16 fac_ms = 0; //ms延时倍乘数
//初始化延迟函数, SYSTICK的时钟固定为HCLK时钟的1/8, SYSCLK:系统时钟, 单位为MHZ
void delay_init(u8 SYSCLK)
{
SysTick->CTRL &= 0xfffffffb; //bit2清空,选择外部时钟 HCLK/8
fac_us = SYSCLK/8;
fac_ms = (u16)fac_us*1000;
}
//延时nms, 注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms, 对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD = (u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL = 0x01 ; //开始倒数
do {
temp = SysTick->CTRL;
}while(temp&0x01 && !(temp&(1<<16)));//等待时间到达
SysTick->CTRL = 0x00; //关闭计数器
SysTick->VAL = 0X00; //清空计数器
}
//延时nus, nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD = nus*fac_us; //时间加载
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL = 0x01 ; //开始倒数
do{
temp = SysTick->CTRL;
}while(temp&0x01 && !(temp&(1<<16)));//等待时间到达
SysTick->CTRL = 0x00; //关闭计数器
SysTick->VAL = 0X00; //清空计数器
}
#endif
//-------------------------------------------------------------------
#ifdef TIMER_DELAY
void decrement_delay(void)
{
if(counter_delay_ms != 0)
{
/* Decrement the counter */
counter_delay_ms--;
}
}
void delay_init(u8 SYSCLK)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(TIMER_DELAY_CLOCK, ENABLE);
TIM_TimeBaseStructure.TIM_Period = TIMER_DELAY_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler = TIMER_DELAY_PRESCALER;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMER_DELAY, &TIM_TimeBaseStructure);
TIM_UpdateRequestConfig(TIMER_DELAY, TIM_UpdateSource_Global);
TIM_ClearITPendingBit(TIMER_DELAY, TIM_IT_Update);
/* Enable TIMER Update interrupt */
TIM_ITConfig(TIMER_DELAY, TIM_IT_Update, ENABLE);
// Disable timers
TIM_Cmd(TIMER_DELAY, DISABLE);
/* Enable and set TIMER IRQ used for delays */
NVIC_InitStructure.NVIC_IRQChannel = TIMER_DELAY_IRQ_CHANNEL;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMER_DELAY_PREEMPTION_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMER_DELAY_SUB_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void delay_ms(uint16_t delay)
{
counter_delay_ms = delay;
TIM_SetCounter(TIMER_DELAY, 0);
/* TIM4 enable counter */
TIM_Cmd(TIMER_DELAY, ENABLE);
/* Wait for 'delay' milliseconds */
while(counter_delay_ms != 0);
/* TIM4 disable counter */
TIM_Cmd(TIMER_DELAY, DISABLE);
}
void TIMER_DELAY_IRQ_HANDLER(void)
{
/* Clear TIMER update interrupt flag */
TIM_ClearITPendingBit(TIMER_DELAY, TIM_IT_Update);
decrement_delay();
}
#endif
当然运行RTOS时, 一般系统定时器延时就不能用了.
上一篇:stm32中的NVIC_Configuration(void)函数
下一篇:STM32 通用底层函数集锦, 自用
推荐阅读最新更新时间:2024-11-16 22:56
设计资源 培训 开发板 精华推荐
- 555电路
- AD5644R 四路 14 位 nanoDAC 的典型应用
- ZXLD1320 用于 LED 驱动的降压模式 DC-DC 转换器的典型应用,具有 1.5A 输出和电流控制
- 基于L6360的IO-Link通信主收发器演示板
- LT3761HMSE 升压型 LED 驱动器的典型应用电路,具有内部生成 PWM 的输出短路保护
- CN0224
- 智能小车|专为学校比赛设计的多功能小车
- 使用 NXP Semiconductors 的 ISP1161 的参考设计
- NCP1615GEVB:具有电流控制频率折返评估板的高压 PFC 控制器
- DC913A,使用 LTC3773EUHF 高性能、三相、三路输出同步降压型开关稳压控制器的演示板