为啥某些按键按几次就不管用了 unsigned int i_S=0; // 标志位,用于判断输入是否合法 unsigned int j_S=0; // 标志位,用于判断是否需要更新坐标值 unsigned int TmpS; // 临时变量,用于存储6位数值 if (key_val >= KEY_0 && key_val <= KEY_9) { printf("%d\r\n",Freque); // 输入数字时,更新对应位置上的数值 Record.Olds = Record.Memory[Freque]; Record.Memory[Freque] = key_val - KEY_0; //将键值转换为数字 i_S = 0; j_S = 1; // 更新横坐标值 if (j_S == 1 ) { if(Freque<3){ TmpS = Record.Memory[0] * 100 + Record.Memory[1] * 10 + Record.Memory[2]; if (TmpS > 600) { i_S = 1; } else { Record.FactX = TmpS;}} if(Freque<6){ TmpS = Record.Memory[3] * 100 + Record.Memory[4] * 10 + Record.Memory[5]; if (TmpS > 600) { i_S = 1; } else { Record.FactY = TmpS;}}} // 输入不合法,恢复旧数值 if (i_S == 1) { Record.Memory[Freque] = Record.Olds;} else { // 输入合法,递推到下一位 Freque = (Freque < 6) ? (Freque + 1) : 0;} key_val = 0; }
时间: 2024-04-28 12:21:28 浏览: 14
这段代码中,按键按几次不管用的原因可能是因为输入的数字超出了合法范围,导致输入不合法,然后恢复了旧的数值,从而没有更新坐标值。具体来说,当输入数字时,首先会将对应位置上的数值更新为输入的数字,然后会判断输入是否合法,如果输入不合法,就会将对应位置上的数值恢复为旧的数值。如果输入合法,就会递推到下一位,继续输入。在判断输入是否合法的过程中,会将输入的6位数值拼接成横坐标和纵坐标,然后判断横坐标和纵坐标是否都小于等于600,如果有一个大于600,就认为输入不合法,将对应位置上的数值恢复为旧的数值。所以,如果输入的数字超出了合法范围,就会导致输入不合法,从而恢复旧数值,没有更新坐标值,看起来按键按几次不起作用。
相关问题
单片机,修改以下代码#include<reg52.h> unsigned char cols[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xE3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; unsigned char p_i =0;//p_i=0表示显示第一幅图像 void main(){ //定时器1和中断 TMOD = 0x10; TR1=1; TH1=0xfc; TL1=0x67; EA=1; ET1=1; while(1); } void interrupt_T1() interrupt 3{ static unsigned char row_i=0;//row_i=0表示选中点阵第一行 static unsigned int cnt=0;//cnt=1表示进过1ms,用于点阵行的切换 static unsigned int p_cnt=0;//p_cnt=1表示进过1ms,用于图像的切换 TH1=0xfc; TL1=0x67; P0 = 0xff;//消隐 cnt++; p_cnt++; if(cnt==1){ cnt=0; row_i++; if(row_i==8){ row_i =0; } } if(p_cnt==10){ p_cnt=0; p_i++; if(p_i==17){ p_i =0; } } switch(row_i){ case 0:P2 =0x01;P0 = cols[0+p_i];break; case 1:P2=0x02;P0 = cols[1+p_i];break; case 2:P2 =0x04;P0 = cols[2+p_i];break; case 3:P2=0x08;P0 = cols[3+p_i];break; case 4:P2 =0x10;P0 = cols[4+p_i];break; case 5:P2=0x20;P0 = cols[5+p_i];break; case 6:P2 =0x40;P0 = cols[6+p_i];break; case 7:P2=0x80;P0 = cols[7+p_i];break; default:break; plaintext Copy code } }实现8*8点阵9到0倒序秒表
以下是修改后的代码:
#include<reg52.h>
unsigned char cols[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xE3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char p_i =0;//p_i=0表示显示第一幅图像
unsigned char sec_cnt = 0; // 秒计数器
unsigned char sec_num = 9; // 当前显示的秒数
void main(){
//定时器1和中断
TMOD = 0x10;
TR1=1;
TH1=0xfc;
TL1=0x67;
EA=1;
ET1=1;
while(1);
}
void interrupt_T1() interrupt 3{
static unsigned char row_i=0;//row_i=0表示选中点阵第一行
static unsigned int cnt=0;//cnt=1表示进过1ms,用于点阵行的切换
static unsigned int p_cnt=0;//p_cnt=1表示进过1ms,用于图像的切换
TH1=0xfc;
TL1=0x67;
P0 = 0xff;//消隐
cnt++;
p_cnt++;
if(cnt==1){
cnt=0;
row_i++;
if(row_i==8){
row_i =0;
}
}
if(p_cnt==10){
p_cnt=0;
p_i++;
if(p_i==17){
p_i =0;
}
}
switch(row_i){
case 0:P2 =0x01;P0 = cols[0+p_i];break;
case 1:P2=0x02;P0 = cols[1+p_i];break;
case 2:P2 =0x04;P0 = cols[2+p_i];break;
case 3:P2=0x08;P0 = cols[3+p_i];break;
case 4:P2 =0x10;P0 = cols[4+p_i];break;
case 5:P2=0x20;P0 = cols[5+p_i];break;
case 6:P2 =0x40;P0 = cols[6+p_i];break;
case 7:P2=0x80;P0 = cols[7+p_i];break;
default:break;
}
// 每隔1秒更新秒数
if (sec_cnt == 100) {
sec_cnt = 0;
if (sec_num == 0) {
sec_num = 9;
} else {
sec_num--;
}
// 更新cols数组,显示倒序秒数
for (int i = 16; i < 24; i++) {
cols[i] = cols[i] & ~(1 << sec_num);
}
}
sec_cnt++;
}
在原有的代码基础上,我们添加了两个变量sec_cnt和sec_num,分别用于计数和记录当前秒数。在T1中断中,我们每隔1秒更新一次秒数,并更新cols数组,将倒序秒数显示在点阵上。
好的,你的问题是如何在这段代码的基础上实现按键控制继电器使电机正转与反转。那么可以按照以下步骤: 在程序开头的定义中,添加两个变量用于记录电机状态,例如: 复制 int motor_status = 0; // 0表示电机停止,1表示电机正转,2表示电机反转 int button_status = 0; // 0表示没有按键按下,1表示按键1按下,2表示按键2按下 在主程序的while循环中,添加对按键状态的检测,例如: 复制 if (button1 == 0) // 按键1按下 { button_status = 1; } else if (button2 == 0) // 按键2按下 { button_status = 2; } else // 没有按键按下 { button_status = 0; } 根据按键状态,控制电机的状态,例如: 复制 if (button_status == 1) // 按键1按下,电机正转 { if (motor_status != 1) // 如果电机不是正转状态,则控制继电器闭合,使电机正转 { motor = 1; delay(1000); motor_status = 1; } } else if (button_status == 2) // 按键2按下,电机反转 { if (motor_status != 2) // 如果电机不是反转状态,则控制继电器断开,使电机停止,然后再控制继电器闭合,使电机反转 { motor = 0; delay(1000); motor = 1; delay(1000); motor_status = 2; } } else // 没有按键按下,电机停止 { if (motor_status != 0) // 如果电机不是停止状态,则控制继电器断开,使电机停止 { motor = 0; delay(100); motor_status = 0; } }将这个代码整合成可以运行的keil51可以运行的代码
好的,以下是整合后的可运行的Keil51代码:
```
#include <reg51.h>
sbit motor = P1^0; // 直流电机控制信号
sbit button1 = P3^0; // 按键1
sbit button2 = P3^1; // 按键2
int motor_status = 0; // 0表示电机停止,1表示电机正转,2表示电机反转
int button_status = 0; // 0表示没有按键按下,1表示按键1按下,2表示按键2按下
void delay(unsigned int time) // 延时函数
{
unsigned int i, j;
for (i = time; i > 0; i--)
{
for (j = 110; j > 0; j--);
}
}
void main()
{
motor = 0; // 初始状态设为停止
while (1)
{
if (button1 == 0) // 按键1按下
{
button_status = 1;
}
else if (button2 == 0) // 按键2按下
{
button_status = 2;
}
else // 没有按键按下
{
button_status = 0;
}
if (button_status == 1) // 按键1按下,电机正转
{
if (motor_status != 1) // 如果电机不是正转状态,则控制继电器闭合,使电机正转
{
motor = 1;
delay(1000);
motor_status = 1;
}
}
else if (button_status == 2) // 按键2按下,电机反转
{
if (motor_status != 2) // 如果电机不是反转状态,则控制继电器断开,使电机停止,然后再控制继电器闭合,使电机反转
{
motor = 0;
delay(1000);
motor = 1;
delay(1000);
motor_status = 2;
}
}
else // 没有按键按下,电机停止
{
if (motor_status != 0) // 如果电机不是停止状态,则控制继电器断开,使电机停止
{
motor = 0;
delay(100);
motor_status = 0;
}
}
}
}
```
需要注意的是,这段代码中用到了延时函数,但是不同的MCU的晶振频率可能不同,因此需要根据实际情况调整延时的时间。