使用PIC16F887定时器完成跑马灯流程。闪烁规则:从上往下逐个点亮,从下往上逐个 熄灭,上下逐个往中间点亮,从中间往外围熄灭。K1 断开跑马灯全部熄灭。每个灯点亮或熄灭间隔 1s,要求分别用 TMR1 实现定时,通过中
时间: 2024-05-03 22:22:19 浏览: 88
单片机定时器实现灯的闪烁功能
断函数实现跑马灯流程。
首先,需要配置定时器 TMR1。将 TMR1 的时钟源设置为内部时钟,预分频器为 1,使得 TMR1 的时钟频率为系统时钟频率。同时,设置 TMR1 的计数器上限为 65535,以确保可以计数足够长的时间。
```c
T1CONbits.TMR1CS = 0b00; // 时钟源为内部时钟
T1CONbits.T1CKPS = 0b00; // 预分频器为 1
T1CONbits.TMR1ON = 1; // 启动 TMR1
TMR1H = 0xFF; // 计数器上限为 65535
TMR1L = 0xFF;
```
接下来,需要在中断函数中实现跑马灯的流程。首先需要定义一个全局变量 `led_index`,用于记录当前点亮的 LED 灯编号。然后,在 `TMR1` 中断函数中,根据 `led_index` 的值进行相应的操作。
```c
int led_index = 0; // 当前点亮的 LED 灯编号
void __interrupt() isr() {
if (TMR1IF) { // TMR1 中断
TMR1IF = 0; // 清除中断标志
if (led_index == 0) { // 从上往下逐个点亮
LATC = 1 << led_index;
led_index++;
} else if (led_index < 7) { // 上下逐个往中间点亮
LATC = (1 << led_index) | (1 << (14 - led_index));
led_index++;
} else if (led_index == 7) { // 中间点亮
LATC = 0b01111110;
led_index++;
} else if (led_index < 14) { // 从下往上逐个熄灭
LATC = (1 << led_index) | (1 << (14 - led_index));
led_index++;
} else { // 停止跑马灯
TMR1ON = 0;
}
}
}
```
最后,需要在 `main` 函数中启用 `TMR1` 中断,并等待 `K1` 按钮按下停止跑马灯。
```c
void main() {
// 配置 IO 口为输出模式
TRISC = 0x00;
// 启用 TMR1 中断
PEIE = 1; // 使能外设中断
TMR1IE = 1; // 使能 TMR1 中断
// 等待 K1 按钮按下
while (PORTBbits.RB0 == 1) {
// 等待
}
// 等待 K1 按钮释放
while (PORTBbits.RB0 == 0) {
// 等待
}
// 启动 TMR1 定时器
TMR1ON = 1;
// 主循环
while (1) {
// 等待中断
}
}
```
完整代码如下:
```c
#include <xc.h>
// 配置 PIC16F887 的配置字
#pragma config FOSC = EXTRCCLK // 内部 RC 振荡器作为时钟源
#pragma config WDTEN = OFF // 禁用看门狗定时器
#pragma config LVP = OFF // 禁止低电压编程模式
int led_index = 0; // 当前点亮的 LED 灯编号
void __interrupt() isr() {
if (TMR1IF) { // TMR1 中断
TMR1IF = 0; // 清除中断标志
if (led_index == 0) { // 从上往下逐个点亮
LATC = 1 << led_index;
led_index++;
} else if (led_index < 7) { // 上下逐个往中间点亮
LATC = (1 << led_index) | (1 << (14 - led_index));
led_index++;
} else if (led_index == 7) { // 中间点亮
LATC = 0b01111110;
led_index++;
} else if (led_index < 14) { // 从下往上逐个熄灭
LATC = (1 << led_index) | (1 << (14 - led_index));
led_index++;
} else { // 停止跑马灯
TMR1ON = 0;
}
}
}
void main() {
// 配置 IO 口为输出模式
TRISC = 0x00;
// 启用 TMR1 中断
PEIE = 1; // 使能外设中断
TMR1IE = 1; // 使能 TMR1 中断
// 等待 K1 按钮按下
while (PORTBbits.RB0 == 1) {
// 等待
}
// 等待 K1 按钮释放
while (PORTBbits.RB0 == 0) {
// 等待
}
// 启动 TMR1 定时器
TMR1ON = 1;
// 主循环
while (1) {
// 等待中断
}
}
```
阅读全文