当前位置: 首页 > news >正文

6.DSP学习记录之定时器

基于 TI 28335

  • 一、28335定时器介绍
    • 1.定时原理
      • (1)寄存器简介
      • (2)对主频脉冲计数
      • (3)对TIMCLK计数
    • 2.定时器寄存器介绍
      • (1)定时器控制寄存器TIMERxTCR
      • (2)定时器预定标寄存器PSC
      • (3)定时器计数器TIM
      • (4)定时器周期寄存器TRD
  • 二、定时器中断软件实现
    • 1.定时器中断配置步骤
    • 2.定时器中断实验

如何用16位存储器表示32位?
用两个16位存储器,举例:XH:X(XH表示高16位,X表示低16位)

一、28335定时器介绍

定时器就是计数器

1.定时原理

(1)寄存器简介

28335的定时器在总体上和STM32定时器类似,但是28335相当于两个对脉冲计数的串联,首先TIMCLK组对设定 主频的脉冲计数,到计数值后输出一个TIMCLK,然后串联的计数器对TIMCLK进行计数
在这里插入图片描述
如上图,28335的定时器由四个寄存器组成:按照我的理解,按计数原理分为两组,一组为TIMCLK计数,也就是小脉冲计数(我自己理解),包括定时器分频寄存器TDDRH:TDDR(TDDRH为TDDR的高16位,下面三个类推),预定标计数器PSCH:PSC;另一组为周期寄存器 PRDH:PRD和计数器TIMH:TIM

什么是TIMCLK??
TIMCLK是一个对主频脉冲的计数值

(2)对主频脉冲计数

TIMCLK由定时器分频器TDDRH:TDDR 和定时器预定标器PSCH:PSC来控制的。
先给定时器分频器 TDDRH:TDDR 赋值,然后装载入预定标器PSCH:PSC中,每隔一个SYSCLKOUT脉冲,PSCH:PSC中的值减1,当PSCH:PSC中的值为0时,就会输出一个TIMCLK从而使TIMH:TIM减1。在下一个定时器输入时钟周期开始时,TDDRH:TDDR中的值重新装载入PSCH:PSC中,周而复始地循环下去。因此,TIMCLK就等于(TDDRH:TDDR+1)个系统时钟的时间。

假设主频为X Mhz而TIMCLK的计算为:

TIMCLK = (TDDRH:TDDR + 1)/ X * 0.000001

(3)对TIMCLK计数

在CPU定时器工作前,先要根据实际的需求,计算好CPU定时器周期寄存器的值,然后给周期寄存器PRDH:PRD赋值。当启动定时器开始计数时,周期寄存器PRDH:PRD里面的值装载进定时器计数寄存器TIMH:TIM中。

计数器寄存器TIMH:TIM里面的值每隔一个TIMCLK就减小1,直到计数到0,完成一个周期的计数,而CPU定时器这时候就会产生一个中断信号,完成一个周期的计数后,在下一个定时器输入时钟周期开始时,周期寄存器PRDH:PRD里面的值重新装载入计数器寄存器TIMH:TIM中,周而复始地循环下去。于是,一个CPU定时器周期所经历的时间就等于:

(PRDH:PRD+1)×TIMCLK

结合以上计数原理,最终定时器的定时时间T计算式为:

T = (PRDH:PRD+1) × (TDDRH:TDDR + 1)/ X * 0.000001

而实际应用时,通常是确定了要定时的时间T和CPU的系统时钟X,来确定周期寄存器PRDH:PRD的值。TDDRH:TDDR通常可以取为0,如果取0的时候,PRDH:PRD的值超过了32位寄存器的范围,那么TDDRH:TDDR可以取其他值,使得PRDH:PRD的值小一些,从而能放到32位寄存器中。

此处注意:
在实际的定时使用中,通常不直接写入PRD和TDDR,而是通过调用库函数ConfigCpuTimer,定义:

