本帖最后由 tanxin2721 于 2014-1-2 22:59 编辑
最近在用89c52做一个通过按键输入,数码管显示数值,来控制步进电机转动时间的程序,在用到中断函数的时候遇到了点问题,就是在中断3里面重新设置初值的时候有用到全局变量s,但是用了之后没有作用。如果把s改成常数的话,那又正常的了。比如我把s改成20,那么P1_0灯亮2秒是正常的,但是如果改成s的话,灯一直是亮的。不知道是怎么回事,我查了一下,说中断函数里的变量需用volatile定义,我也定义了,但是没有作用.都快崩溃了,调了4,5个晚上了,还是没有调出来,只有来求助各位达人了。
数码管显示部分可以不用看,主要是在按键扫描里面关于中断的问题。直白点可以关注灯P1_0亮的时间是否准确。
#include <reg52.h>
#include <string.h>
unsigned char num[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f}; //共阳极LED段码0~9
unsigned char a,k,m,H[50];
volatile unsigned char s,p,q,biaozi,time;
sbit P1_0=P1^0;
sbit P3_4=P3^4;
sbit P3_2=P3^2;
/*************延时Xms*****************/
void Delay_nms(unsigned int n) //延时程序
{ unsigned int i,j;
for(i=n;i>0;i--)
for(j=100;j>0;j--);
}
/*****************键盘扫描函数*************************************/
void GetKey ( )//键盘扫描函数,用于识别哪一个键按下,并读取键值
{
unsigned char X,Y,Z;
if(P1_0==1)
{
P0=0x0f; //先对P3置数 行扫描
if(P0!=0x0f) //判断是否有键按下
{
Delay_nms(5); //延时,软件去干扰
if(P0!=0x0f) //确认按键按下X = P3;
{
X=P0&0x0f; //保存行扫描时有键按下时状态
P0=0xf0; //列扫描
Y=P0&0xf0; //保存列扫描时有键按下时状态
Z=X|Y; //取出键值
switch ( Z ) //判断键值(那一个键按下)
{
case 0xd7: k=0; break; //对键值赋值
case 0xee: k=1; break;
case 0xde: k=2; break;
case 0xbe: k=3; break;
case 0xed: k=4; break;
case 0xdd: k=5; break;
case 0xbd: k=6; break;
case 0xeb: k=7; break;
case 0xdb: k=8; break;
case 0xbb: k=9; break;
case 0x77: k=10;break;
case 0x7b: k=11;break;
default : break;
}
while(P0!=0XF0) /*等待按键释放*/
{
}
if(k!=10)
{
H[m]=k;
m++;
a++;
}
else if(k==10) //若k=10(按键确认键)
{
/***********************************送给步进电机一段脉冲信号*******************/
TMOD=0X51; //设定定时器0方式1和计数器1方式1
TH0=(65536-1250)/256;
TL0=(65536-1250)%256;
TH1=(65536-100)/256;
TL1=(65536-100)%256;
time=0;
biaozi=0;
p=0;
q=0;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
P1_2=0;
/*********************等待第一次脉冲信号输入完全然后电机不转,等待特定秒数后再转动********/
while(time==0)
{}
/****************根据按键得出计时时间值***********************/
if (a<=1)
{
s=20;
}
else if(a==2)
{
if(H[0]>=2)
{
s=H[0]*10+H[1];
}
else{s=20;}
}
else if(a==3)
{
s=H[0]*100+H[1]*10+H[2];
}
else if(a>=4)
{s=H[m-4]*1000+H[m-3]*100+H[m-2]*10+H[m-1];}
/****************************************************/
P1_0=0; //灯P1_0亮
p=1;
q=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
while(biaozi==0)
{}
/***********************电机再次转动**************************/
TMOD=0X01;
p=0;
TR0=0;
}
}
if(k==11)
{
memset(H,0,sizeof(H));
m=0,a=0;
}
}
}
}
/*******************数码管显示*****************************************/
void dispy()
{ int U;
P0=num[10];
P2=0XFB;
Delay_nms(2);
P2=0XFF;
if(a==1 )
{
U=H[m-1];
P0=num[U];
P2=0XF7;
Delay_nms(2);
P2=0XFF;
}
else if(a==2)
{
U=H[m-1];
P0=num[U];
P2=0XF7;
Delay_nms(2);
P2=0XFF;
U=H[m-2];
P0=num[U];
P2=0XFB;
Delay_nms(2);
P2=0XFF;
}
else if(a==3)
{
U=H[m-1];
P0=num[U];
P2=0XF7;
Delay_nms(2);
P2=0XFF;
U=H[m-2];
P0=num[U];
P2=0XFB;
Delay_nms(2);
P2=0XFF;
U=H[m-3];
P0=num[U];
P2=0XFD;
Delay_nms(2);
P2=0XFF;
}
else if(a>=4)
{
U=H[m-1];
P0=num[U];
P2=0XF7;
Delay_nms(2);
P2=0XFF;
U=H[m-2];
P0=num[U];
P2=0XFB;
Delay_nms(2);
P2=0XFF;
U=H[m-3];
P0=num[U];
P2=0XFD;
Delay_nms(2);
P2=0XFF;
U=H[m-4];
P0=num[U];
P2=0XFE;
Delay_nms(2);
P2=0XFF;
}
}
/**********************中断函数****************************/
timer0() interrupt 1 using 1
{ if(p==0)
{
P3_2=!P3_2; //外部输入给步进电机脉冲信号
P3_4=!P3_4; //与P3_5相连,送给计数器脉冲信号
TH0=(65536-1250)/256;
TL0=(65536-1250)%256;
}
else if(p==1)
{
P3_4=!P3_4; //与P3_5相连,送给计数器脉冲信号
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
}
timer1() interrupt 3 using 3
{ if(q==0)
{
TR0=0;
ET0=0;
ET1=0;
TR1=0;
time=1;
TH1=(65536-s)/256;
TL1=(65536-s)%256;
}
else if(q==1)
{
P1_0=1; //灯P1_0灭
TR0=1;
biaozi=1;
}
}
/**********************主函数******************************/
void main(void)
{ a=0,m=0;
P3_4=1;
P1_0=1;
P3_2=1;
while(1)
{
GetKey();//得到键值
dispy(); //数码管显示
}
}
/************************************************************/
|