2024-09-08
单片机
00

目录

深入了解 PIC16F1719 的 Timer2:配置与应用
Timer2 简介
Timer2 的主要特性
Timer2 的配置
中断服务例程(ISR)
常见问题及解决方案
全部代码
总结

深入了解 PIC16F1719 的 Timer2:配置与应用

在嵌入式系统中,定时器(Timer)是一种极其重要的外设,用于实现延时、计数和事件调度。本文将深入探讨 PIC16F1719 微控制器中的 Timer2,涵盖其配置方法、应用实例以及常见问题的解决方案。

Timer2 简介

Timer2 是一个 8 位的定时器,与其他定时器相比,它具有一些独特的特性。它可以通过外部晶振(通常是内部时钟源)产生精确的时间延迟,广泛用于生成PWM信号和定时中断。

Timer2 的主要特性

  1. 8 位计数器:Timer2 是一个 8 位定时器,计数范围从 0 到 255。
  2. 可编程预分频器:Timer2 具有 4 种预分频选项(1:1, 1:4, 1:16),可通过 T2CKPS 位配置。
  3. 后分频器:通过 4 位后分频器(0:1 到 15:1),可以进一步细化定时精度。
  4. 周期寄存器:PR2 寄存器定义了 Timer2 的计数周期。

Timer2 的配置

在 PIC16F1719 中配置 Timer2 包括设置预分频器、周期寄存器和后分频器。下面的代码展示了如何配置 Timer2:

c
// 设置预分频器为 16 T2CONbits.T2CKPS = 0b10; // 设置周期寄存器 PR2 为 255 PR2 = 255; // 设置 Timer2 初始值为 0 TMR2 = 0; // 设置后分频器为 15 T2CONbits.T2OUTPS = 0b1110; // 启动 Timer2 T2CONbits.TMR2ON = 1; // 启用 Timer2 中断 PIE1bits.TMR2IE = 1; // 启用外设中断 INTCONbits.PEIE = 1; INTCONbits.GIE = 1;

中断服务例程(ISR)

在使用 Timer2 时,我们通常需要利用其产生的中断来执行周期性任务。中断服务例程(ISR)是处理这些定时中断的地方。以下是一个简单的 ISR 示例,它每秒钟切换 LED 状态:

c
void __interrupt() isr(void){ static unsigned char count = 0; if (PIR1bits.TMR2IF) { PIR1bits.TMR2IF = 0; // 清除 Timer2 中断标志位 count++; if (count >= 122) { // 调整计数值以匹配所需的时间间隔 count = 0; LATDbits.LATD1 ^= 1; // 切换 LED 状态 } } }

常见问题及解决方案

  1. LED 不闪烁:如果你的 LED 不闪烁,首先检查 Timer2 的配置是否正确。确认预分频器和后分频器的设置符合需求,同时确保中断服务例程能够正确处理 Timer2 中断。

  2. 中断未触发:确保 Timer2 中断已启用,且全局和外设中断已开启。检查 PIE1bits.TMR2IEINTCONbits.GIE 的设置是否正确。

  3. 计数器周期不符:调整 PR2 寄存器和后分频器值,确保 Timer2 的周期与实际需求相符。通过计算公式验证设置是否符合预期。

全部代码

c
/* PIC16F1719 配置位设置 */ #pragma config FOSC = INTOSC /* 振荡器选择位 (INTOSC 振荡器: CLKIN 引脚上的 I/O 功能) */ #pragma config WDTE = OFF /* 看门狗定时器使能 (WDT 禁用) */ #pragma config PWRTE = OFF /* 上电定时器使能 (PWRT 禁用) */ #pragma config MCLRE = ON /* MCLR 引脚功能选择 (MCLR/VPP 引脚功能为 MCLR) */ #pragma config CP = OFF /* 闪存程序存储器代码保护 (程序存储器代码保护禁用) */ #pragma config BOREN = OFF /* 低电压复位使能 (低电压复位禁用) */ #pragma config CLKOUTEN = OFF /* 时钟输出使能 (CLKOUT 功能禁用。CLKOUT 引脚上的 I/O 或振荡器功能) */ #pragma config IESO = ON /* 内外部切换模式 (内外部切换模式使能) */ #pragma config FCMEN = ON /* 故障安全时钟监控器使能 (故障安全时钟监控器使能) */ #pragma config WRT = OFF /* 闪存自写保护 (写保护关闭) */ #pragma config PPS1WAY = OFF /* 外设引脚选择单向控制 (PPSLOCK 位可以通过软件反复设置和清除) */ #pragma config ZCDDIS = ON /* 零交叉检测禁用 (ZCD 禁用。ZCD 可以通过设置 ZCDCON 的 ZCDSEN 位来启用) */ #pragma config PLLEN = ON /* 锁相环使能 (4x PLL 使能) */ #pragma config STVREN = ON /* 栈溢出/下溢复位使能 (栈溢出或下溢将导致复位) */ #pragma config BORV = LO /* 低电压复位电压选择 (低电压复位电压 (Vbor),选择低触发点。) */ #pragma config LPBOR = OFF /* 低功率低电压复位 (低功率低电压复位禁用) */ #pragma config LVP = ON /* 低电压编程使能 (低电压编程使能) */ /* 定义系统振荡器频率 */ #define _XTAL_FREQ (32000000ul) #include <xc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> //counter variable int count = 0; void main(void) { unsigned char index = 0; /* 程序初始化设置 */ OSCCON = 0xF0; /* 设置 INTOSC 为 8MHz,并使用 4xPLL,使系统振荡器达到 32MHz */ INTCON = 0; /* 禁用所有中断源 */ PIE1 = 0; PIE2 = 0; PIE3 = 0; // Allow PLL startup time ~2 ms __delay_ms(10); ANSELA = 0x00; // 将所有A端口引脚设置为数字模式 ANSELB = 0x00; // 将所有B端口引脚设置为数字模式 ANSELC = 0x00; // 将所有C端口引脚设置为数字模式 // Set PIN D1 as output TRISDbits.TRISD1 = 0; // Turn off LED LATDbits.LATD1 = 0; // Setup PORTD TRISD = 0; ANSELD = 0; ///////////////////// // Configure Timer2 ///////////////////// // prescale = 16 T2CONbits.T2CKPS = 0b10; // Set period to 255 PR2 = 255; // Set TMR2 to 0 TMR2 = 0; // postscale = 15 T2CONbits.T2OUTPS = 0b1110; // enable timer2 T2CONbits.TMR2ON = 1; // enable timer2 interrupt PIE1bits.TMR2IE = 1; // enable peripheral interrupt INTCONbits.PEIE = 1; INTCONbits.GIE = 1; // 使能全局中断 while (1) { // Main loop does nothing, all action in ISR } } void __interrupt() isr(void){ static unsigned char count = 0; if (PIR1bits.TMR2IF) { PIR1bits.TMR2IF = 0; // 清除 Timer2 中断标志位 count++; if (count >= 122) { // Adjust this count based on your desired period count = 0; LATDbits.LATD1 ^= 1; // Toggle LED state } } }

总结

Timer2 是 PIC16F1719 微控制器中功能强大的定时器之一,通过适当配置,可以用于生成精确的时间延迟和周期性任务。在配置 Timer2 时,需要确保所有相关寄存器和位设置正确无误。通过上述示例和解决方案,你可以轻松地实现 Timer2 的配置和应用。

希望这篇博客能帮助你更好地理解和使用 Timer2。如果你有更多问题或需要进一步的帮助,欢迎随时交流!

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!