#一、系统定时器简介
    
    #二、SysTick定时时间的计算
    
    #三、SysTick中断优先级
    
    #四、SysTick的应用及其代码
   
    
     一、系统定时器简介
    
   
    SysTick:24位系统定时器,
    
     只能递减
    
    ,存在于内核嵌套在NVIC中,所有的Cortex_M中都有这个系统定时器。
   
    重装载值reload递减,当递减到0会触发中断并且会有置位countflag标志,VAL表示当前值,然后reload继续从预设值开始递减,周而复始。
    
    
    
    
    
     
   
    
     二、SysTick定时时间的计算
    
   
    1.
    
     T
    
    :一个计数循环的时间,跟reload和CLK有关
    
    2.
    
     CLK
    
    :72M或9M,由CTRL寄存器配置
    
    3.
    
     reload
    
    :24位,用户自己配置
   
    
     
      T=reload
     
     (1/CLk)
    
    *
   
    CLK=72M,1us=(72)
    
     (1/72000000)
     
     CLK=72M,1ms=(72000)
    
    (1/72000000)
   
时间单位换算:1us=1000ms=1000000us=1000000000ns
    
     三、SysTick中断优先级
    
    
    1.system tick属于内核的外设,它的中断优先级配置:scb->sharx寄存器;
    
    外设中断优先级配置的是nvic->iprx寄存器
    
    有优先级的分组
   
    2.STM32 的外设(内核还是片上)都是使用4个二进制来表示中断优先级
    
    3.中断优先级的分组对内核和外设同样适用,只需要将中断优先级的四个位按外设优先级来分组即可,人为的进行分出抢占优先级和子优先级。
   
    
     举例:
    
   
1<<4-1=16-1=15(1 1 1 1)
    
     四、SysTick的应用及其代码
    
   
1)编写一个us延迟函数
2)编写一个ms延迟函数
    
     文件新建:
    
   
    1.在USER中新建文件夹SYSTEM
    
    
    
    2.打开工程,在工程中新建组别
    
    
    
    3.为新建的组别命名
    
    
    
    4.将在USER文件夹新建的SYSTEM文件夹添加进新建组别中
    
    
    
    5.在内核中调用的系统定时器使能函数 :uint32_t SysTick_Config(uint32_t ticks)
    
    
    
    6.控制/状态寄存器使能
    
    
    
    
     代码部分:
    
   
SysTick.c
#include "stm32f10x.h"
#include "systick.h"
void ms_delay(uint32_t ms)//毫秒级延迟函数
{
	  uint32_t i=0;
		SysTick_Config(72000);//定义一个循环1毫秒
	  for(i=0;i<ms;i++)
	  {
		   
			  while(!((SysTick->CTRL)&(1<<16)));
		
		}
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//将控制及状态寄存器失能
}
void us_delay(uint32_t ms)//微秒级延迟函数
{
	  uint32_t i=0;
		SysTick_Config(72);//定义一个循环1微秒
	  for(i=0;i<ms;i++)
	  {
		   
			  while(!((SysTick->CTRL)&(1<<16)));
		
		}
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//将控制及状态寄存器失能
}
SysTick.h
#include "stm32f10x.h"
void ms_delay(uint32_t ms);
void us_delay(uint32_t ms);
main.c
#include "stm32f10x.h"
#include "main.h"
#include "LED.h"
#include "usart.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "tim.h" 
#include "motor.h"
#include "systick.h"
void delay(uint16_t time)//延迟函数
{
		uint16_t i=0;
	  while(time--)
		{
				i=12000;
			  while(i--);
		}
}
int  main()
{
	 usart_init();//串口初始化
	 LED_Init();//LED初始化
	 GPIO_SetBits(GPIOA,GPIO_Pin_1);//关灯
	
	while(1)
	{
			GPIO_ResetBits(GPIOA,GPIO_Pin_1);//开灯
		  ms_delay(500);//延时500ms
		  GPIO_SetBits(GPIOA,GPIO_Pin_1);//关灯
		  ms_delay(500);//延时500ms
		
	
	}
	 
	
	 
	 
}
	
usart.c
#include "stm32f10x.h"
#include "usart.h"
#include <stdio.h>
void usart_init(void)
{
	  
		GPIO_InitTypeDef gpioinstructure;//GPIO结构体初始化函数
	  USART_InitTypeDef usartinstructure;//USART结构体初始化函数
	  NVIC_InitTypeDef  nvicinstructure;//中断控制器结构体初始化函数
	  
	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断控制器优先抢占级组
		
	//1.配置GPIO、USART、引脚复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置GPIOA时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置引脚复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//配置USART时钟
		
	//2.配置GPIO结构体
	   
    //配置PA9 TX 输出引脚
		gpioinstructure.GPIO_Mode  =  GPIO_Mode_AF_PP;//复用推挽输出
	  gpioinstructure.GPIO_Pin   =  GPIO_Pin_9 ;//引脚9
	  gpioinstructure.GPIO_Speed =  GPIO_Speed_50MHz;//速度为50Mhz
	
	  GPIO_Init(GPIOA,&gpioinstructure);//GPIO初始化
	
	  //配置PA10 RX 接收引脚
	  gpioinstructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输出
	  gpioinstructure.GPIO_Pin   = GPIO_Pin_10;//引脚10
		
		GPIO_Init(GPIOA,&gpioinstructure);//GPIO初始化
		
	//3.配置串口的结构体
	  usartinstructure.USART_BaudRate = 115200;//波特率为115200
		usartinstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流配置
		usartinstructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx ;//接收模式
		usartinstructure.USART_Parity = USART_Parity_No;//无校验位
		usartinstructure.USART_StopBits = USART_StopBits_1;//一个停止位
		usartinstructure.USART_WordLength = USART_WordLength_8b;//有效数据位为8位
    
    USART_Init(USART1,&usartinstructure);//初始化串口1
    
    USART_Cmd(USART1,ENABLE);	//使能串口1
		
		USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//串口中断配置
		
	//4.配置中断控制器的结构
	  nvicinstructure.NVIC_IRQChannel  =  USART1_IRQn;//中断通道
		nvicinstructure.NVIC_IRQChannelCmd = ENABLE; //通道使能
		nvicinstructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级配置为1
		nvicinstructure.NVIC_IRQChannelSubPriority = 1;//子优先级配置为1
		
	  NVIC_Init(&nvicinstructure);//中断控制器初始化
			  
}
//发送字符
void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
		USART_SendData(USARTx, Data);
	  while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET);
}
//发送字符串
void USARTSendStr(USART_TypeDef* USARTx, char *str)
{
		uint16_t i=0;
	  do
		{
			  USARTSendByte(USARTx,*(str+i));
			  i++;
		}while(*(str+i)!='\0');
		
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
		
}
//printf函数的重映射
int fputc(int ch,FILE *f)
{
		USART_SendData(USART1,(uint8_t)ch);//发送
	  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//发送数据寄存器空标志位判断
	  
		return (ch);
	
}
int fgetc(FILE *f)
{
		while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);//接收数据寄存器非空标志位判断
    return (int)USART_ReceiveData(USART1);//返回接收到的字符
}
 
		
usart.h
#include "stm32f10x.h"
#include <stdio.h>
void usart_init(void);
void USARTSendStr(USART_TypeDef* USARTx, char *str);
 
