微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机的延时与中断问题及解决方法

单片机的延时与中断问题及解决方法

时间:11-19 来源:互联网 点击:

流水灯亮.就然后执行全亮全暗3次 !可是就是不会跳到全亮全暗3次~~

答:
R0没有赋初值!另外建议不要使用前2B个地址,因为51中断矢量就在这个空间里。建议从0030H开始。以下程序在keil4中仿真成功。
ORG 0000H
AJMP AG
ORG 0030H
AG:MOV A,#11111110B
MOV R0,#8
AG1:RL A
MOV P0,A
ACALL DELAY
DJNZ R0,AG1
ACALL DELAY
MOV A,#11111111B
MOV P1,A
ACALL DELAY
MOV P0,#00000000B
ACALL DELAY
MOV P0,#11111111B
ACALL DELAY
MOV P0,#00000000B
ACALL DELAY
MOV P0,#11111111B
ACALL DELAY
SJMP AG
DELAY:MOV R3,#10
D3:MOV R2,#200
D1:MOV R1,#250
D2JNZ R1,D2
DJNZ R2,D1
DJNZ R3,D3
RET
END

5、STC89C52通过两个外部中断P3.2和P3.3,来控制P1.0和P1.1的数码管亮和灭,一定keil C
说明:通过外部中断0,P1.0的数码管亮,中断结束后,数码管灭;再由外部中断1,P1.1的数码管亮,次中断结束后,数码管灭;简言之就是一个中断只控制一个数码管,中断之间在功能上没有必然的联系,编程环境keil C51。P1.0和P1.1口上接的都是普通LED小灯,数码管=LED小灯。

以下是我编的程序,就是一个中断控制一个数码管,但是当有两个中断时,我就抓瞎了
#include
sbit D1=P1^0;
void main()
{
D1=1;
EA=1;
EX0=1;
}
void exter() interrupt 0
{
D1=0;
}
求高手帮我改改程序,改成两个中断的那种,功能要求都写在上面了~3Q,我会去keil里面模拟的~~o()^))o

答:
/*模块低电平有效、外部中断0、1为低电平出发*/
#include "reg52.h"
void delay( char i)
{
unsigned char t;
while(i--)
{
for(t=0;t<108;t++);
}
}
void INT0_ROUTING() interrupt 0//外部中断0子程序
{
P0=0xfe;//LED0点亮
while((P3|0xfb)==0xff);//等待外部中断0口(P3^2松开)
delay(10);//延时去抖动
P0=0xff;//LED0熄灭
}
void INT0_ROUTING() interrupt 2
{
P0=0xfd;//LED1点亮
while((P3|0xf7)==0xff);//等待外部中断1口(P3^3松开)
delay(10);//延时去抖动
P0=0xff;//LED1熄灭
}

void main()
{
EA=1;//中断总开关
EX0=1;//外部中断0开
EX1=1;//外部中断1开
/*默认低电平触发*/
while(1);//死循环 防止跑飞
}

6、单片机中断问题,下面这段程序不知道为什么只进一次中断,就没有反应了呢?

#include // 包含51单片机寄存器定义的头文件
#define uint unsigned int
sbit key1=P1^4;
sbit key2=P1^5;

void delay1ms(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<125;j++) //1ms基准延时程序
{
;
}
}
}
void init()
{
EA=1; //开总中断
ES=1; //开串口中断
TMOD= 0x21; //定时器1定时方式2,定时器1工作于8位自动重载模式, 用于产生波特率
SCON = 0x50; // 设定串行口工作方式1 允许接收
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1= 0xfd; //11.0592M 波特率9600
TL1= 0xfd;
PCON =0x00; // 波特率不倍增
TR1= 1; //启动定时器T1
TR0=1; //启动定时器T0
ET0=1; //打开T0中断
}
void key()
{
if(key2==0)
P0=0x3f;
delay1ms(5000);
P0=0xf3;
}
void mainxh()
{
while(1)
{
key();
P0=0x32;
}
}
void keybreak()
{
P0=0xf1;
delay1ms(5000);
P0=0x1f;
mainxh();
}
void main(void)
{
init();
mainxh();
}
void Time0(void) interrupt 1
{
TH0=(65536-50000)/256; //定时器T0的高8位重新赋初值
TL0=(65536-50000)%256; //定时器T0的高8位重新赋初值
if(key1==0)
keybreak();
}

这个程序上电后P0口显示0x32;按下key2显示0x3f;key1用于中断,每20ms检测是否有按下key1键,有的话,P0口显示0xf1。

