目录
1 博客内容
博客内容基于STM32F103 RET6芯片,实现PC3引脚LED灯闪烁,程序使用系统定时器SysTick,主要参考野火:指南者开发板教程文件。
2 主程序(Main.c):
//================================================
// 名称: Main.c
// 作者: Morven_X
// 版本: 1.1
// 编制: 2021/01/12 23:55
// 更新: 2021/01/20 22:27
// 功能: 基于STM32F103 RET6芯片,点亮PC3引脚LED灯,周期500ms闪烁
// 简介: 增加系统计时器对ms和us定义(Keil 5.28)
// Email: morven_xie@163.com
//================================================
# include "stm32f10x.h"
# include "LED1.h"
# include "Delay.h"
int main(void)
{
LED_Init();
Delay_Init();
while(1)
{
GPIOC->ODR|=1<<3; // 输出高,PC3设置高电平输出
// GPIO_SetBits(GPIOC,GPIO_Pin_3);
Delay_ms(500); //延时500毫秒
GPIOC->ODR&=0<<3; // 输出低,PC3设置低电平输出
// GPIO_ResetBits(GPIOC,GPIO_Pin_3);
Delay_ms(500); //延时500毫秒
}
}
3 延时头文件(Delay.h)
# ifndef _Delay_H
# define _Delay_H
# include "stm32f10x.h"
void Delay_Init(void);
void Delay_ms(u32 ms);
void Delay_us(u32 us);
#endif
4 延时程序(Delay.c)
# include "Delay.h"
u32 fac_us,fac_ms;
void Delay_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //HCLK为系统总线总线时钟 HCLK/8=9MHz
fac_us=SystemCoreClock/8000000; // fac_us=72M/8000000=9,即延时系统计数从8到0计数9次需要时间1微秒
fac_ms=(u16)fac_us*1000; // fac_ms=72M/8000000*1000=9000,原理同上,每个毫秒需要的systick时钟数
}
// 使用系统滴答systick实现,使用4个寄存器。
// SysTick->CTRL, --控制和状态寄存器(地址:0xE000_E010)
// SysTick->LOAD, --重装载寄存器(地址:0xE000_E014)
// SysTick->VAL, --当前值寄存器(地址:0xE000_E018)
// SysTick->CALIB, --校准值寄存器(地址:0xE000_E01C)
// 程序使用SysTick->CTRL位状态进行判断,定时器使能位:0位(Enable)==1和事件标志位:16位(CountFlag)==0
// 重装寄存器(SysTick->LOAD为24位计算器,延时2的24次方,除以延时系统频率9MHz,得出最大能力1.864s)
//延时us函数:
void Delay_us(u32 us)
{
u32 T_SysTick_CTR;
SysTick->LOAD=us*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
T_SysTick_CTR = SysTick->CTRL; //注意:[16]读后清零
}while((T_SysTick_CTR & 0x01) && !(T_SysTick_CTR & (1 << 16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时ms函数:
void Delay_ms(u32 ms)
{
u32 T_SysTick_CTR;
SysTick->LOAD=(u32)ms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数,可用SysTick->CTRL|=(u32)0x01替代
do
{
T_SysTick_CTR = SysTick->CTRL; //注意:[16]读后清零
}while((T_SysTick_CTR & 0x01) && !(T_SysTick_CTR & (1 << 16))); //等待时间到达,temp&0x01检查定时器使能位,!(temp&(1<<16)检查定时器事件标志位
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器,可用SysTick->CTRL = 0x00替代
SysTick->VAL =0X00; //清空计数器
}
5 程序运行结果
5.1 开发板未上电状态:
5.2 LED灯闪烁状态
5.3 Debug调试数据
调用库文件参考:
logical analyzer 与实际时间不一致,不再深入研究。