STM32 开发板入门教程 (三) 系统时钟 SysTick

发布者:EnchantedDream最新更新时间:2015-08-12 来源: eefocus关键字:STM32  开发板  系统时钟  SysTick 手机看文章 扫描二维码
随时随地手机看文章
(一) 背景介绍

在传统的嵌入式系统软件按中通常实现 Delay(N) 函数的方法为:

for(i = 0; i <= x; i ++);

          ---  对应于 对应于 N 毫秒的循环值

对于STM32系列微处理器来说,执行一条指令只有几十个 ns,进行 for 循环时,要实现 N 毫秒的 x 值非常大,而且由于系统频率的宽广,很难计算出延时 N 毫秒的精确值。针对 STM32 微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用 Delay(N)。


(二) STM32 SysTick 介绍

Cortex-M3 的内核中包含一个 SysTick 时钟。SysTick 为一个 24 位递减计数器,SysTick 设定初值并使能后,每经过 1 个系统时钟周期,计数值就减 1。计数到 0 时,SysTick 计数器自动重装初值并继续计数,同时内部的 COUNTFLAG 标志会置位,触发中断 (如果中断使能情况下)。

在 STM32 的应用中,使用 Cortex-M3 内核的 SysTick 作为定时时钟,设定每一毫秒产生一次中断,在中断处理函数里对 N 减一,在Delay(N) 函数中循环检测 N 是否为 0,不为 0 则进行循环等待;若为 0 则关闭 SysTick 时钟,退出函数。

注: 全局变量 TimingDelay , 必须定义为 volatile 类型 , 延迟时间将不随系统时钟频率改变。



(三) ST SysTick 库文件

使用ST的函数库使用systick的方法
1、调用SysTick_CounterCmd()               -- 失能SysTick计数器
2、调用SysTick_ITConfig ()                     -- 失能SysTick中断
3、调用SysTick_CLKSourceConfig()        -- 设置SysTick时钟源。
4、调用SysTick_SetReload()                  -- 设置SysTick重装载值。
5、调用SysTick_ITConfig ()                     -- 使能SysTick中断
6、调用SysTick_CounterCmd()               -- 开启SysTick计数器


(四) SystemTick 工程实战

外部晶振为 8 MHz,9 倍频,系统时钟为 72MHz,SysTick 的最高频率为9MHz(最大为HCLK / 8),在这个条件下,把 SysTick 效验值设置成9000,将 SysTick 时钟设置为 9 MHz, 就能够产生 1ms 的时间基值,即 SysTick 产生 1ms 的中断。

   
    RCC_Configuration();
    SysTick_Configuration();


第一步: 配置 RCC 寄存器 和 SysTick 寄存器

RCC_Configuration: 配置 RCC 寄存器
void RCC_Configuration(void)
{
   
    RCC_DeInit();
   
   
    RCC_HSEConfig(RCC_HSE_ON);
   
   
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
   
    if(HSEStartUpStatus == SUCCESS)
    {
        
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        
        
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
        
        RCC_PCLK1Config(RCC_HCLK_Div2);
        
        
        FLASH_SetLatency(FLASH_Latency_2);
        
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        
        
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        
        
        RCC_PLLCmd(ENABLE);
        
        
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
        {
        }
        
        
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        
        while(RCC_GetSYSCLKSource() != 0x08)
        {
        }
    }
   
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
                         RCC_APB2Periph_AFIO, ENABLE);
}



SysTick_Configuration: 配置 SysTick
void SysTick_Configuration(void)
{
   
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
   
   
    NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 3, 0);
   
   
    SysTick_SetReload(72000);
   
   
    SysTick_ITConfig(ENABLE);
}



第二步: 配置 SysTick 中断函数

这里我们定义了一个 TestSig 全局变量, 用于我们使用 Keil 软件自带的逻辑分析仪来分析.


volatile vu32 TimingDelay = 0;
vu8 TestSig = 0;

void SysTickHandler(void)
{
    TimingDelay--;
    if(TimingDelay % 2)
    {
        TestSig = 1;
    }
    else
    {
        TestSig = 0;
    }
}


第三步: 编写 Delay 延时函数

Delay: 系统延时函数, 使用系统时钟操作.

void Delay(u32 nTime)
{
   
    SysTick_CounterCmd(SysTick_Counter_Enable);
   
    TimingDelay = nTime;
   
    while(TimingDelay != 0);
   
   
    SysTick_CounterCmd(SysTick_Counter_Disable);
   
    SysTick_CounterCmd(SysTick_Counter_Clear);
}


第四步:  主函数中调用 Delay

在 Mini-STM32 开发板上有两个 LED 灯, 分别是 PA0, PA1. 我们做个流水灯程序, 让他们循环点亮.
    while(1)
    {   
        GPIO_SetBits(GPIOA,GPIO_Pin_0);
        Delay(100);
        GPIO_ResetBits(GPIOA,GPIO_Pin_0);
        Delay(100);
        GPIO_SetBits(GPIOA,GPIO_Pin_1);
        Delay(100);
        GPIO_ResetBits(GPIOA,GPIO_Pin_1);
        Delay(100);  
    }


(五) 仿真调试

把工程通过后, 进入软件仿真
如下图所示:点击工程快捷菜单的逻辑分析仪

在逻辑分析仪中我们点击 Setup 按键会弹出安装对话框.
点右上方的 "新建" 图标, 在菜单中输入 "TestSig" 这个全局变量.
添加完之后就可以点 Close 了. 如果您仿真完可以点击 左下方的 "Kill All" 删除所有监视变量.

全速运行后就可以看到下面的波形了哦


