找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2425|回复: 6
收起左侧

STM32 SysTick定时器使用(非常适合初学者)

[复制链接]
ID:632424 发表于 2021-8-2 12:39 | 显示全部楼层 |阅读模式
作为一名stm32的初学者,无人指导自学还是很困难的,网络上虽热资料很多,但是对于基础薄弱的人来说还是很难理解各个外设的使用,初次发帖,以最简单明了的方式解说使用SysTick定时器,没有专业术语,简单粗暴。(专业的大佬请视而不见,哈哈哈)下面的程序是使用Systick定时2秒实现led间隔2秒亮灭(stm32f103c8t6芯片)
#include"stm32f10x.h"
uint32_t count;               //定义了一个全局变量,stm32f10x_it.h也声明这个全局变量
void led_config()             //引脚PB8的配置
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void delay(uint16_t ntime)  //延时函数,ntime就是次数
{
count=ntime;                   //ntime这个值由我们自己设定,就是进入SysTick中断的次数,ntime赋值给全局变量count
while(count!=0);              //进入Systick中断一次,count就减1,这边判断count是否减到零,跳出while
}
int main()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);   //开启GPIOB时钟,先开启时钟,GPIO引脚参数才能有效配置
led_config();                                                                  //引脚PB8配置写入
SysTick_Config(72000);                                                  //SysTick的时钟源是72MHz, 72000就是定时1ms进入中断函数
while(1)
{
  GPIO_SetBits(GPIOB,GPIO_Pin_8);
  delay(2000);                                                        //延时2s,进入中断2000次,每次减1,最后得到0,跳出while,执行下一语句ResetBits
  GPIO_ResetBits(GPIOB,GPIO_Pin_8);
  delay(2000);
}
}

*******************以下是需要配置的一些东西********************************

在stm32f10x_it.c文件中找到void SysTick_Handler(void)中断函数, 函数里面写入count--  如下:
void SysTick_Handler(void)
{
    count--;                                                   
}


在stm32f10x_it.h文件中一定要定义全局变量count,如下:
  extern uint32_t count;            

我看了很多帖子,都是把SysTick_Handler函数写的很累赘,我喜欢简单 count--,一句搞定,大家都很忙
新人第一次发帖,不好的地方多指导,感谢





评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:569561 发表于 2021-8-2 15:20 | 显示全部楼层
void delay(uint16_t ntime)  //延时函数,ntime就是次数
{
count=ntime;                   //ntime这个值由我们自己设定,就是进入SysTick中断的次数,ntime赋值给全局变量count
while(count!=0);              //进入Systick中断一次,count就减1,这边判断count是否减到零,跳出while
}
这里怎么减少的呢?
回复

使用道具 举报

ID:592807 发表于 2021-8-2 15:50 | 显示全部楼层
1205551786 发表于 2021-8-2 15:20
void delay(uint16_t ntime)  //延时函数,ntime就是次数
{
count=ntime;                   //ntime这个 ...

他这里没有减少,在滴答定时器中断里面减少,这里就是将他while锁住,等待定时器将count减少至0.
另外一般会在这里加一个标志位delay_flag
uint8_t delay_flag;
uint16_t delay_count;
void delay_ms(uint16_t ntime)
{

}
回复

使用道具 举报

ID:592807 发表于 2021-8-2 16:06 | 显示全部楼层
1  你这里是将16进制数字直接赋值给32进制变量,最好进制一致,要么都用16要么都用32,虽然不报错,但是习惯要养好。 uint32_t count;               //定义了一个全局变量,stm32f10x_it.h也声明这个全局变量
void delay(uint16_t ntime)  //延时函数,ntime就是次数
{
count=ntime;  

2 就是你的滴答定时器不会因为你的delay函数计时结束就不进入中断,所以你最好加一个标志位,没有调用delay()函数时它不做任何处理直接退出
   {
if(delay_flag ==1){count--;}
else ;
   }  

回复

使用道具 举报

ID:632424 发表于 2021-8-2 21:20 | 显示全部楼层
黄youhui 发表于 2021-8-2 16:06
1  你这里是将16进制数字直接赋值给32进制变量,最好进制一致,要么都用16要么都用32,虽然不报错,但是习 ...

感谢指正,我刚学,经验不足
回复

使用道具 举报

ID:958310 发表于 2021-8-5 19:38 | 显示全部楼层
我昨天在论坛上看到了一个更高级的方法,你这里是每到2S时间就一直卡死,这样太浪费CPU资源了,可以设计成如果没到2S就跳过/忽略这个操作,然后继续下去执行别的操作。这样系统实时性就提高很多,CPU就能做到“负载均衡”了…………
回复

使用道具 举报

ID:592807 发表于 2021-8-7 09:04 | 显示全部楼层
bigbigcong 发表于 2021-8-5 19:38
我昨天在论坛上看到了一个更高级的方法,你这里是每到2S时间就一直卡死,这样太浪费CPU资源了,可以设计成 ...

事事无绝对,有些地方是必须要卡主的,比如某些外设初始化需要延时1S启动。你说的那是标志位必须用在循环不停检测标志位才行,它不会运行到第一万行代码时,时间到了就突然跳到第一执行代码,必须在第一到第n行代码之间不停循环,确保时间一到立马能执行对应的函数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表