27,382
社区成员
发帖
与我相关
我的任务
分享
#include <reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define led P2
uchar code TAB[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar DAT[]={0,0,0,0};
uchar MIN=0,SECOND=0;
uchar t;
uchar i=0; //定义计数
sbit LSA=P2^2; //138译码器的ABC管脚
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit BUZZER=P1^5; //蜂鸣器P1.5管脚
//LED为P2口
void delay(int n); //延时子程序说明
void sound(); // 蜂鸣器子程序说明
void light(); //流水灯子程序 说明
/*-----------------------------------------------------------------------------------*/
void main() //主函数
{
EA=1; //初始化设置
ET0=1;
TMOD=0x01;
TH0=-50000/256;
TL0=-50000%256;
TR0=1;
/*-----------------------------------------------------------------------------------*/
EX0=1; //初始化中断
EX1=1;
IT0=1;
IT1=1;
/*-----------------------------------------------------------------------------------*/
while(1) //一直循环
{
for(t=0;t<=3;t++)
{
switch(t) //位选,选择点亮的数码管,
{
case(3):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(1):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(0):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=TAB[DAT[t]]; //查表送到P0口
delay(250); //每一位延时一会
// P0=0x00; //消隐
}
}
}
/*-----------------------------------------------------------------------------------*/
void intserv1 (void) interrupt 1 using 1 //定时计数器T0中断服务子程序
{
TH0=-50000/256;
TL0=-50000%256;
i++;
if(i==20)
{ i=0;
SECOND++;
if(SECOND==60)
{ MIN++;
SECOND=0;
if(MIN==60)
MIN=0;
}
// DAT[0]=MIN/10; //能放在for的外面吗? 可以!
// DAT[1]=MIN%10;
// DAT[2]=SECOND/10;
// DAT[3]=SECOND%10;
}
if(MIN==0&&SECOND==11) //5MIN到了 蜂鸣器叫 流水灯发光
{ MIN=0;
SECOND=11;
sound(); //蜂鸣器发声函数
light(); //流水灯函数
TR0=0; //关定时器
}
DAT[0]=MIN/10; //能放在for的外面吗?
DAT[1]=MIN%10;
DAT[2]=SECOND/10;
DAT[3]=SECOND%10;
}
/*-----------------------------------------------------------------------------------*/
void intserv2 (void) interrupt 0 using 1 //int0中断
{MIN++;
if(MIN==60)
MIN=0;
DAT[0]=MIN/10;
DAT[1]=MIN%10;
}
/*-----------------------------------------------------------------------------------*/
void intserv3 (void) interrupt 2 using 1 //int1中断
{SECOND++;
if(SECOND==60)
{MIN++;
SECOND=0;}
DAT[2]=SECOND/10;
DAT[3]=SECOND%10;
}
/*-----------------------------------------------------------------------------------*/
void delay(int n) //延时程序
{
int i;
for(i=0;i<=n;i++);
}
/*-----------------------------------------------------------------------------------*/
void sound() //蜂鸣器子程序
{
uchar i;
while(1)
{ BUZZER=1;
for(i=0;i<=20;i++);
BUZZER=~BUZZER;
for(i=0;i<=20;i++);
}
}
/*-----------------------------------------------------------------------------------*/
void light() //流水灯子程序
{ uchar i;
led=0xfe;
delay(300);
while(1)
{
for(i=0;i<7;i++)
{
led=_crol_(led,1);
delay(300);
}
led=0xfe;
delay(300);
}
}
你定义的STORE[]数组的实际长度为3,而数组索引j在每次执行KEY_PRESS()函数时都会++,因此,会出现数组索引j大于3的情况,即越界访问。需要考虑对j重新计数。
楼主你上面两个函数是两个死循环,这个又不是多线程的,肯定只会跑在一个地方啊
这样也会影响我前三次按键吗 你定义的STORE[]数组的实际长度为3,而数组索引j在每次执行KEY_PRESS()函数时都会++,因此,会出现数组索引j大于3的情况,即越界访问。需要考虑对j重新计数。
void light() //流水灯子程序 { uchar i; led=0xfe; delay(300); while(1)//这里会死循环,主程序只能在这里跑 { for(i=0;i<7;i++) { led=_crol_(led,1); delay(300); } led=0xfe; delay(300); } }
/*********
* 矩阵键盘 55 56行的不遮起来就不对
* 可以变为计算器
********************************************************************************/
#include<reg52.h>
#define KEY_VALUE P1
#define uchar unsigned char
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
uchar KEY_NUM;
char code TAB[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,'+','-','*','='};//显示0~F的值
char STORE[]={0,0,0};
uchar j=0; //数组的下标
uchar RES; //运算结果
/*******************************************************************************************/
void delay(int i) //延时
{
while(i--);
}
/*******************************************************************************************/
void KEY_PRESS() //按键子程序
{ uchar a;
KEY_VALUE=0xf0; //先判断哪一行按下
if(KEY_VALUE!=0xf0)
{
delay(1000);
if(KEY_VALUE!=0xf0) //判断是否真正按下去
{
switch(KEY_VALUE)
{
case(0x70):KEY_NUM=0;break; //先判断哪一行按下
case(0xB0):KEY_NUM=4;break;
case(0xD0):KEY_NUM=8;break;
case(0xE0):KEY_NUM=12;break;
}
KEY_VALUE=0x0f; //判断哪一列按下
switch(KEY_VALUE)
{
case(0x07):KEY_NUM=KEY_NUM;break;
case(0x0B):KEY_NUM=KEY_NUM+1;break;
case(0x0D):KEY_NUM=KEY_NUM+2;break;
case(0x0E):KEY_NUM=KEY_NUM+3;break;
}
while(a<50&&KEY_VALUE!=0x0f)
{
delay(1000);
a++;
}
}
}
// STORE[j]=KEY_NUM; //先保存下来放在数组中
// j++;
}
/*******************************************************************************************/
void WATCH() //显示函数
{
// if(TAB[KEY_NUM]=='=') //=时显示RES里面的
// {P0=TAB[RES];
// }
// else if(TAB[KEY_NUM]=='+'||'-'||'*'); //+-*时无变化
// else
P0=TAB[KEY_NUM]; //其他时显示数字
}
/*******************************************************************************************/
//void RESULT() //求结果函数 全部为0-9的显示
//{
// if(TAB[KEY_NUM]=='=')
// {
// if(TAB[STORE[1]]=='+')
// RES=STORE[0]+STORE[2];
// if(TAB[STORE[1]]=='-')
// RES=STORE[0]-STORE[2];
// if(TAB[STORE[1]]=='*')
// RES=STORE[0]*STORE[2];
// }
//
//
//}
/*******************************************************************************************/
void main()
{
LSA=1;LSB=1;LSC=1;
while(1) //此处一直执行注意将显示函数全放在while里面
{
KEY_PRESS();
// RESULT();
WATCH();
}
}
这样的话就可以实现键盘了
但是55 56行不遮起来的话矩阵键盘5之后的都不能正常显示了#include<reg52.h>
#define KEY_VALUE P1
#define uchar unsigned char
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
uchar KEY_NUM;
char code TAB[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,'+','-','*','='};//显示0~F的值
char STORE[]={0,0,0};
uchar j=0; //数组的下标
uchar RES; //运算结果
/*******************************************************************************************/
void delay(int i) //延时
{
while(i--);
}
/*******************************************************************************************/
void KEY_PRESS() //按键子程序
{ uchar a;
KEY_VALUE=0xf0; //先判断哪一行按下
if(KEY_VALUE!=0xf0)
{
delay(1000);
if(KEY_VALUE!=0xf0) //判断是否真正按下去
{
switch(KEY_VALUE)
{
case(0x70):KEY_NUM=0;break; //先判断哪一行按下
case(0xB0):KEY_NUM=4;break;
case(0xD0):KEY_NUM=8;break;
case(0xE0):KEY_NUM=12;break;
}
KEY_VALUE=0x0f; //判断哪一列按下
switch(KEY_VALUE)
{
case(0x07):KEY_NUM=KEY_NUM;break;
case(0x0B):KEY_NUM=KEY_NUM+1;break;
case(0x0D):KEY_NUM=KEY_NUM+2;break;
case(0x0E):KEY_NUM=KEY_NUM+3;break;
}
while(a<50&&KEY_VALUE!=0x0f)
{
delay(1000);
a++;
}
}
}
STORE[j]=KEY_NUM; //先保存下来放在数组中
j++;
}
/*******************************************************************************************/
void WATCH() //显示函数
{
if(TAB[KEY_NUM]=='=') //=时显示RES里面的
{P0=TAB[RES];
}
else if(TAB[KEY_NUM]=='+'||'-'||'*'); //+-*时无变化
else
P0=TAB[KEY_NUM]; //其他时显示数字
}
/*******************************************************************************************/
void RESULT() //求结果函数 全部为0-9的显示
{
if(TAB[KEY_NUM]=='=')
{
if(TAB[STORE[1]]=='+')
RES=STORE[0]+STORE[2];
if(TAB[STORE[1]]=='-')
RES=STORE[0]-STORE[2];
if(TAB[STORE[1]]=='*')
RES=STORE[0]*STORE[2];
}
}
/*******************************************************************************************/
void main()
{
LSA=1;LSB=1;LSC=1;
while(1) //此处一直执行注意将显示函数全放在while里面
{
KEY_PRESS();
RESULT();
WATCH();
}
}
自己写了一个使用矩阵键盘和一个八段数码管的极其简单计算器,但是烧进去以后按键没有作用,数码管只显示8. ,这个是在我之前一个按键显示0到F的代码修改的,之前的那个是可以正常显示的,但是在这个里面把后来增加的去掉只留一个49 50行的那个保存键盘显示就在5之后不正常了,,你的sound()函数和light()函数中都有while(1)循环,但没有跳出循环的控制,因此结果就变成只进入排在前面的函数中一直执行,而无法跳出该函数去执行下一个函数。去掉这两个函数中的while(1)就可以了。