如果你使用仿真器在 Mini-STM32 上调试的话你还可以看到两个 LED 在跑跑马灯程序了.
到此我们这章节的教程就结束了, 相信大家也掌握了 System Tick 的用法了.
关键字:STM32  开发板  系统时钟  SysTick 引用地址:STM32 开发板入门教程 (三) 系统时钟 SysTick

上一篇:STM32开发板学习笔记--通用定时器
下一篇:STM32 开发板入门教程 (一) GPIO

推荐阅读最新更新时间:2024-03-16 14:28

结合STM32给大家描述一下单片机常见的划分区域
编排 | strongerHuang 看到有小伙伴在讨论关于单片机内存的话题,今天就结合STM32给大家描述一下常见的划分区域。 在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)、常量区、代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。 总的分布如下所示: 内存高地址 栈区 堆区 .bss段 .data段 常量区 内存低地址 代码区 一、栈区(stack) 临时创建的局部变量存放在栈区。 函数调用时,其入口参数存放在栈区。 函数返回时,其返回值存放在栈区。 const定义的局部变量存放在栈区。 2、堆区(heap) 堆区用于存放程序运行
[单片机]
结合<font color='red'>STM32</font>给大家描述一下单片机常见的划分区域
stm32校验和计算的问题
常用的通信中,经常会有一些校验方法,比如DHT22的单总线协议。 根据参考手册,只需要计算 if((buf +buf +buf +buf )==buf ) 就可以了,但是!!! 对于stm32来说,其计算结果可能不是想象中的那样,举个例子,buf0-4的值都为0x80,那么和就是0x200,至少对于stm32来说,结果是0x00000200,而buf 的值是0,那么0x200和0相等吗? 所以这个判断不成立,就得不到我们想要的值。 只需要在判断计算的时候加一个变量强制转换,或者对256取模就可以了。 if((u8)(buf +buf +buf +buf )==buf ) { *humi=(buf
[单片机]
STM32:外部晶振时钟配置
void SystemClock_Config(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); //INPUT HSE = 24M ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(ENABLE); //M0 defined FLASH_SetLatency(FLASH_Latency_1); //M0 defined RCC_PR
[单片机]
<font color='red'>STM32</font>:外部晶振<font color='red'>时钟</font>配置
STM32 arm汇编(thumb-2指令集)启动代码分析
;// h Stack Configuration ;// o Stack Size (in Bytes) 0x0-0xFFFFFFFF:8 ;// /h Stack_Size EQU 0x00000200 ;//定义堆栈大小 AREA STACK, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段 按8字节对齐 ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0 Stack_Mem SPACE Stack_Size
[单片机]
STM32外部中断测试
环境: 主机:WIN7 开发环境:MDK4.23 MCU:STM32F103CBT6 说明: STM32有20个外部中断线,其中EXTI0-EXTI15给I/O端口使用 EXTI线16连接到PVD输出 EXTI线17连接到RTC闹钟事件 EXTI线18连接到USB唤醒事件 EXTI线19连接到以太网唤醒事件(只适用于互联型产品) 源代码: 初始化: //打开NTRX外部中断 void open_ntrx_irq(void) { //定义中断结构体 NVIC_InitTypeDef NVIC_InitStructure ; //定义外部中断结构体 EXTI_InitTypeDe
[单片机]
<font color='red'>STM32</font>外部中断测试
STM32 ADC 多通道16路电压采集
下面介绍一种利用STM32单片机制作的16路多通道ADC采集电路图和源程序。采用USB接口与电脑连接,实则USB转串口方式,所以上位机可以用串口作为接口。电路图中利用LM324作为电压跟随器,起到保护单片机引脚的作用。直接在电脑USB取点,省去外接电源麻烦,实测耗电电流不到20ma. 1.主控电路图: 2. USB转串口电路图 3.LM324电压跟随器电路图 4.滤波电路图 5.16路接口电路图 6.电源电路图 7.16路ADC初始化程序: void Adc_Init(void) { //先初始化IO口 RCC- APB2ENR|=0X7 2; //使能PORTA\PORAB\PORTC口
[单片机]
<font color='red'>STM32</font> ADC 多通道16路电压采集
STM32中电源各引脚说明
一、数字电路中,电源符号VCC:C=circuit,表示电路的意思,即接入电路的电压;VDD:D=Device,表示器件的意思,即器件的工作电压;VSS:S=Series,表示公共连接的意思,通常指电路公共接地端电压。总结来说,VCC接电路的电源(±),VSS接电路的地,VDD接器件的电源引脚(±)。 二、STM32中电源各引脚说明VDDA:A=Analog,表示模拟的意思,所以就是表示模拟器件的工作电压;VSSA:表示模拟器件的公共端地。VBAT:给后备区域供电,维持包括RTC/BKP寄存器等在内的一些数据的保存。100引脚的封装中:VREF-:A/D的参考,当需要使用时,必须绑定到VSSA(使得所有模拟器件的参考都相对于V
[单片机]
使用STM32单片机点亮LED
有一人,登场于金庸先生的《神雕侠侣》,以大理段氏“一阳指”自成一派,武学修为登峰造极,“天下五绝”之一,号称“南帝”,他就是“一灯大师”。如今,武林中逐渐被遗忘的“一灯大师”,却活跃在另一个行业——嵌入式开发中。 传说,每一个成功的MCU(俗称单片机)开发组中,都有一名“一灯大师”,他精通所有开发板的点灯方法,对于企业引入的新开发板,总是勤学苦练,从点灯开始,快速掌握新开发板的编程要点,带领团队走向胜利。 成为“一灯大师”,离不开持续的修行,离不开对一招一式的勤学苦练。本文将讲解如何通过编程来控制STM32点亮一个LED。 学习环境: 1.软件:Keil5 2.硬件:STM32开发板(笔者使用信盈达公司的M4开发板,芯片型
[单片机]
使用<font color='red'>STM32</font>单片机点亮LED
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved