8、TM4单片机的滴答定时器,及利用定时器精确延时
在我们日常使用单片机的时候,延时一般采用循环的方式,但是这样的方式只能用于粗略的延时,但我们需要精准的时间控制的时候,便需要利用定时器获得精确的延时。
本次采用TM4内的滴答定时器。
文章目录
- 1、滴答定时器使用
- (1)初始化代码
- (2)解释
- 2、利用定时器进行延时的方法
- 1、精髓:micros()函数
- 2、利用micros()实现延时
- 测试例程1
- 测试例程2
1、滴答定时器使用
滴答定时器结构比较简单,在TM4内部是一个24位自减的计数器。
(1)初始化代码
SysTickPeriodSet(SysCtlClockGet()/1000); // 1ms
SysTickIntRegister(SysTick_IntHandler);
SysTickIntEnable();
SysTickEnable();
(2)解释
1、首先进行周期设置,用系统频率除以1000,表示1ms的中断。
计算方法:定时器的工作原理便是在系统时钟驱动下进行计数,假设系统时钟频率是10KHz,代表1秒钟可以计10000个数,即:即计一个数的时间t = 1/10000 s = 0.1 ms
,那么如果我要设置一个一毫秒的中断,即需要数10个数,因为10*(1/10000) = 1/1000 s = 1ms
。
因此对于SysTickPeriodSet()
这个函数来说,我需要一毫秒的中断,便将系统时钟除以1000作为参数传进去即可。
2、然后设置中断函数的地址
即SysTick_IntHandler
便是中断处理函数的函数名称,代表该函数的地址。
3、使能中断,打开定时器
SysTickIntEnable();
SysTickEnable();
4、写中断处理函数
这里是设置了一个全局变量,每进入一次中断便将其加1。
void SysTick_IntHandler(void)
{System_Time_ms++;
}
5、测试:见文末测试例程1。
2、利用定时器进行延时的方法
1、精髓:micros()函数
首先我们需要知道系统的当前精确时间,这里实现了一个micros()
函数,以微秒为单位。
uint32_t micros(void)
{register uint32_t ms, tick; do{ms = System_Time_ms;tick = HWREG(NVIC_ST_CURRENT); }while(ms != System_Time_ms);return (ms+1)*1000 - tick/usTicks;
}
在这个函数中,因为滴答定时器的中断是1ms,所以System_Time_ms
便是系统运行的ms数,HWREG(NVIC_ST_CURRENT)
是针对寄存器的操作,获得当前滴答定时器内部的计数值。usTicks = Clock/1000000
,所以tick/usTicks = tick*(1000000/Clock)
,即将定时器计数值转换为实际的us数,然后通过(ms+1)*1000 - tick/usTicks
的运算,即得到了us级的系统时间。
2、利用micros()实现延时
这里的逻辑就是进入函数时记录当前时间,然后一直用实时时间和开始时间进行比较,作差,得到延时时间。
void delay_us(uint32_t nus)
{uint32_t t0 = micros();while(micros() - t0 < nus);
}void delay_ms(uint32_t nms)
{uint32_t t0 = micros();while(micros() - t0 < nms*1000);
}
测试:见测试例程2。
测试例程1
功能:打印系统当前时间,以毫秒为单位。
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/systick.h"
#include <stdio.h>uint32_t System_Time_ms = 0;void delay_ms(int n)
{for(int i = 0; i < n; i++)SysCtlDelay(SysCtlClockGet()/3000);
}//重写fputc函数以支持printf
int fputc(int ch, FILE *f)
{UARTCharPut(UART0_BASE,(unsigned char)ch);//如果用其他串口,只需修改基址(UART0_BASE)即可。return ch;
}void SysTick_IntHandler(void)
{System_Time_ms++;
}int main()
{ SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);//初始化串口0SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));GPIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);UARTConfigSetExpClk(UART0_BASE, 16000000, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));//初始化滴答定时器SysTickPeriodSet(SysCtlClockGet()/1000); // 1msSysTickIntRegister(SysTick_IntHandler);SysTickIntEnable();SysTickEnable();while(1){printf("%d\n", System_Time_ms);//打印系统时间delay_ms(100);}
}
测试例程2
功能:延时10ms,然后打印出来花费的具体时间。
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/systick.h"
#include "inc/hw_types.h"
#include "inc/hw_nvic.h"
#include <stdio.h>volatile uint32_t usTicks = 0;
volatile uint32_t System_Time_ms = 0;void delay_us(uint32_t nus);
void delay_ms(uint32_t nms);
int fputc(int ch, FILE *f);
void SysTick_IntHandler(void);
uint32_t micros(void);
void UART0_Init(uint32_t Baud);
void SysTick_Init(void);int main(void)
{ SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);UART0_Init(115200);SysTick_Init();uint32_t t0,t1;while(1){t0 = micros();delay_ms(10);t1 = micros();printf("%d\n", t1-t0);//打印系统时间}
}void delay_us(uint32_t nus)
{uint32_t t0 = micros();while(micros() - t0 < nus);
}void delay_ms(uint32_t nms)
{uint32_t t0 = micros();while(micros() - t0 < nms*1000);
}int fputc(int ch, FILE *f)
{UARTCharPut(UART0_BASE,(unsigned char)ch);return ch;
}void SysTick_IntHandler(void)
{System_Time_ms++;
}uint32_t micros(void)
{register uint32_t ms, tick; do{ms = System_Time_ms;tick = HWREG(NVIC_ST_CURRENT); }while(ms != System_Time_ms);return (ms+1)*1000 - tick/usTicks;
}void UART0_Init(uint32_t Baud)
{SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));GPIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);UARTConfigSetExpClk(UART0_BASE, 16000000, Baud, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}void SysTick_Init(void)
{SysTickPeriodSet(SysCtlClockGet()/1000); // 1msSysTickIntRegister(SysTick_IntHandler);SysTickIntEnable();SysTickEnable();usTicks = SysCtlClockGet() / 1000000; // usTicks = 80
}
8、TM4单片机的滴答定时器,及利用定时器精确延时相关推荐
- 基于STM32滴答时钟的多任务定时器
基于STM32滴答时钟的多任务定时器 基于STM32滴答时钟的多任务定时器 概述 声明:此定时器仅提升个人编程能力和学习使用,不得用于商用,用于商用一切后果自行负责. API说明 滴答时钟初始化并创建 ...
- c语言流水灯定时器延时,实现流水灯以间隔500ms的时间闪烁(系统定时器SysTick实现的精确延时)...
/** ****************************************************************************** * @file main.c * ...
- 实现流水灯以间隔500ms的时间闪烁(系统定时器SysTick实现的精确延时)
/** ****************************************************************************** * @file main.c * ...
- STM32系统滴答_及不可不知的延时技巧
我想每个单片机爱好者及工程开发设计人员都有过点灯的经历.流水灯是个好东西,尤其是在调试资源有限的环境中,有时会帮上大忙. 然在最初入门时,如何让这些小灯们按照我们的想法欢快地跑起来呢,绝大多数小朋友的 ...
- STM32系统滴答_及不可不知的延时技巧 - (上)
文章转载自https://my.oschina.net/czzhu/blog/228596:作者:小汉憨憨 摘要: 尤应强调注意的是SysTick 中断优先级. 我想每个单片机爱好者及工程开发设计人员 ...
- 51单片机实例学习二 按键中断识别、定时器、利用定时器产生乐曲、数摸转换 ADC0804和DAC0832
六.按键中断识别 [实验任务] 采用中断技术,每按一下按键,计数器加1,并用LED显示出来. [硬件电路] 注意:我们只用4位数码管中的两位. 注意:a接P0.0;b接P0.1;c接P0.3-- 注意 ...
- STM32系统滴答_及不可不知的延时技巧 - (下)
本文转载自https://my.oschina.net/czzhu/blog/261802:作者:小汉憨憨 摘要: 单片机非阻塞延时巧妙的软件设计. 下面为大家介绍一个曾见过的在裸机系统中,非阻塞延时 ...
- 嵌入式开发(7)系统定时器(SysTick)之延时函数运用
目录 一.系统定时器 1. 简介 2.工作原理 3.频率的概念 二.库函数SysTick定时器操作 系统定时器配置 三.寄存器SysTick定时器操作 1.系统定时器的用途 2.寄存器 3.官方示例 ...
- 【STM32】HAL库-系统滴答定时器SysTick
SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3.CM4内核芯片,都有Systick定时器.Systick定时器常用来做延时,或者实时系统的心跳时钟.这样可以节省MCU资源,不用 ...
最新文章
- Team Foundation Server Beta3 安装指南
- 一 Struts2 开发流程
- Java平滑处理什么意思_为何要进行数据平滑处理?
- python 发包爬取中国移动充值页面---可判断手机号是否异常
- 线性回归(一)---一元线性回归
- linux非root用户关机,在Linux中普通用户图形界面登录以后为什么可以关机或者重启机器...
- 在MVC3中使用code first生成数据局库并操作数据库
- 英特尔加入 GPU 战局,终用上 6nm 工艺?
- java截取字符串函数
- mysql使用GROUP BY分组实现取前N条记录的方法或最近几条消费记录
- 两部门:解除蒙古国部分地区口蹄疫疫情禁令
- axure8.0注册码
- 第二章 一元函数的导数与微分概念及其计算
- 京东E卡购买api接口
- 华为畅享20 pro 和华为畅享Z 的区别 哪个好
- Echarts折线图X轴Y轴图例位置调整
- Java——博主的学习路线
- 记一次 Centos7.x Hadoop3.x集群安装部署 Pig 0.17.0
- 2022年废纸价格预测
- 初玩SM2259XT2+B27A自制固态开卡成功,SM2259XT2量产工具和SM2258XT类似