STM32微控制器综合实训2 系统滴答定时器的应用

实验2 系统滴答定时器的应用

查询方式的延迟程序设计

delay.c

1、delay_init

1.void delay_init()  
2.{   
3.   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    //选择外部时钟  HCLK/8  
4.   fac_us=SystemCoreClock/8000000;             // 72M/8M=9,9个脉冲为1ms    
5.   ......
6.   fac_ms=(u16)fac_us*1000;//非OS下,代表每个ms需要的systick时钟数      
7.}   

fac_us表示us因子,fac_us=SystemCoreClock/8000000=72M/8M=9,表示9个脉冲为1ms,为了在之后的delay_us函数中将需要延迟的us数转化为脉冲数。

2、delay_us

1.void delay_us(u32 nus)
2.{  
3. u32 temp;       
4. SysTick->LOAD=nus*fac_us;      //时间加载      
5. SysTick->VAL=0x00;             //清空计数器
6. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数   
7. do
8. {
9.  temp=SysTick->CTRL;
10. }while((temp&0x01)&&!(temp&(1<<16)));  //等待时间到达
11. SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
12. SysTick->VAL =0X00;            //清空计数器  
13.}

其实就是先把要延时的us数换算成 SysTick 的时钟数,然后写入 LOAD 寄存器。然后清空当前寄存器VAL的内容,再开启倒数功能。等到倒数结束,即延时了nus。最后关闭 SysTick,清空VAL的值。实现一次延时nus的操作。这里特别说明一下:temp&0x01,这一句是用来判断 Systick 定时器是否还处于开启状态,可以防止 systick 被意外关闭导致的死循环。

main.c

1.  #include "sys.h"  
2.  #include "usart.h"  
3.  #include "delay.h"     
4.  int main(void)  
5.  {   
6.     
7.    GPIO_InitTypeDef  GPIO_InitStructure;
8.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);  //使能PB,PE端口时钟      
9.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;              //LED0-->PB.5 端口配置  10.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出  
10.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      
11.   GPIO_Init(GPIOE, &GPIO_InitStructure); 
12.   GPIO_SetBits(GPIOE,GPIO_Pin_5);                      
13.   delay_init();     
14.     while(1)  
15.     {  
16.       GPIO_SetBits(GPIOE,GPIO_Pin_5);            //PB.5 输出高  
17.       delay_ms(1000);  
18.       GPIO_ResetBits(GPIOE,GPIO_Pin_5);       //PB.5 输出高  
19.       delay_ms(1000);  
20.     }    
21. }   
 

编译仿真

独立按键控制LED灯的亮灭
打开仿真
在这里插入图片描述
设置断点

先点击运行
在这里插入图片描述
运行结果:
GPIOE_ORD寄存器由高电平变为低电平。
在这里插入图片描述在这里插入图片描述

中断方式的延迟程序设计

stm32f10x_it.c

完善SysTick_Handler函数

1. void SysTick_Handler(void)  
2.  {  
3.      static u8 aa;  
4.      if(aa>200)  aa=0;  
5.      else    
6.          aa++;  
7.      if(aa==100)   
8.      {  
9.              GPIO_ResetBits(GPIOE,GPIO_Pin_5);        
10.      }  
11.      else if(aa==200)  
12.      {  
13.              GPIO_SetBits(GPIOE,GPIO_Pin_5);      
14.      }  
15.  }
   

每1ms进入一次SysTick中断,并将中断次数用变量stastic修饰的变量aa保存,每进一百次SysTick中断,就把PE5清0。

main.c

1.  #include "sys.h"  
2.  #include "usart.h"  
3.  #include "delay.h"     
4.  int main(void)  
5.  {   
6.    GPIO_InitTypeDef  GPIO_InitStructure;  
7.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); 
8.       
9.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;             
10.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        
11.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     
12.  GPIO_Init(GPIOE, &GPIO_InitStructure);                    
13.  GPIO_SetBits(GPIOE,GPIO_Pin_5);                           
14.     SysTick->LOAD=360000; 
15.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);   //选择外部时钟  HCLK/8  
16.     SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |        
17.                     SysTick_CTRL_TICKINT_Msk |   
18.                     SysTick_CTRL_ENABLE_Msk;   
19.                     //选择时钟源|开启SysTick中断|SysTick使能  
20.     while(1)  
21.     {  
22. //    GPIO_SetBits(GPIOE,GPIO_Pin_5);            //PB.5 输出高  
23. //      delay_ms(1000);  
24. //      GPIO_ResetBits(GPIOE,GPIO_Pin_5);       //PB.5 输出高  
25. //      delay_ms(1000);  
26.     }     
27. }

编译仿真

打开仿真
在这里插入图片描述
设断点:
在这里插入图片描述
先点击运行
在这里插入图片描述

运行结果:
GPIOE_ORD寄存器由高电平变为低电平。
在这里插入图片描述
在这里插入图片描述

作业

1、宏定义define的作用
在这里插入图片描述
2、delay_us()函数中,变量fac_us的含义是什么,如何计算的?
在这里插入图片描述
3、如果修改系统主频为48M,则delay_us函数是否需要做相应的修改?
在这里插入图片描述
4、Systick定时器的延时时间最长到多少?(72M系统频率)如何计算的?
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答关于STM32系统滴答定时器(systick)应用的问题。 系统滴答定时器(systick)是STM32中一个非常重要的计时器,它是一个24位的递减计数器,每当计数器减为0时,会触发一个中断。它通常用于操作系统的时间片轮转、延时函数的实现等。 在STM32中,我们可以通过如下代码使能系统滴答定时器: ```c // 使能系统滴答定时器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; ``` 然后,我们可以通过如下代码设置系统滴答定时器的时钟源和计数器值: ```c // 设置系统滴答定时器的时钟源和计数器值 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk; // 使用处理器时钟作为时钟源 SysTick->LOAD = SystemCoreClock / 1000 - 1; // 设置计数器值为1ms ``` 在这段代码中,我们将系统滴答定时器的时钟源设置为处理器时钟,每次计数器减1代表1个处理器时钟周期的时间。然后我们将计数器的初值设置为`SystemCoreClock / 1000 - 1`,这里的`1000`代表我们希望系统滴答定时器每1ms中断一次。 最后,我们需要在中断服务函数中处理系统滴答定时器中断: ```c void SysTick_Handler(void) { // 处理系统滴答定时器中断 } ``` 在中断服务函数中,我们可以编写自己的代码来处理系统滴答定时器中断。例如,可以实现一个简单的延时函数: ```c void delay_ms(uint32_t ms) { uint32_t i; for (i = 0; i < ms; i++) { while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数器减为0 } } ``` 这个函数可以让程序在执行到它的时候暂停一段时间,等待系统滴答定时器中断触发一定次数后再继续执行。 希望这些代码可以帮助您更好地理解STM32系统滴答定时器应用。如果您还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值