新闻中心

EEPW首页>嵌入式系统>设计应用> 单片机中断问题30例

单片机中断问题30例

作者: 时间:2013-05-07 来源:网络 收藏

第一个送来的申请信号,也不可过短,应该能让对方检测到。

10、程序如下,我想要得到的效果是1秒左边的电动机转动,同时黄灯亮,1秒右边转动,蓝灯亮,以此循环下去,但是这个程序用上去后,左边转》右边转》左边转》之后就一直是左边了,不切换了,谁能帮我解决下问题,感激不尽!!

#include

sbit m=P2^0;

sbit b=P2^6;

sbit y=P2^7;

unsigned char count;

void main()

{

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TR0=1;

ET0=1;

EA=1;

count=0;

m=!0;

b=!1;

y=!0;

while(1)

{

if(TF0==1)

{

count++;

if(count==20)

{

m=0;

b=1;

y=0;

}

if(count==40)

{

m=!0;

b=!1;

y=!0;

}

TF0=0;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

}

}

}

答案

#include

sbit m=P2^0;

sbit b=P2^6;

sbit y=P2^7;

unsigned char count;

void main()

{

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TR0=1;

count=0;

m=!0;

b=!1;

y=!0;

while(1) {

if(TF0==1) {

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TF0=0;

count++;

if(count==20) {

m=0; b=1; y=0;

}

if(count==40) {

count=0; //加上这句.

m=!0; b=!1; y=!0;

}

}

}

}!

用T0定时50ms,溢出20次,溢出40次,分别代表了具体的时间。 溢出40次之后,应该从头开始统计溢出次数,所以,此处应该有count=0;。 楼主原来的程序,缺少count=0;,那么它就会继续增加,直到65536,才自动回到0。 这样,时间,就难以控制了。

11、求助关于51外部中断的问题,小弟最近在学,刚做了一个键盘扫描程序。发现如果外部中断为电平触发,程序能正常运行。但如果改为边沿触发,在将键值送给显示重开中断指令为EX0=1后,中断竟然还会被触发一次,这之后,再按键就不能触发中断了。如果将中断程序中关中断语句去掉,按键能被扫描,但引起中断的次数不好说了。请大侠们看看哪出问题了。谢谢

uchar keynum,//定义全局变量按键时的键值

dpnum,//显示值

time1,//延时计数值

topen,//延时计数控制

keyin;//外部中断0向主程序传递有中断标识,有键按下

keydeal;//按键程序调用标志

uchar keytable[4][4]={7,8,9,'/',4,5,6,'*',1,2,3,'-','c',0,'=','+'};//按实际键盘编值

uchar keyboard();//键盘扫描程序,负责键值扫描,判断键释放由主函数完成

void display(uchar,uchar);// 显示子程序,

sbit keysign=P3^2;//P3.2为中断0入口,此定义用于程序判断是否真有键按下及键是否释放

void main()

{uchar keybiao,keybiao1;//有键按下标志,键放开标志

IE=0x89;//开总中断,外部中断0,定时器中断1

IT0=1;//中断触发方式

PT1=1;//中断优先级

TMOD=0x90;//定时器1工作方式1

TH1=(65536-5000)/256;//定时器初值高8位(定时5ms)

TL1=(65536-5000)%256;

TR1=1;//开始计时

P2=0xf0;//给键盘列高电平,行低电平

keydeal=0x00;//让键处理初值为0,既未处理

while(1)

{if(keyin==1) //可能有键按下

{

if(time1>=2)//已延时10ms;计数2次,

{if(keysign==0keydeal==0)

{keynum=keyboard();

keybiao=1;

keydeal=1;

topen=0;//关延时计数

}//判断是否真有键按下,调用键盘扫描程序

else if(keybiao==0time1>=2keybiao1==0)

{EX0=1;

keyin=0;

topen=0;

}//如果没键按下,重开外部中断0,中断标志清0

}

if(keybiao==1keysign!=0)

{keybiao=0;

time1=0;

keybiao1=1;//为防止前一次time1的影响而设的标志

topen=1;

}

if(keybiao1==1time1>=2)

{keybiao1=0;

topen=0;

EX0=1;

keyin=0;//重开外部中断0,中断标志清0

keydeal=0;//重开键未处理,让程序可调用处理程序

dpnum=keynum;//将键值传给显示

}

}

}

}

void display(uchar x,uchar i)//中断控制显示,显示一直持续到下次中断到

uchar keyboard()

{uchar con1,con2,i,j;

con1=P2|0x0f;//只保留P2口高四位,便于switch

switch(con1)//通过cp可得到列为0的位

{case 0x7f:j=3;break;//j为列值

case 0xbf:j=2;break;

case 0xdf:j=1;break;

case 0xef:j=0;break;

}

for(i=0;i=3;i++)

{P2=_crol_(0xfe,i);//依次给行赋0

con2=P2|0x0f;// 只保留P2口高四位,便于比较

if(con2!=0xff) break;

}

P2=0xf0;//给键盘列高电平,行低电平

return(keytable[i][j]);

}

void T1_time()interrupt 3

{TH1=(65536-5000)/256;//定时器初值高8位(定时5ms)

TL1=(65536-5000)%256;

time1++;

if(topen!=1) time1=0;//如果延时标志不为1,不开始计时

display(dpnum,5);

}

void int0()interrupt 0

{EX0=1;

keyin=1;//向主程序传递键按下



评论


相关推荐

技术专区

关闭