五、扩展定时器ET
先上代码,后解释重点:
1、初始化定时器:【其实就是官方例程中的代码】
void Test_Etimx(ETIMx_Type* ETIMx)
{
ETIM_InitTypeDef init_para;
volatile uint08 EtimNum;
EtimNum = ((uint32_t)ETIMx - ETIMER1_BASE)>>5;
//信号源参数
init_para.sig_src_para.SIG1SEL = ETIMx_ETxINSEL_SIG1SEL_GROUP1; /* 内部信号1源选择GROUP1 */
switch(EtimNum)
{
case 0:
//信号源参数
init_para.sig_src_para.GRP1SEL = ETIMx_ETxINSEL_GRP1SEL_ET1_APBCLK; /* GROUP1 信号选择APBCLK */
//ET1时钟使能
RCC_PERCLK_SetableEx( ET1CLK, ENABLE );
//NVIC中断配置
NVIC_DisableIRQ(ETIM1_IRQn);
NVIC_SetPriority(ETIM1_IRQn,2);//中断优先级配置
NVIC_EnableIRQ(ETIM1_IRQn);
break;
case 1:
//信号源参数
init_para.sig_src_para.GRP1SEL = ETIMx_ETxINSEL_GRP1SEL_ET2_APBCLK; /* GROUP1 信号选择APBCLK */
//ET2时钟使能
RCC_PERCLK_SetableEx( ET2CLK, ENABLE );
//NVIC中断配置
NVIC_DisableIRQ(ETIM2_IRQn);
NVIC_SetPriority(ETIM2_IRQn,2);//中断优先级配置
NVIC_EnableIRQ(ETIM2_IRQn);
break;
case 2:
//信号源参数
init_para.sig_src_para.GRP1SEL = ETIMx_ETxINSEL_GRP1SEL_ET3_APBCLK; /* GROUP1 信号选择APBCLK */
//ET3时钟使能
RCC_PERCLK_SetableEx( ET3CLK, ENABLE );
//NVIC中断配置
NVIC_DisableIRQ(ETIM3_IRQn);
NVIC_SetPriority(ETIM3_IRQn,2);//中断优先级配置
NVIC_EnableIRQ(ETIM3_IRQn);
break;
case 3:
init_para.sig_src_para.GRP1SEL = ETIMx_ETxINSEL_GRP1SEL_ET4_APBCLK; /* GROUP1 信号选择APBCLK */
//ET4时钟使能
RCC_PERCLK_SetableEx( ET4CLK, ENABLE );
//NVIC中断配置
NVIC_DisableIRQ(ETIM4_IRQn);
NVIC_SetPriority(ETIM4_IRQn,2);//中断优先级配置
NVIC_EnableIRQ(ETIM4_IRQn);
break;
default:
break;
}
init_para.sig_src_para.PRESCALE1 = clkmode - 1 + 99; //100分频 /* ETx预分频寄存器1 */ 00表示1分频,FF表示256分频
// init_para.sig_src_para.PRESCALE2 = clkmode - 1; //1分频 /* ETx预分频寄存器2 */ 00表示1分频,FF表示256分频
//控制类参数
init_para.ctrl_para.EXFLT = ENABLE; /* 引脚输入数字滤波使能打开 */
init_para.ctrl_para.MOD = ETIMx_ETxCR_MOD_COUNTER; /* 工作模式选择计数模式 */
init_para.ctrl_para.CASEN = DISABLE; /* 扩展定时器级联关闭 */ //定时器独立工作
init_para.ctrl_para.EDGESEL = ETIMx_ETxCR_EDGESEL_RISING; //上升沿 /* 计数模式采沿方式选择
init_para.ctrl_para.CAPCLR = DISABLE; /* 带清零捕捉模式控制 */ //捕捉不清0,计数器一直自由计数
init_para.ctrl_para.CMPIE = DISABLE; /* 扩展定时器比较中断使能 */
init_para.ctrl_para.CAPIE = DISABLE; /* 扩展定时器捕捉中断使能 */
init_para.ctrl_para.OVIE = ENABLE; /* 扩展定时器溢出中断使能 */
init_para.ctrl_para.INITVALUE = 0xffff - 8000;
init_para.ctrl_para.CEN = DISABLE; /* 启动控制 */
//初始化ETIM
ETIMx_Init(ETIMx, &init_para);
ETIMx_ETxCR_CEN_Setable(ETIMx, DISABLE); //停止定时器
//ETIMx_ETxCR_CEN_Setable(ETIMx, ENABLE); //启动定时器
// initmp=ETIMx_ETxIVR_Read(ETIM1); //获取 ET 计数初值
}
2、定时器中断:
void ETIM1_IRQHandler(void)
{
if(SET == ETIMx_ETxIF_OVIF_Chk(ETIM1))
{
ETIMx_ETxIF_OVIF_Clr(ETIM1);
++ETNum;
if(ETNum>39)
{
TimeOutFlag=1;
ETNum=0;
ETIMx_ETxCR_CEN_Setable(ETIM1, DISABLE); //停止定时器
// ETIMx_ETxIF_OVIF_Clr(ETIM1); //在这之前打断点时开启此条命令
}
else
{
TimeOutFlag=0;
}
}
}
3、说明:
在初始化函数中,需要关注的应该是分频器分频和计数初值,即init_para.sig_src_para.PRESCALE1 = clkmode - 1 + 99; 和 init_para.ctrl_para.INITVALUE = 0xffff - 8000;
这关系到,进入中断多少次表示多少时间。
拿上面的程序来看,如果主频是8M,现在设置100分频,即80000,表示的意思是计数一个周期的时间是1/80000,也就是说,计时1s需要计数80000个周期,这当然会溢出,因为最高也就是0xffff,这是因为复旦微开发板FM33G0系列,它是16位的定时器。
所以设置init_para.ctrl_para.INITVALUE = 0xffff - 8000; 这个初始值的意思是从该初始值开始,向上计数,直到0xffff溢出产生中断,然后自动重载初值。
也就是说是想每次进入中断的时候计数8000个周期,即耗时100ms,那想要表示1s计时,那就需要进入中断10次,即把中断函数里面的条件改成if(ETNum>9)即表示1s时间。
当然中断里面的计数变量可以根据你选择的频率,分频,和计数初值灵活设置。