这里主要是使用Systick 时钟来实现精准延迟,它本质也是一个定时器,使用时只需复制粘贴使用,这里是使用72M的STM32F103ZET6,不同型号需要自行修改对应参数。
#include "stm32f10x.h"
static uint8_t D_us=0; //微妙系数
static uint16_t D_ms=0; //毫秒系数
void Delay_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
D_us = SystemCoreClock/8000000;
D_ms = (uint16_t)D_us * 1000;
}
void Delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->LOAD = nus*D_us; //延时重装载值
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL|= 0x01 ; //启动SysTick定时器
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待延时结束
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->VAL = 0X00; //清空计数器
}
void Delay_ms(uint32_t nms)
{
uint32_t temp;
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->LOAD = nms*D_ms; //延时重装载值
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL|= 0x01 ; //启动SysTick定时器
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待延时结束
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->VAL = 0X00; //清空计数器
}
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//开启时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIO
GPIO_SetBits(GPIOC,GPIO_Pin_0); //将LED端口拉高,熄灭所有LED
}
int main( void )
{
Delay_Init();
LED_Init();
while(1)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
Delay_ms(500);
GPIO_SetBits(GPIOC,GPIO_Pin_0);
Delay_ms(500);
}
}