答 :
ORG 0000H AJMP MAIN ORG 0001H LJMP INT_0 ORG 30H MAIN:MOV SP,#8FH MOV P0,#0FFH MOV P3,#0FFH SETB IT0 SETB EA SETB EX0 LJMP START START: MOV A,#10000000B LOOP: MOV P0,A RLC A LCALL DELAY LCALL DELAY LJMP LOOP LJMP START;
这句是多余的 根本不会执行 INT_0: PUSH ACC ;
由于p中1断中1A被设为10所以5中7断返回后对A移位没有意义,o A一e直为10 ,并不d是只能中断一1次 .
还有,不清楚key1是什么中断,貌似是键盘扫描吧,
while(1)
{
key();
P0=0x32;
}
都进入死循环了,所以跳不出来,就一次中断了。

7、新手学习avr单片机ATmage 128 遇到问题,中断程序被忽略问题,找不到原因。
avr studio 4 软件仿真时,编译通过了,单在编译信息栏却看到中断程序被忽略。在软件仿真时也发现中断程序没有执行。不知道问题出在哪里,我用的是avr studio 4 ATmage 128 单片机.

程序如下

#include
#include
void main() //用的是TC0 溢出中断,来控制八位LED 一秒闪烁
{
PORTE = 0xFF; //LED 关 端口高电平位关
DDRE = 0xFF;
MCUCR |=(1sei(); //开启全局中断
TIMSK|=(1TCNT0 =155; //定时器赋初值
TCCR0 |= (1 < CS01); //8分频
while (1);

}

volatile unsigned int j =0;
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
TCNT0 = 156; //设初值
j++;
if(j <= 5000) //中断5000次后 执行LED 电平翻转
PORTE ^= 0xFF; //LED 电平翻转

}

../lesson2.c:18: warning: ignoring #pragma interrupt_handler timer0_ovf_isr

上面是写的程序。还有编译信息栏里的话。

答:
不是,你那句#pragma interrupt_handler timer0_ovf_isr:17是ICCAVR编译软件中写中断的方式,而看你的头文件#include 和#include 应该是用avr studio装GCCavr编译软件的写法,你加上把中断成
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 156; //设初值
j++;
if(j <= 5000) //中断5000次后 执行LED 电平翻转
PORTE ^= 0xFF; //LED 电平翻转

}
看看,记住,这是GCCAVR 编译软件的写法

8\新学的C51单片机,编了个电平触发式中断程序,不知道为什么和跳变沿的一样了,诸位帮忙看看.
#include
#define uchar unsigned char
#define uint unsigned int
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
void delay(uint z);
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void main()
{
EA=1;
EX0=1;
IT0=0;
while(1)
{ d1=1;
dula=1;
P0=table[1];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(500);

dula=1;
P0=table[2];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(500);

dula=1;
P0=table[3];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay(500);

dula=1;
P0=table[4];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay(500);

dula=1;
P0=table[5];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay(500);

dula=1;
P0=table[6];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay(500);

}
}
void delay(uint z)
{
uint x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
void enter() interrupt 0
{
d1=0;
}

答: 你这个程序中设置IT0=0,说明是低电平触发,所以只要P3^2口一直是低电平那么主程序停止,所以发光二极管点亮,如果P3^2口变为高电平,主程序继续,发光二极管熄灭。另一种情况是当IT0=1的时候是负跳变触发,就是当P3^2口检测到一个又高电平到低电平的跳变后,触发中断,在中断函数中点亮灯,立即出中断,执行到d1=1时熄灯。看到的现象就是灯闪一下,直到又检测到一个负跳变,灯又闪一下。两种触发方式的现象是不一样的,如果你硬件没问题的话。你可以把中断函数写成d1=!d1试试。

9、在C51单片机中,中断服务程序怎么撤销中断引脚上的低电平?
我用的是,第一个单片机输出低电平到第二个单片机的P3^2,第二个单片机是电平触发方式中断
低电平触发方式:要求低电平保持到CPU实际响应为止,为了避勉CPU再次响应中断,在中断服务程序中应该撤除中断引脚上的低电平。请问,怎么撤销?在中断服务程序中怎么写? 直接写P3^2=1;行吗?
答:
第一个单片机的程序,是谁来编写? 如果也是楼主,那就好办了。
第二个单片机完成了中断的功能,在退出之前,可以向第一个单片机回送一个脉冲;
第一个单片机收到这个脉冲,就应该撤消送到第二个单片机的中断申请信号。
----
另外,如果能算出来完成中断的时间,第一个单片机送来的申请信号,就不要超过这个时间,应该及时、自动的撤消申请信号。
第一个单片机送来的申请信号,也不可过短,应该能让对方检测到。

10、程序如下,我想要得到的效果是1秒左边的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top