STM32微控制器综合实训2 系统滴答定时器的应用
程序员文章站
2022-07-03 17:43:04
...
查询方式的延迟程序设计
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系统频率)如何计算的?
上一篇: 在古代,清朝妃嫔穿花盆底鞋有何作用?有一个重要原因
下一篇: 西方情人节吃什么美食