使用PIC16F887定时器完成跑马灯流程。闪烁规则:从上往下逐个点亮,从下往上逐个 熄灭,上下逐个往中间点亮,从中间往外围熄灭。K1 断开跑马灯全部熄灭。每个灯点亮或熄灭间隔 1s,要求分别用 TMR1 实现定时,通过中
时间: 2024-04-30 13:22:50 浏览: 6
断处理函数控制灯的状态。
首先,需要设置 PIC16F887 的定时器 TMR1 的计数时间和计数器的初始化值。假设使用内部时钟源,频率为 8MHz,计数时间为 1s,则需要将计数器的初始化值设为 65535-8000000/4=49151。具体实现代码如下:
```c
#include <xc.h>
#define _XTAL_FREQ 8000000 // 内部时钟源频率为 8MHz
void init_timer1() {
T1CONbits.TMR1CS = 0; // 使用内部时钟源
T1CONbits.T1CKPS = 0b11; // 1:8 预分频器,计数时间为 1s
TMR1 = 49151; // 初始化计数器
PIR1bits.TMR1IF = 0; // 清除 TMR1 中断标志位
PIE1bits.TMR1IE = 1; // 使能 TMR1 中断
T1CONbits.TMR1ON = 1; // 启动 TMR1
}
void interrupt isr() {
if (PIR1bits.TMR1IF) { // TMR1 中断
// TODO: 控制灯的状态
TMR1 = 49151; // 重新初始化计数器
PIR1bits.TMR1IF = 0; // 清除 TMR1 中断标志位
}
}
int main() {
init_timer1();
// TODO: 初始化 I/O 端口和其他相关设置
while (1) {
// TODO: 主循环
}
return 0;
}
```
接下来,需要在中断处理函数中控制灯的状态。首先,需要定义一个全局变量 `led_state` 表示当前灯的状态,取值为 0~7,分别表示从上往下 1~4 灯、从下往上 1~4 灯、从中间往外围 1~2 灯。然后,可以根据当前的 `led_state` 值来控制灯的状态。具体实现代码如下:
```c
volatile unsigned char led_state = 0; // 当前灯的状态
void interrupt isr() {
if (PIR1bits.TMR1IF) { // TMR1 中断
switch (led_state) {
case 0: // 从上往下逐个点亮
// TODO: 点亮第 1 个灯
led_state = 1;
break;
case 1: // 从上往下逐个点亮
// TODO: 点亮第 2 个灯
led_state = 2;
break;
case 2: // 从上往下逐个点亮
// TODO: 点亮第 3 个灯
led_state = 3;
break;
case 3: // 从上往下逐个点亮
// TODO: 点亮第 4 个灯
led_state = 4;
break;
case 4: // 从下往上逐个熄灭
// TODO: 熄灭第 4 个灯
led_state = 5;
break;
case 5: // 从下往上逐个熄灭
// TODO: 熄灭第 3 个灯
led_state = 6;
break;
case 6: // 从下往上逐个熄灭
// TODO: 熄灭第 2 个灯
led_state = 7;
break;
case 7: // 从下往上逐个熄灭
// TODO: 熄灭第 1 个灯
led_state = 8;
break;
case 8: // 上下逐个往中间点亮
// TODO: 点亮第 2 个灯
led_state = 9;
break;
case 9: // 上下逐个往中间点亮
// TODO: 点亮第 3 个灯
led_state = 10;
break;
case 10: // 从中间往外围熄灭
// TODO: 熄灭第 2 个灯
led_state = 11;
break;
case 11: // 从中间往外围熄灭
// TODO: 熄灭第 3 个灯
led_state = 12;
break;
case 12: // 从中间往外围熄灭
// TODO: 熄灭第 1 个灯
led_state = 13;
break;
case 13: // 从中间往外围熄灭
// TODO: 熄灭第 4 个灯
led_state = 0;
break;
}
TMR1 = 49151; // 重新初始化计数器
PIR1bits.TMR1IF = 0; // 清除 TMR1 中断标志位
}
}
```
最后,需要在主循环中检测 K1 的状态,如果 K1 被按下,则将 `led_state` 的值设为 0,即全部熄灭。具体实现代码如下:
```c
int main() {
init_timer1();
// TODO: 初始化 I/O 端口和其他相关设置
while (1) {
if (PORTBbits.RB0 == 0) { // K1 被按下
led_state = 0; // 全部熄灭
}
}
return 0;
}
```