stm32之Systick(系统时钟)

简介: Systick的两大作用:   1、可以产生精确延时;   2、可以提供给操作系统一个单独的心跳(时钟)节拍; 通常实现Delay(N)函数的方法为:   for(i=0;i串口USART * ...

Systick的两大作用:

  1、可以产生精确延时;

  2、可以提供给操作系统一个单独的心跳(时钟)节拍;

通常实现Delay(N)函数的方法为:

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

    ;

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

  cortex的内核中包含一个SysTick时钟,SysTick为一个24位递减计数器;SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1;计数到0,SysTick计数器自动装载初值并继续计数,同时内部的COUNTFLAG标志会置位;触发中断(前提是中断使能);

  如果外部晶振(即外接的晶振)位8Mhz,经过内部9分频;系统时钟则为72Mhz(cpu的时钟);SysTick的最高频率为9Mhz(cpu时钟的8分频);在这个条件下;如果设置SysTick值为9000;而SysTick是9Mhz;则能产生1ms的时间基;即SysTick产生1ms的中断;

 

  SysTick相关的寄存器:

  CTRL:  SysTick控制和状态寄存器;

  LOAD:  SysTick重装载值寄存器;

  VAL:   SysTick当前寄存器;(重新写入的时候;会把状态寄存器的FLAG清零)

  CALIB:  SysTick校准值寄存器;

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计数器;

 

/*Include---------------------------*/
#include"stm32f10x_lib.h"        //包含所有的头文件
#include<stdio.h>

//----------------函数声明--------------------
void Delay_MS(u16 dly);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART3_Configuration(void);


u8 tab[] = "hello welcome to class !";

void SYSTICK_Configuration(void)
{
    SysTick_CounterCmd(SysTick_Counter_Disable);
    SysTick_ITConfig(DISABLE);
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    SysTick_SetReload(9000*1000);
       SysTick_CounterCmd(SysTick_Counter_Enable);

    //*************打开systick时钟,但是由于systick时钟是默认开启的;
    
}      


/*******************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/ 
int main(void)
{
    u8 min, sec;
    #ifdef DEBUG
    debug();
    #endif
    //------------初始化------------
    RCC_Configuration();
    GPIO_Configuration();    
    USART3_Configuration();
    SYSTICK_Configuration();      

//     id_num[0] = *((u8*)(0x1FFFF7E9));    //stm32芯片id的放置地址,96位id;12字节
     printf("hello world\n");
    //------------将数据上传给上位机-----------
    min = 1;
    sec = 30;

    while(1)
    {
        FlagStatus Status;
        Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
        if(Status == RESET)
        {
            ;
        }
        else
        {
            sec++;
            if(sec == 60)
            {
                sec=0;
                min++;
            }
            printf("\t\t%d:%d", min, sec);
        }
    }
        
}

/*******************************************************************************
* Function Name  : Delay_Ms
* Description    : delay 1 ms.
* Input          : dly (ms)
* Output         : None
* Return         : None
*******************************************************************************/
void Delay_MS(u16 dly)
{
    u16 i,j;
    for(i=0;i<dly;i++)
        for(j=1000;j>0;j--);
}

/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
    //----------使用外部RC晶振-----------
    RCC_DeInit();            //初始化为缺省值
    RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟 
    while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪
    
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
    FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state
    
    RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK
    RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK
    RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/2
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ
    RCC_PLLCmd(ENABLE);            //Enable PLLCLK

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait till PLLCLK is ready
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);    //Select PLL as system clock
    while(RCC_GetSYSCLKSource()!=0x08);        //Wait till PLL is used as system clock source
    
    //---------打开相应外设时钟--------------------
    RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);    //使能APB2外设的GPIOC的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启             
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : 初始化GPIO外设
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
//由电路图可知;配置PC10,PC11引脚
void GPIO_Configuration(void)
{
    //CLK:PB5  CLR:PE11 DATA:PE10
    GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PB.1-
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //输出模式为 "复用推挽输出"
    GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOB寄存器
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ;     //选择PE.10 PE.11
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输出模式为    "浮空输入"
    GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOE寄存器
    
    //开启时钟    必须在RCC_Configuration中设置    
    
    
    //端口重映射:PC10/PC11
    GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);    
} 

void USART3_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

    USART_Init(USART3, &USART_InitStructure);

    USART_Cmd(USART3, ENABLE);    //开启使能
}

/***********************************************************
 name:    fputc                                               *
 Description:重定向这个c库printf函数,文件流--->串口USART  *
                                                           *
************************************************************/
int fputc(int ch,FILE *f)
{
    //ch发送给USART1
    USART_SendData(USART3, ch);
    //等待发送完毕
    while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)
        ;
    return ch;
}

 

相关文章
|
4月前
|
芯片
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
215 0
|
24天前
|
传感器 监控 物联网
基于STM32+微波雷达设计的非接触式睡眠监控系统
本项目开发一种非接触式的睡眠监控系统,该系统利用先进的60GHz毫米波雷达技术和STM32微控制器,实现了对人体在睡眠过程中的存在感知、运动感知以及生理指标如呼吸频率、心率的实时监测。系统能够自动评估睡眠质量,并在用户睡眠周期结束时提供睡眠评分。为了确保用户能够在任何地点了解自己的睡眠状况,系统集成了Wi-Fi模块,可以将收集到的数据上传至华为云物联网平台,并通过专门设计的移动应用程序供用户远程访问。此外,系统还具备超阈值报警功能,当检测到异常的生理指标时会发出警报提醒。本地1.44寸TFT LCD显示屏用于实时显示监测到的信息,包括生理指标和环境数据。为了全面监测用户的健康状况,系统还加入了
66 0
基于STM32+微波雷达设计的非接触式睡眠监控系统
|
15天前
|
存储 机器学习/深度学习 编解码
基于STM32的车牌识别系统
基于STM32的车牌识别系统
45 0
|
15天前
|
传感器 网络协议 物联网
基于STM32的环境监测系统 (esp8267)(下)
基于STM32的环境监测系统 (esp8267)(下)
44 0
|
15天前
|
传感器 测试技术 芯片
基于STM32的环境监测系统 (esp8266)(上)
基于STM32的环境监测系统 (esp8266)(上)
111 0
|
2月前
|
存储 传感器 Linux
STM32微控制器为何不适合运行Linux系统的分析
总的来说,虽然技术上可能存在某些特殊情况下将Linux移植到高端STM32微控制器上的可能性,但从资源、性能、成本和应用场景等多个方面考虑,STM32微控制器不适合运行Linux系统。对于需要运行Linux的应用,更适合选择ARM Cortex-A系列处理器的开发平台。
191 0
|
4月前
|
前端开发 安全
stm32f407探索者开发板(十一)——SystemInit时钟系统初始化剖析
stm32f407探索者开发板(十一)——SystemInit时钟系统初始化剖析
123 0
|
4月前
stm32f407探索者开发板(十)——时钟系统精讲
stm32f407探索者开发板(十)——时钟系统精讲
|
6月前
|
内存技术 存储 Android开发
MCU最小系统电路设计(以STM32F103C8T6为例)-3
MCU最小系统电路设计(以STM32F103C8T6为例)
MCU最小系统电路设计(以STM32F103C8T6为例)-3
|
5月前
|
芯片
【STM32】详解RTC实时时钟的概念和配置&示例代码
【STM32】详解RTC实时时钟的概念和配置&示例代码