你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32之Systick(系统时钟)

[复制链接]
STMCU小助手 发布时间:2022-1-20 21:23
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计数器;

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

  4. //----------------函数声明--------------------
  5. void Delay_MS(u16 dly);
  6. void RCC_Configuration(void);
  7. void GPIO_Configuration(void);
  8. void USART3_Configuration(void);


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

  10. void SYSTICK_Configuration(void)
  11. {
  12.     SysTick_CounterCmd(SysTick_Counter_Disable);
  13.     SysTick_ITConfig(DISABLE);
  14.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  15.     SysTick_SetReload(9000*1000);
  16.        SysTick_CounterCmd(SysTick_Counter_Enable);

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


  20. /*******************************************************************************
  21. * Function Name  : main
  22. * Description    : Main program.
  23. * Input          : None
  24. * Output         : None
  25. * Return         : None
  26. *******************************************************************************/
  27. int main(void)
  28. {
  29.     u8 min, sec;
  30.     #ifdef DEBUG
  31.     debug();
  32.     #endif
  33.     //------------初始化------------
  34.     RCC_Configuration();
  35.     GPIO_Configuration();   
  36.     USART3_Configuration();
  37.     SYSTICK_Configuration();      

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

  43.     while(1)
  44.     {
  45.         FlagStatus Status;
  46.         Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
  47.         if(Status == RESET)
  48.         {
  49.             ;
  50.         }
  51.         else
  52.         {
  53.             sec++;
  54.             if(sec == 60)
  55.             {
  56.                 sec=0;
  57.                 min++;
  58.             }
  59.             printf("\t\t%d:%d", min, sec);
  60.         }
  61.     }
  62.         
  63. }

  64. /*******************************************************************************
  65. * Function Name  : Delay_Ms
  66. * Description    : delay 1 ms.
  67. * Input          : dly (ms)
  68. * Output         : None
  69. * Return         : None
  70. *******************************************************************************/
  71. void Delay_MS(u16 dly)
  72. {
  73.     u16 i,j;
  74.     for(i=0;i<dly;i++)
  75.         for(j=1000;j>0;j--);
  76. }

  77. /*******************************************************************************
  78. * Function Name  : RCC_Configuration
  79. * Description    : Configures the different system clocks.
  80. * Input          : None
  81. * Output         : None
  82. * Return         : None
  83. *******************************************************************************/
  84. void RCC_Configuration(void)
  85. {
  86.     //----------使用外部RC晶振-----------
  87.     RCC_DeInit();            //初始化为缺省值
  88.     RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟
  89.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪
  90.    
  91.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
  92.     FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state
  93.    
  94.     RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK
  95.     RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK
  96.     RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/2
  97.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ
  98.     RCC_PLLCmd(ENABLE);            //Enable PLLCLK

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

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

  135. void USART3_Configuration(void)
  136. {
  137.     USART_InitTypeDef USART_InitStructure;
  138.     USART_InitStructure.USART_BaudRate = 9600;
  139.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  140.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  141.     USART_InitStructure.USART_Parity = USART_Parity_No;
  142.     USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;
  143.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

  144.     USART_Init(USART3, &USART_InitStructure);

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

  147. /***********************************************************
  148. name:    fputc                                               *
  149. Description:重定向这个c库printf函数,文件流--->串口USART  *
  150.                                                            *
  151. ************************************************************/
  152. int fputc(int ch,FILE *f)
  153. {
  154.     //ch发送给USART1
  155.     USART_SendData(USART3, ch);
  156.     //等待发送完毕
  157.     while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)
  158.         ;
  159.     return ch;
  160. }
复制代码

收藏 评论0 发布时间:2022-1-20 21:23

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版