请问怎么修改才能使灯跟着按钮闪烁,按第一次三个灯之间闪烁间隔维一秒,按第二次闪烁间隔为两秒,第三次为4秒,第四次又回到1秒。
注:按钮接线IN=PB4,VCC=VDD,GND=GND.灯的接线CND=CND,红灯R=PB2黄Y=PB1绿G=PB0
#include <ny8.h>
#include "ny8_constant.h"
#define UPDATE_REG(x) __asm__("MOVR _" #x ",F")
void delay(unsigned int t) {
unsigned int i, j;
for(i=0;i<t;i++)
for(j=0;j<125;j++);
}
void isr(void) __interrupt(1)
{
static unsigned int i;
static unsigned int a=0;
if(INTFbits.T1IF)
{
INTF= (unsigned char)~(C_INT_TMR1);
if(i>=500)
{
i=0;
if(a == 0)
{
PB0 =1; PB1 =0; PB2 =0;
a=a+1;
}
else if(a == 1)
{
PB0 =0; PB1 =1; PB2 =0;
a=a+1;
}
else if(a > 1)
{
PB0 =0; PB1 =0; PB2 =1;
a=0;
}
}
else{
i=i+1;
}
}
if(INTFbits.T0IF)
{
INTF= (unsigned char)~(C_INT_TMR0);
}
if(INTFbits.WDTIF)
{
INTF= (unsigned char)~(C_INT_WDT);
}
}
void main(void)
{
unsigned char R_shift_regl = 0xFF;
//;Initial GPIO
IOSTB = C_PB5_Input | C_PB4_Input | C_PB3_Input; // Set PB0 & PB1 to input mode,others set to output mode
PORTB = 0x07; // PB0、PB1 & PB2 are output High
DISI();
//;Initial Timer0
PCON1 = C_TMR0_Dis; // Disable Timer0
TMR0 = 0; // Load 0x00 to TMR0 (Initial Timer0 register)
T0MD = C_PS0_TMR0 | C_PS0_Div8 ; // Prescaler0 is assigned to Timer0, Prescaler0 dividing rate = 1:8,clock source is instruction clock
//;--Initial WDT (if WDT needs prescaler0 dividing rate )--------------------------------------------------
// T0MD = C_PS0_WDT // Prescaler0 is assigned to WDT, Prescaler0 dividing rate = 1:2 (WDT select interrupt)
//;--------------------------------------------------------------------------------------------------------
//;Initial Timer1
TMR1 = 0xFF; // Load 0xFF to TMR1 (Initial Timer1 register)
T1CR1 = C_TMR1_Reload | C_TMR1_En; // Enable Timer1, Initial value reloaded from TMR1, Non-stop mode
T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Div4; // Enable Prescaler1, Prescaler1 dividing rate = 1:4, Timer1 clock source is instruction clock
//;Setting Interrupt Enable Register
INTE = C_INT_WDT | C_INT_TMR1 | C_INT_TMR0; //
//;Initial Power control register
PCON = C_WDT_En | C_LVR_En; // Enable WDT , Enable LVR
//;Enable Timer0 & Global interrupt bit
PCON1 = C_TMR0_En; // Enable Timer0
ENI(); // Enable all unmasked interrupts
while(1);
}
}
if (buttonPressCount == 0) {
delay(1000); // 1秒延迟
} else if (buttonPressCount == 1) {
delay(2000); // 2秒延迟
} else if (buttonPressCount == 2) {
delay(4000); // 4秒延迟
} else if (buttonPressCount == 3) {
delay(1000); // 1秒延迟
}
【以下回答由 GPT 生成】
#include <ny8.h>
#include "ny8_constant.h"
#define UPDATE_REG(x) __asm__("MOVR _" #x ",F")
void delay(unsigned int t) {
unsigned int i, j;
for (i=0; i<t; i++) {
for (j=0; j<125; j++);
}
}
void isr(void) __interrupt(1) {
static unsigned int i;
static unsigned int a=0;
static unsigned int interval = 1000; // 初始间隔为1秒
if (INTFbits.T1IF) {
INTF = (unsigned char)~(C_INT_TMR1);
if (i >= interval/2) { // 间隔的一半时间打开灯
if (a == 0) {
PB0 = 1;
PB1 = 0;
PB2 = 0;
a = a + 1;
}
else if (a == 1) {
PB0 = 0;
PB1 = 1;
PB2 = 0;
a = a + 1;
}
else if (a > 1) {
PB0 = 0;
PB1 = 0;
PB2 = 1;
a = 0;
}
}
else {
i = i + 1;
}
if (i >= interval) { // 闪烁间隔时间到了
i = 0;
}
}
if (INTFbits.T0IF) {
INTF = (unsigned char)~(C_INT_TMR0);
}
if (INTFbits.WDTIF) {
INTF = (unsigned char)~(C_INT_WDT);
}
if (INTFbits.INTF) { // 检测按钮是否按下
INTFbits.INTF = 0;
interval *= 2; // 闪烁间隔翻倍
if (interval > 4000) { // 如果闪烁间隔超过4秒,则重置为1秒
interval = 1000;
}
}
}
解决方案解释:
首先,在代码中添加一个变量interval
来存储闪烁的间隔时间,初始化为1秒(1000毫秒)。
在isr
函数中,根据计时器i
的值来控制灯的亮灭。当i
的值大于等于interval/2
时,打开相应的灯。
在每次执行完闪烁逻辑后,判断i
的值是否大于等于interval
,如果是,则重置为0,达到循环闪烁的效果。
在isr
函数中,添加对按钮按下的检测。如果检测到按钮按下,则将interval
翻倍。如果interval
大于4000毫秒(4秒),则将其重置为1000毫秒。
注意事项:
由于代码中没有提供计时器的初始化和启动相关的代码,这部分功能需要根据具体的单片机型号和开发环境来实现。
请根据具体的硬件连接和单片机型号,确定按钮和灯的引脚定义是否正确,并在代码中进行相应的修改。
以上代码仅提供了逻辑的修改,具体的编译、下载和调试过程需要根据具体的开发环境和工具链来完成。