📄 timer.c
字号:
/****************************************Copyright (c)**************************************************/
/**
;** 西南科技大学计算机科学学院
;**
;** http://www.cs.suswt.edu.cn
;**
;** 日期:
;** 描述:
;** 作者:
;**
;**--------------*.*文件
;**------------------------------------------------------------------------------------------------------*/
/**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define _TIMER_C_
#ifdef _TIMER_C_
/************************************************
* Header File *
***********************************************/
#include"config.h"
#include"sounder.h"
#include"led.h"
/************************************************
* Globale variable *
***********************************************/
uint32 div0 = 0;
uint32 div1 = 0;
uint32 overflow = 0;
/*
TCR 定时控制寄存器,控制定时计数器(禁止或复位,是否启用) 1启用0禁止
TC 定时器计数器 32位计数器,计数频率为pclk经过预分频计数器后频率值。(选择做定时器还是计数器,0定时器,1计数器)
PR 预分频控制寄存器 用于设定分频值,32位寄存器,pclk/3相当于3个脉冲时间产生一个上升沿 计数时钟频率=Fpclk/(N+1)
PC 预分频计数器 32位计数器,计数频率为pclk,当计数值等于预分频计数器的值时,TC计数器加一
IR 中断标志寄存器 读该寄存器识别中断源,写该寄存器清除中断标志
MCR 匹配控制寄存器 用于控制在匹配时是否产生中断或复位TC
位 功能
0 中断(MR0) 为1时,MR0与TC值的匹配将产生中断
1 复位(MR0) 为1时,MR0与TC值的匹配将使TC复位
2 停止(MR0) 为1时,MR0与TC值的匹配将清零TCR的bit0位,使TC和PC停止
5:3 MR1
8:6 MR2 与上对应相同
9:11 MR3
MR n 匹配寄存器n,通过MCR寄存器可以设置匹配发生时的动作
EMR 外部匹配寄存器 EMR控制外部匹配管脚MATx.0~MATx.3
CCR 捕获控制寄存器,用于设置捕获信号的触发特征(下降沿捕获还是上升沿),以及捕获发生时是否产生中断
CRn(1~3) 捕获寄存器n,在捕获n引脚上产生捕获时间时,CRn装载TC的值
*/
/*
中断输入可以在VIC被设置成三类
1、FIQ中断 :具有最高优先级
2、向量IRQ中断 : 具有中等优先级 VIC最多支持16个向量IRQ中断,这些中断被分为16个优先级,每个优先级有一个中断服务地址
3、非向量IRQ中断 : 具有最低优先级 所有的非向量IRQ中断共用一个中断服务地址
VICIntEnable 中断使能寄存器32位,每一位控制一个中断源,向某一位写入1,允许该中断源产生中断
VICIntClr 中断使能清零寄存器,与VICIntEnable相反,写入1,相应位中断源禁止中断
VICIntSelect 中断选择寄存器 向某位写1,对应中断源产生FIQ中断,否则产生IRQ中断 其中断相应延时相应较长
VICVectCntl 中断向量控制寄存器 为中断源分配向量IRQ的优先级 ,VICVectCntl n,n值越小优先级越高,0<=n<=15
VICVectCntl 位 7 6 5 4 3 2 1 0
功能 - - En 【 中断源序号 】
VICVectAddr 向量地址寄存器 为该中断优先级设置服务程序入口地址
VICRawIntr 中断状态寄存器 32寄存器,当某位为1时,对应位中断源产生中断请求
VICFIQStatus FIQ状态寄存器 32寄存器,当某位为1时,对应位中断源产生FIQ中断请求
VICIRQStatus IRQ状态寄存器 32寄存器,当某位为1时,对应位中断源产生IRQ中断请求
VICSoftInt 软件中断寄存器 32寄存器,当某位为1时,对应位中断源产生相应中断请求
VICSoftIntClear 软件中断清零寄存器 当某位为1时,将清零VICSoftInt对应位
软件使能寄存器
VICSoftInt 位 31~1 0
功能 - 该位为1时只有在特权模式下访问VIC寄存器
中断初始化步骤:
1、设置中断类型 VICIntSelect
2、设置中断优先级 VICVectCnt
3、将中断服务程序写入相应中断优先级的中断服务程序地址 VICVectAddrn = (int)IRQ_Timer0Interrupt
4、使能外部中断 VICIntEnable
定时器初始化步骤:
1、计数定时器计数频率 T0PR = ?
2、设置匹配值及工作模式
3、设置捕获方式
4、设置定时器中断VIC
5、启动定时器 TCR
中断类型号 中断类型号
0 WDT(Watchdog Interrupt) 10 SPI0
1 - 11 SPI1
2 ARM Core 12 PLL
3 ARM Core 13 RTC
4 TIMER0 14 System Control(External Interrupt0(EINT0))
5 TIMER1 15 System Control(External Interrupt1(EINT1)
6 UART0 16 System Control(External Interrupt2(EINT2)
7 UART1 17 System Control(External Interrupt3(EINT3)
8 PWM0 (Match 0-6(MR0-6)) 18 A/D
*/
#define TIMER0_ENABLE
#ifdef TIMER0_ENABLE
/*******************************************************************************
Function Name:void __irq IRQ_Timer0(void) *
Description : Timer0的中断服务函数,需要利用Timer0进行中断的程序都可以放在这个*
函数中 *
ads1.2 规定,在定义中断服务函数时,必须加入关键字__irq保证函数返*
回时会切换处理器模式 *
需要注意的是:注意在退出中断服务程序时,要清零相应外设的中断标志*
以及VICVectAddr,为响应下一次中断做好准备 *
*******************************************************************************/
uint8 sounder_flag = TRUE;
void __irq IRQTimer0(void)
{
if(sounder_flag)
{
SOUNDEROn();
sounder_flag = FALSE;
}
else
{
SOUNDEROff();
sounder_flag = TRUE;
}
/* 上面添加需要定时器中断的代码*/
T0IR=0X01; //清除中断
VICSoftIntClear=0x00000010;
VICVectAddr=0x00; //清除地址
}
/*******************************************************************************
Function Name: void Timer0_InterruptSet(void) *
Function Description :对中断向量的设置,包括中断类型,中断优先级,中断服务地址 *
中断使能。 *
*******************************************************************************/
void TIMER0InterruptSet(void)
{
VICIntSelect &= 0xffffffef; //第4、5位分别代表定时计数器0、1 设置中断类型
VICVectCntl0 = 0x24; //为中断源分配向量IRQ的优先级 ,VICVectCntl n,n值越小优先级越高,0<=n<=15
//0010 0100 中断源序号为4 代表计数器0中断
VICVectAddr0 = (int)IRQTimer0; //向量地址寄存器 为该中断优先级设置服务程序入口地址
VICIntEnable = 0x00000010; //中断使能 允许相应中断源产生中断
}
/*******************************************************************************
Function Name: void Timer0_Init(void) *
Description : 定时器计数器0初始化设置,包括预分频值,匹配模式,启动复位等。 * *
*******************************************************************************/
void TIMER0Init(void) //另外一种写法 void Timer1_Init(uint32 Div,uint32 Ovf)
{
T0TC = 0;
T0PR = div0; //设置预分频值 定时器计数时钟频率 Fpclk/(PR+1)
T0MCR = 0x03; //设置匹配模式 匹配后复位T0TC,并产生中断标志
T0MR0 = Fpclk; //设置匹配值 可以理解为计数器益出值 设置1ms匹配值
T0TCR = 0x03; //启动并复位
TIMER0InterruptSet();
}
/*******************************************************************************
Function Name: void Timer0_Start(void) *
Function Description : 定时器计数器0启动 *
*******************************************************************************/
void TIMER0Start(void)
{
T0TCR = 0x01; //定时器使能,相当与定时计数器的开关
}
#endif
//#define TIMER1_ENABLE
#ifdef TIMER1_ENABLE
/*******************************************************************************
Function Name:void __irq IRQ_Timer1(void) *
Description : Timer1的中断服务函数,需要利用Timer1进行中断的程序都可以放在这个*
函数中 *
ads1.2 规定,在定义中断服务函数时,必须加入关键字__irq保证函数返*
回时会切换处理器模式 *
需要注意的是:注意在退出中断服务程序时,要清零相应外设的中断标志*
以及VICVectAddr,为响应下一次中断做好准备 *
*******************************************************************************/
void __irq IRQTimer1(void)
{
/* 上面添加需要定时器中断的代码*/
T1IR=0X01; //清除中断
VICSoftIntClear=0x00000010;
VICVectAddr=0x00; //清除地址
}
/*******************************************************************************
Function Name: void Timer1_InterruptSet(void) *
Function Description :对中断向量的设置,包括中断类型,中断优先级,中断服务地址 *
中断使能。 *
*******************************************************************************/
void TIMER1InterruptSet(void)
{
VICIntSelect &= 0xffffffdf; //第4、5位分别代表定时计数器0、1 设置中断类型
VICVectCntl0 = 0x25; //为中断源分配向量IRQ的优先级 ,VICVectCntl n,n值越小优先级越高,0<=n<=15
//0010 0100 中断源序号为4 代表计数器0中断
VICVectAddr0 = (int)IRQTimer1; //向量地址寄存器 为该中断优先级设置服务程序入口地址
VICIntEnable = 0x00000020; //中断使能 允许相应中断源产生中断
}
/*******************************************************************************
Function Name: void Timer1_Init(void) *
Description : 定时器计数器1初始化设置,包括预分频值,匹配模式,启动复位等。 * *
*******************************************************************************/
void TIMER1Init(void) //另外一种写法 void Timer1_Init(uint32 Div,uint32 Ovf)
{
T1TC = 0;
T1PR = div1; //设置预分频值 定时器计数时钟频率 Fpclk/(PR+1)
T1MCR = 0x03; //设置匹配模式 匹配后复位T0TC,并产生中断标志
T1MR0 = Fpclk/1000; //设置匹配值 可以理解为计数器益出值 设置1ms匹配值
T1TCR = 0x03; //启动并复位
TIMER1InterruptSet();
}
/*******************************************************************************
Function Name: void Timer0_Start(void) *
Function Description : 定时器计数器0启动 *
*******************************************************************************/
void TIMER1Start(void)
{
T1TCR = 0x01; //定时器使能,相当与定时计数器的开关
}
#endif
#endif
/*****************************************************************************
* End of Entire File *
****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -