#一、系统定时器简介
#二、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);