voidConfigCpuTimer(structCPUTIMER_VARS*Timer,floatFreq,floatPeriod){Uint32 temp;//Initializetimerperiod:Timer->CPUFreqInMHz=Freq;Timer->PeriodInUSec=Period;temp=(long)(Freq*Period);Timer->RegsAddr->PRD.all=temp;//Setpre-scalecountertodivideby1(SYSCLKOUT):Timer->RegsAddr->TPR.all =0;Timer->RegsAddr->TPRH.all =0;//Initializetimercontrolregister:Timer->RegsAddr->TCR.bit.TSS = 1; // 1 = Stop timer, 0 =Start/RestartTimerTimer->RegsAddr->TCR.bit.TRB=1; //1=reloadtimerTimer->RegsAddr->TCR.bit.SOFT=0;Timer->RegsAddr->TCR.bit.FREE=0; //TimerFreeRunDisabledTimer->RegsAddr->TCR.bit.TIE=1; //0=Disable/1=EnableTimerInterrupt//Resetinterruptcounter:Timer->InterruptCount=0;}

可以看到: Timer->RegsAddr->PRD.all=temp;
而 temp=(long)(FreqPeriod);;即PRD为该函数第二第三参数乘积,而 Timer->RegsAddr->TPR.all =0;说明将TDDR取为0,则根据定时公式:
T = (PRDH:PRD+1) × (TDDRH:TDDR + 1)/ X * 0.000001
T = Freq
Period / X * 0.000001,若Freq为主频,单位为MHz,则:

T = Period * 0.000001
即 参数Period 为定时周期乘以0.000001
而 T 的单位是秒S,则Period 单位为微秒us

2.定时器寄存器介绍

定时器配置和控制的寄存器如下:
在这里插入图片描述

(1)定时器控制寄存器TIMERxTCR

在这里插入图片描述
在这里插入图片描述

(2)定时器预定标寄存器PSC

在这里插入图片描述

(3)定时器计数器TIM

在这里插入图片描述

(4)定时器周期寄存器TRD

在这里插入图片描述

二、定时器中断软件实现

1.定时器中断配置步骤

(1)使能定时器时钟

 EALLOW;SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK=1;//CPUTimer0EDIS;

(2)初始化定时器参数
包括制定定时器寄存器地址、周期寄存器值、预定标计数器值等。
要使用F28335的CPU定时器,还需要对其内部相关寄存器的设置,具体设置代码如下:

//指向定时器0的寄存器地址
CpuTimer0.RegsAddr=&CpuTimer0Regs;//设置定时器0的周期寄存器值
CpuTimer0Regs.PRD.all =0xFFFFFFFF;//设置定时器预定标计数器值为0CpuTimer0Regs.TPR.all =0;CpuTimer0Regs.TPRH.all=0;//确保定时器0为停止状态
CpuTimer0Regs.TCR.bit.TSS=1;//重载使能
CpuTimer0Regs.TCR.bit.TRB=1;//Resetinterruptcounters:CpuTimer0.InterruptCount=0;

(3)定时器的设置
要使用定时器还需要设置它的定时周期以及设置定时器的控制寄存器等.这一步通过TI封装好的函数直接配置。

 voidConfigCpuTimer(structCPUTIMER_VARS*Timer,floatFreq,float Period)

该函数有3个参数,第1个表示哪个定时器,第2个表示定时器频率,第3个表示定时器周期值。
(4)设置定时器0的中断入口地址

//设置定时器0的中断入口地址为中断向量表的INT0EALLOW;PieVectTable.TINT0=&TIM0_IRQn;//中断服务函数名EDIS;

(5)开启定时器中断功能,并使能定时器

CpuTimer0Regs.TCR.bit.TSS=0;	 //开始定时器功能PieCtrlRegs.PIEIER1.bit.INTx7=1;//PIE级中断使能,第一组中断的第7个小中断,即定时器0//使能CPU总中断
IER|=M_INT1;
EINT;
ERTM;

(6)编写定时器中断服务函数
中断服务函数用于产生中断后的操作,注意要在编写中断服务函数时需要在函数名前面加上一个关键字“interrupt”

interruptvoidTIM0_IRQn(void){......功能程序
}

2.定时器中断实验

效果:用定时器0控制LED1灯按照一秒翻转电平闪烁
代码:
中断代码:

#include "Interrupt.h"
#include "led.h"interrupt void TIM0_IRQn(void)
{EALLOW;GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;PieCtrlRegs.PIEACK.bit.ACK1=1;EDIS;
}void Tim0_Init(float Freq, float Period)
{//1.时钟初始化EALLOW;SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;EDIS;//2.初始化定时器参数CpuTimer0.RegsAddr=&CpuTimer0Regs;//指向定时器0的寄存器地址CpuTimer0Regs.PRD.all =0xFFFFFFFF; //设置定时器0的周期寄存器值CpuTimer0Regs.TPR.all =0;//设置定时器预定标计数器值为0CpuTimer0Regs.TPRH.all=0;CpuTimer0Regs.TCR.bit.TSS=1; //确保定时器0为停止状态CpuTimer0Regs.TCR.bit.TRB=1; //重载使能CpuTimer0.InterruptCount=0; //Resetinterruptcounters://3.定时器定时周期以及设置定时器的控制寄存器等ConfigCpuTimer(&CpuTimer0,Freq,Period);//4.设置定时器0的中断入口地址为中断向量表的INT0EALLOW;PieVectTable.TINT0=&TIM0_IRQn;EDIS;//5.开启定时器中断功能,并使能定时器CpuTimer0Regs.TCR.bit.TSS=0;	 //开始定时器功能PieCtrlRegs.PIEIER1.bit.INTx7=1;//PIE级中断使能,第一组中断的第7个小中断,即定时器0//使能CPU总中断IER|=M_INT1;EINT;ERTM;
}

主函数:

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "beep.h"
#include "Key.h"
#include "led.h"
#include "Interrupt.h"void main()
{InitSysCtrl();InitPieCtrl();IER=0x0000;IFR=0x0000;InitPieVectTable();Led_Init();Tim0_Init(150,100000);while(1){GpioDataRegs.GPCCLEAR.bit.GPIO64=1;}
}
http://www.dtcms.com/a/461184.html

相关文章:

  • 阳春新农村建设网站中铁建设集团有限公司西北分公司
  • 简化OffSec考试报告编写:OSCP-Exam-Report-Template-Markdown项目详解
  • 北京网站设计制作过程数据服务网站开发
  • Go基础:一文掌握Go语言网络编程
  • TENGJUN-3.5MM耳机插座(JA06-BPF032-A):反向沉板结构下的4极音频连接解决方案
  • 使用IOT-Tree接入各种设备转OPC UA Server输出
  • 【大模型实战篇】从Python函数到MCP服务器:完整转换示例
  • 怎样增加网站的权重小企业做网站有用吗
  • 【ArkTS-通用事件】
  • 为什么要放弃用Docker?
  • 东方仙盟修仙(五)赛博科技修仙养老是一种爱好
  • 大模型训练过程中主动学习和课程学习的全面对比
  • Redis数据库隔离业务缓存对查询性能的影响分析
  • Mapper接口的解析
  • 网站中链接怎么做的广东网站建设案例
  • 网站开发部门结构公司做网站的费用属于什么费用
  • 做电影方面的网站怎么做外贸免费平台
  • transformers音频实战02-基于 Speech Commands 数据集的语音识别实战项目全流程
  • 天津做网站美工锦州网站建设信息
  • Terraform + RustFS 实战:10分钟实现对象存储 IaC 化,运维效率提升300%
  • 遇到RabbitMQ 的 `channel_max` 限制报错
  • 机器学习实战项目:Python+Flask 汽车销量分析可视化系统(requests爬车主之家+可视化 源码+文档)✅
  • 惠州城乡建设部网站印刷包装公司网站模板
  • WEB前端 JavaScript 学习笔记
  • 如何使用Python实现LRU缓存
  • OSCP渗透实战(第二期):Linux系统攻防与权限提升完全指南
  • LeetCode 118. 杨辉三角
  • AI原生应用架构白皮书 - AI原生应用架构及其关键要素
  • 蓝绿发布与金丝雀发布策略简介_笔记
  • 流媒体视频技术在明厨亮灶场景中的深度应用