基于STM32F103C8T6的系统定时器SysTick配置LED灯闪烁

  • Post author:
  • Post category:其他


#一、系统定时器简介

#二、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);







版权声明:本文为weixin_72921448原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。