您的位置 首页 IC

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

延时与中断出错,是单片机新手在单片机开发应用过程中,经常会遇到的问题,本文汇总整理了包含了MCS-51系列单片机、MSP430单片机、C51单片…

延时与中止犯错,是单片机新手在单片机开发运用进程中,经常会遇到的问题,本文汇总整理了包括了MCS-51系列单片机、MSP430单片机、C51单片机、8051F的单片机、avr单片机、STC89C52、PIC单片机…..在内的各种单片机常见的延时与中止问题及处理办法,期望对单片机新手们,有所协助!

一、单片机延时问题20问

1、单片机延时程序的延不时刻怎样算的?
答:假定用循环句子完结的循环,无法核算,可是能够经过软件仿真看到详细时刻,可是一般精准确延时是无法用循环句子完结的。
假定想准确延时,一般需求用到守时器,延不时刻与晶振有联络,单片机体系一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。榜首种更简略发生各种规范的波特率,后两种的一个机器周期别离为1 μs和2 μs,便于准确延时。本程序中假定运用频率为12 MHz的晶振。最长的延不时刻可达216=65 536 μs。若守时器作业在办法2,则可完结极短时刻的准确延时;如运用其他守时办法,则要考虑重装守时初值的时刻(重装守时器初值占用2个机器周期)。

2、求个单片机89S51 12M晶振 用守时器延时10分钟,操控1个灯就能够
答:能够设50ms中止一次,守时初值,TH0=0x3c、TL0=0xb0。中止20次为1S,10分钟的话,需中止12000次。计12000次后,给一IO口一个低电平(如功率不行,可再加扩展),就可操控灯了。

而且还要看你用什么言语核算了,汇编延时准确,知道单片机作业周期和循环次数即可算出,但不具有可移植性,在不同品种单片机中,汇编不通用。用c的话,由于各种软件履行功率不相同,不会太准,通常用守时器做延时或做一个不准确的延时,延时短的话,在c中运用汇编的nop做延时

3、51单片机C言语for循环延时程序时刻核算 ,设晶振12MHz,即一个机器周期是1us。
for(i=0,i<100;i++)
for(j=0,j<100;j++)
我觉得时刻是100*100*1us=10ms,怎样会是100ms
答:
不或许的,是不是你的编译有错的啊
我改的晶振12M,在KEIL 4.0 里面编译的,为你得出的成果最大也便是40ms,这是软件的原因,
不或许呈现100ms那么大的距离,是你的软件的原因。
不信你实践编写一个秒钟,运用原理核算编写一个烧进单片机和运用软件测验的秒程序烧进单片机,你会发现原理核算的程序是正确的

4 、51单片机c言语 _nop_()是一个空指令?短时刻延时的?空几个机器周期?
答:这个_nop_()等效与汇编里面的,NOP指令,也便是空一个机器周期,假定是传统51单片机的话,等于空12个时钟周期

5、51单片机 延时500ms 用机器周期叠加怎样算?
答:DELAY:
MOV R7,#4
D2:MOV R6,#250
D1:MOV R5,#250
DJNZ R5,$
DJNZ R6,D1
DJNZ R7,D2
RET
假定晶振为12MHz
刚延不时刻为:
250*250*4*2=500MS

6、51单片机C言语程序中延时函数delay的原理是什么?
现在找到两个函数
榜首:
void delay(void)
{ unsigned int i,j;
for(i=0;i<500;i++)
{ for(j=0;j<121;j++)
{;}
}
}

第二:
void delay(unsigned int k)
{ unsigned int i,j;
for(i=0;i{ for(j=0;j<121;j++)
{;}
}
}
现有几个疑问:
(1):延时函数的原理?
(2):两个for循环的效果?
(3):i、j的取值有什么规则和依据?是不是和单片机接的晶振频率有关?所能延时的最小单位时刻是怎样核算的?
延不时刻怎样核算啊!假定用的是AT89C51RC+11.0592M的晶振呢?
答:
1:原理:仅仅履行一些,没有实质性影响的所谓“无含义指令”,比方做比巨细啊,做某个int的自加运算啊之类的
2:两重for的效果:简略的说,就像高中数学中的“乘法原理”相同,这样能够很容易的敏捷添加上述“无含义指令”的数目
3:关于取值巨细:这个假定是在C下变成,这个值不仅仅与晶振、单片机自身运算速度有关,而且还与C的编译器有关,所以说,这个值虽说是能够准确核算的,但大多数状况下,程序员用的都是“经历值”——当然,假定用汇编编程,状况就不相同了,由于每一条指令所运用的机器周期是必定的,你当然能够依据一切指令运用的总时刻,准确的算出详细延时的总时刻

归纳你的的问题,我给你一点主张,便是刚学单片机的时分,仍是必定要老老实实的从汇编编程学起——这样,在你今后触摸到C之后,你才干了解,这中心实践上阅历了一个什么样的进程,只需这样你才干真实了解单片机。当然,等终究你彻底拿下一种单片机之后,尽量运用C编程,无疑是前史所必定的。

7、51单片机,晶振为6M,求一个10ms的延时程序
答:延时有许多种办法,有一种是让单片机去做无聊的循环,还有一种是用守时器。
榜首种的算法是:
晶振的周期T1=1/f; 这儿f=6MHz 所以T1=1/6 us;(微秒)
单片机花12个T1去履行一个指令,
所以一个机器周期等于12个晶振周期,
T2=12*T1=2us
10ms=1000 0us
所以你要得到10ms的延时就要想办法让机器去做5000条“无聊的指令”
所以
DEL: MOV R5,#05H
F1: MOV R6,#05H
F2: MOV R7,#32H
F3: DJNZ R7,F3
DJNZ R6,F2
DJNZ R5,F1
RET
这种办法是用于对时刻要求不高的当地,我说的是其思维,程序中或许有错的当地
用守时器的办法我不太会就不误人了 (弥补一下便是这个是用汇编写的,你在主程序顶用ACALL DEL调用就延时了。

8、今日我用单片机做“眨眼的LED”试验时,程序运转,每次只令灯亮或灭都没问题,可是一开延时不能呈现期盼的灯亮灯灭的现象,这是怎样回事?
试验的硬件条件是:STC89C52,编译环境:keil 3。

下面是我写的程序,讨教高手!!!

#include // 文件包括处理
#define uchar unsigned char //宏界说,便利今后程序的书写
#define uint unsigned int
sbit P1_0 = P1 ^ 0; //位变量界说
void Delay(uint t)
{
uchar i;
while(–t)
{
for(i = 0; i < 125; i++) //延时1MS,在这儿咱们用的晶振是是12M,依据机器周期的核算,咱们
{;} //可算得本次循环延时约1MS
}
}
void main(void)
{
while(1)
{
P1_0 = 0; //点亮LED灯
Delay(1000); //应单片履行程序的时刻很快,所以有必要延时,要不看不到试验现象
P1_0 = 1; //平息LED灯
}

弥补发问:我是让P1.0先低然后延时之后再高,即灯先亮再灭,然后开端循环的

答:应该这样写
while(1)
{
P1_0 = 0; //点亮LED灯
Delay(1000); //应单片履行程序的时刻很快,所以有必要延时,要不看不到试验现象
P1_0 = 1; //平息LED灯
Delay(1000);
弥补问题:问题恰恰就错在这了,循环完一遍之后灯由灭到亮底子没有时刻延时,即榜首次循环中灯还没来的机灭呢,就进入到第二轮循环中的亮了,所以原因就在这,这过错太初级了,今后引认为鉴吧

9、单片机延时函数的问题
void delay(uchar i)
{
uchar j;
while(i–)
{
for(j=125;j>0;j–)
;
}
}
这个函数中的i,j的巨细有吗?

答:这个函数中j的巨细和你界说的数据类型有关,由于你界说的为无符号字符型,为单字节数据,所以最大为255。.
假定你需求增大,能够改动j的数据类型界说,如unsigned int (2字节)能够到65535;无符号长整形unsigned long(4字节) 能够到4294967295。 而上面所所256是-1,而你界说的是无符号字符型。

10、讨教一个AVR单片机延时的问题
外部晶振用的是8MHz,延时1微秒的程序如下:
void delay_us(unsigned int delay_counter)//延时1us
{
do
{
delay_counter–;
}
while(delay_counter>1);
}
请问,为什么能延时1微秒啊?

答:8MHZ标明单片机的运转周期为1/8us,也便是0.125us履行一步
你运用的是软件延时
那么包括程序的提取,履行等都要花费时刻
比方,你提取这个函数或许花去一步,那现在就运用了0.125us啦
接着你履行这个函数,在单片机内部,运算是经过寄存器的移来移去完结的
这都需求时刻,或许你看到的就一句counter–这个指令,或许会花费好几个时钟周期来完结
举个比方:
c=a+b,只需一句,但实践上花费的时刻并不短
mov a,#data1;//数据data1放入a寄存器
mov b,#data2;//数据data2放入b寄存器
add a,b;//寄存器a的值与b相加,成果放入a
mov c,a;//将a的值放入c
这样才是单片机内部真实履行的指令,这需求花费至少4个时钟周期,而不是1个
至于晶体管级的我就不解说了,你得好好学习汇编才干了解单片机的运作。

至于这个函数为什么能延时1ms,这个是靠经历来判别的,最直接的办法便是用示波器看,以上均为推论。

11、PIC单片机的延时问题 晶振4Mhz:
void delay()
{
unsigned int d=1000;
while(–d){;}
}
此函数在4M晶体下发生10003us的延时,也便是10MS。
问题:我刚算了一下他应该履行了999条指令,1条单周期的指令也才1US,那便是999us,为什么会有10ms的延时?
1:for(x=100;–x;){;} : 2: for(x=0;x<100;x++){;} 2句话相同
榜首句:X的值规模是不是 1~99?为什么?
第二句:X的规模是不是0~99?为什么?这么算的。我知道符号在前在后的差异。2句话应该是不相同的才对啊!
答:
问题1:“我刚算了一下他应该履行了999条指令”由于你算错了。延不时刻是由发生的汇编代码所决议的,C言句子子仅仅个假象,千万不要认为C言语一行便是一条指令!此处由于涉及到双字节减法,因而会有额定的判别,编译成果每次循环耗费几十个周期毫不古怪。

问题2:前一句x从100开端递减,递减至1时退出循环。后一句x从0开端递加,递加到100时退出循环。所谓“2句话”相同仅仅是指这两个循环体的循环次数相同。实践上两个循环的履行进程是彻底不同的,所耗费时刻也有或许不同。

12、stc单片机的延时问题 ,STC10F08XE单片机,晶振22.1184M
void delay(unsigned long uldata)
{
unsigned int j = 0;
unsigned int g = 0;
for (j=0;j<5;j++)
{
for (g=0;g{
_nop_();
_nop_();
_nop_();
}
}
}
当uldata=1时延时多少秒?
请给出详细算法…………
答:用keil转化成汇编句子,然后对照指令表核算就行了

13、我想用单片机衔接不断地向电脑发数,如下:
while (1)
{
send_char(9);
delay(n);
}
如每发送一个数,应延时多少奇妙好呢?即一般最短能延时多少微米呢?如延时太长的话,那发送许多数据不就用很长时刻吗?

答:不做太多的串口处理剖析,只顺着你的问题和你的办法说说:
先考虑下串口的速率 假定9600,那么发送一个字符要多久?
(9600bit/S) / 10bit(一个字符1+8+1) = 960字符/秒 约 1ms/byte
也便是说你假定在1ms内发送超越一个字符就没含义了,硬件速度达不到。
while(1)
{
send_char(9);
delay(n);
}
这个循环是履行周期也就十几微秒+delay()的推迟,所以任何小于1040微秒的推迟对串口硬件来说没含义,上一个还没处理完,下一个就来了底子履行不了嘛。
假定你send_char()里面有while(!TI);TI = 0;这样的句子或有串口中止TI的处理的话,那么实践上你的delay()现已在发送函数里了,while(!TI);这部便是推迟等候吗?那底子不需求主函数去推迟了,直接发就行了。

14、一个单片机延时子程序的问题,在延时子程序那里,一向搞不了解,给r7和r6赋予0,然后下面的djnz r7,delayloop不就一向循环了,那还怎样接下去的程序?

org 0000h
ljmp start
org 0030h
start: mov a,#0feh
mov r5,#8
output: mov p1,a
rl a
call delay
djnz r5,output
ljmp start
delay: mov r6,#0
mov r7,#0
delayloop:djnz r7,delayloop
djnz r6,delayloop
ret
end

答: 你的延时程序不是由于值为0,而是跳转方位不对,改为如下:
delay: mov r6,#0
delayloop:mov r7,#0
:djnz r7,$
djnz r6,delayloop
ret
R7,R6初值为0,可是当DJNZ履行时,这条指令是先减1再判别,所以0-1=255,判别的话也不为0,依然循环256次。

0-1=255的解说:
0000 0000
– 0000 0001
————————-
1111

15、我想提两个单片机延时与按键的问题
1:假定一个程序中延时和按键,假定延时子程序比较长(假定2秒),怎样保证按键能够得到及时呼应(假定PC正在履行延时子程序,正在这时分有按键输入,不是呼应不了)——,,,条件是不能用守时器守时扫描,和中止来做,由于守时器和中止我还有其他用处
2:单片机没有串口。怎样才干使得他与24C02进行通讯(24C02是具有2K内存的EEPROM)
答:
首要清晰一点你说单片机没有串口,应该是指没有I2C口吧。
1 在延时程序里面参加按键的检测
2 用IO口模仿I2C时序读写

16、51单片机延时小程序,求高手解说什么意思?
delay200ms:
mov r2,#82
l0:mov r1,#116
l1:mov r0,#9
djnz r0,$
djnz r1,l1
djnz r2,l0
ret
答:以下是每条指令的时刻,T为一个机器周期
delay200ms:
mov r2,#82;1T
l0:mov r1,#116;1T
l1:mov r0,#9;1T
djnz r0,$;2T
djnz r1,l1;2T
djnz r2,l0;2T
ret;2T
以上共三层循环,疏忽部分指令,最简略算法是:
2*9*116*82=171216
不疏忽指令是:
1+(1+(1+2*9+2)*116+2)*82+2=200001
因而延不时刻大约为200ms

17、于51单片机推迟时刻的问题
uchar i;i–;
uint i;i–;
这两条句子在12M晶振下运转时刻别离是多少??
答:一个时钟周期,2us,共4us

18、周期为6MHZ的单片机延时10秒的子程序的怎样编?
答:/
* 称号 : Delay()
* 功用 : 延时,延不时刻为 10ms * del。这是经过软件延时,有必定差错。
* 输入 : del
* 输出 : 无
*/
void Delay(uint del)
{
uint i,j;
for(i=0; ifor(j=0; j<1827; j++) //这个是经过软件仿真得出的数
;
}
这个是晶振为12mhz的单片机延时10ms的程序,你只需在这个基础上减小一倍就行了,当然至于详细值仍是要调试下的。

19、片机的有些程序需求调用延时程序,怎样能合理的组织循环次数以及空操作的个数?
答:用汇编的话就依据你的其时晶振频率去计算你的指令周期,然后结合你需求推迟的时刻,编写推迟程序,用C的话仍是要看最终生成的汇编码是什么样的了。最简略的办法便是写好程序今后再编译器里软仿真看时刻。附和2| 谈论(1)

20、单片机延时程序问题
延时程序 void delay(uint dt)
{
uchar bt;
for(;dt;dt–);
for(bt=0;bt<255;bt++);
}
编译时有正告C:\DOCUMENTS AND SETTINGS\ADMINISTRATOR\桌面\字 310 点阵LED显现.C(46): warning C235: parameter 1: different types
为什么?求大侠点拨
答:某个函数传参类型与声明类型不符。
别的你这个for(;dt;dt–);没有起到外层循环的效果……

二、单片机中止问题30例

1、单片机外中止INT0为下降沿触发,当中止被触发后cpu履行中止程序,若本次中止的程序还未履行完INT0又来了一个相同的下降沿中止信号怎样办?cpu会怎样处理?若是守时器中止呢?串口中止呢?求解说
答:再来一个INT0信号不会履行。相同的优先级不会打断正在履行的中止。
一. 假定是高优先级的中止来了,会打断低优先级的正在履行的中止而履行高优先级的中止。
51单片机的默许(此刻的IP寄存器不做设置)中止优先级为:
外部中止0 > 守时/计数器0 > 外部中止1 > 守时/计数器1 > 串行中止;
当一起有几种中止抵达时,高优先级中止会先得到服务。
例如:当计数器0中止和外部中止1(优先级 计数器0中止>外部中止1)一起抵达时,会进入计时器0的中止服务函数;可是在外部中止1的中止服务函数正在服务的状况下,这时分任何中止都是打断不了它的,包括逻辑优先级比它高的外部中止0计数器0中止。
51单片机的中止优先级操控寄存器IP能够把默许的中止优先级设置为高或初级,
例如默许是外部中止0 > 守时/计数器0 > 外部中止1 > 守时/计数器1 > 串行中止;
现在设为守时1 和串行中止为高优先级 其它为低 ,那么中止0履行时会被守时器1 或串行中止打断,假定设定的两个高优先级守时/计数器1 和串行中止一起呼应,会再天然排队,先履行守时1中止再履行串行中止。

2、单片机中止问题,中止3为什么不履行,整个程序有什么不对的当地呢?
#include
#define uint unsigned int
#define uchar unsigned char
sbit p1_0=P1^0;
sbit p1_1=P1^1;
sbit p1_2=P1^2;
sbit p1_3=P1^3;
sbit p1_4=P1^4;
sbit p1_5=P1^5;

uchar PWM_T1 = 0;
uchar PWM_T2 = 0;
uint i,m;
void delay(uint z)
{
for(i=z;i>0;i–)
for(m=0;m<110;m++);
}
void PWM_value_left(int pwm_set)
{
PWM_T1=pwm_set;
}
void PWM_value_right(int pwm_set)
{
PWM_T2=pwm_set;
}
void main(void)
{
bit flag = 1;
uint n;
TMOD=0x22;
TH0=241;
TH1=241;
TL0=241;
TL1=241;
TR0=1;
TR1=1;
ET0=1;
ET1=1;
EA=1;
P1=0xf0;
delay(20);
PWM_value_left(7);
PWM_value_right(10);
delay(100);
PWM_value_left(8);
PWM_value_right(9);
delay(100);
PWM_value_left(9);
PWM_value_right(8);
delay(100);
PWM_value_left(10);
PWM_value_right(7);
}
timer0() interrupt 1 using 2
{
static uint t ;
t++;
if(t==10)
{
t=0;
p1_0=1;
p1_1=0;
}
if(PWM_T1==t)
P1=P1&0xfc;
}
timer1() interrupt 3
{
static uint t1 ;
t1++;
if(t1==10)
{
t1=0;
p1_2=1;
p1_3=0;
}
if(PWM_T2==t1)
P1=P1&0xf3;
}

答:没有主循环,
没有比及中止3
程序运转一次就跑飞了!!!

void main(void)
{
//…你的程序
//在这儿加 死循环,等候中止
while(1)
{
;
}
}
而且,中止呼应函数里有必要要清中止标志位(你的没有)!

3、各位大侠帮我看一下我写的51单片机C程序中止有没有问题,履行中止后不能持续履行主程序,注:P3.2口一向接
注:P3.2口一向接地,程序如下:
#include
sbit dula=P2^6;
sbit wela=P2^7;
sbit d0=P1^0;
sbit d1=P1^1;
sbit d2=P1^2;
sbit d3=P1^3;
sbit d4=P1^4;
sbit d5=P1^5;
sbit d6=P1^6;
sbit d7=P1^7;
#define uchar unsigned char
#define uint unsigned int
uchar num;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint z);
void main()
{
EA=1;
EX0=1;
IT0=0;
wela=1;
P0=0xc0;
wela=0;
while(1)
{

for(num=0;num<16;num++)
{
dula=1;
P0=table[num];
dula=0;
delay(1000);
}
}
}
void delay(uint z)
{
uint a,b;
for(a=z;a>0;a–)
for(b=110;b>0;b–);
}
void exter0() interrupt 0
{
uint c;
for(c=0;c<25000;c++);
d0=0;
for(c=0;c<25000;c++);
d0=1;
for(c=0;c<25000;c++);
d1=0;
for(c=0;c<25000;c++);
d1=1;
for(c=0;c<25000;c++);
d2=0;
for(c=0;c<25000;c++);
d2=1;
for(c=0;c<25000;c++);
d3=0;
for(c=0;c<25000;c++);
d3=1;
for(c=0;c<25000;c++);
d4=0;
for(c=0;c<25000;c++);
d4=1;
for(c=0;c<25000;c++);
d5=0;
for(c=0;c<25000;c++);
d5=1;
for(c=0;c<25000;c++);
d6=0;
for(c=0;c<25000;c++);
d6=1;
for(c=0;c<25000;c++);
d7=0;
for(c=0;c<25000;c++);
d7=1;

}
答:
IT0=0;//低电平触发,只需单片机监测到是低电平,就触发中止
你P3.2一向接地,一向是低电平,那中止就不断的履行,当然回不到主程序中了。
改成IT0=1;//下降沿触发,单片机监测到高电平到电平跳变,就触发中止
就算P3.2一向接地,也只触发一次,中止履行完了,就回到主程序中了。

4、我的单片机这个程序为什么不能彻底履行整个程序谁能告诉我!便是无法履行3次亮暗的!
2010-10-20 21:40 发问者:3865203bin3 | 悬赏分:10
ORG 0000H
AG:MOV A,#11111110B
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

我是想履行完流水灯亮.就然后履行全亮全暗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 |=(1<sei(); //敞开大局中止
TIMSK|=(1<TCNT0 =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秒左面的电动机滚动,一起黄灯亮,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==0&&keydeal==0)
{keynum=keyboard();
keybiao=1;
keydeal=1;
topen=0;//关延时计数
}//判别是否真有键按下,调用键盘扫描程序
else if(keybiao==0&&time1>=2&&keybiao1==0)
{EX0=1;
keyin=0;
topen=0;
}//假定没键按下,重开外部中止0,中止标志清0
}
if(keybiao==1&&keysign!=0)
{keybiao=0;
time1=0;
keybiao1=1;//为避免前一次time1的影响而设的标志
topen=1;
}

if(keybiao1==1&&time1>=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;//向主程序传递键按下
topen=1;//10ms延时计数开端
}
由于字数有限,有部分程序给删了,显现等部分程序应该没问题,我在其它当地能正常运转。

答:
不需求每次在进入中止程序后开一次中止;EX0=1能够去掉。
实践上,外部中止作业在边缘触发办法的时分,榜首次电平跳变触发后进入中止程序,然后硬件主动铲除IE0中止标志位。可是在履行中止程序的进程中,假定中止引脚再次检测到电平跳变(负到高),那么IE0会被再次置1 。假定在退出中止程序之前没及时清0,那么就会再次引发一次中止。
而按键的进程,不包括按下和松开时的电平颤动,至少会发生两次电平跳转。
因而,只需在你中止程序里恰当加一点推迟,再将EX=1, 改成IE0=0 。

12、我用的单片机是8051F的单片机,在程序中我用了两个中止。一个是守时计数器2发生的中止100MS一次的数据收集。另一个是向上位机发送收集来的数据,运用的串口来完结的,用的单片机的UART来完结。也是一个中止。这两个中止在一起作业时需求留意些什么?我的中止程序出了一些问题。
(便是默许状况下,UART的中止等级更高,可是有的时分UART的中止不能及时呼应,这是为甚?)
答:
之前和你做的相同就两个中止 UART0加一个守时器 我用的是C8051F040
你向上位机发送数据运用UART0时 要承认守时器作业完毕
T2守时中止后 你加一个完结标志如T2FLAG
if(T2FLAG==1) 将收集的数据放入 UART0的SBUF0 是UART0作业
你100ms的中止时刻 C8051这么快速的单片机怎样都该发送完结了吧。

13、MSP430单片机中止嵌套,怎样跳出中止?
当进行A中止时,来了一个B中止,我想让B中止程序履行完后不持续
履行A中止而跳出整个中止,去履行主程序,请问这个怎样设置呢?
答:
中止的时分会把SR状况跟中止下来要履行句子的地址放进仓库中,完结处理完中止今后cpu要履行的句子,留意是地址先进,SR后进,出栈时SR先出,地址后出,当然了在中止里面能够嵌套中止的,对可屏蔽中止来说,主要是CPU呼应中止今后,GIE会主动复位,所以不能对可屏蔽中止进行嵌套,假定在中止中要嵌套可屏蔽中止的话能够开GIE,但要留意的是假定此刻正在呼应的中止标志仍是置位的状况下会重复进入此中止,就像死循环相同,这时会引起仓库的溢出,而在呼应可屏蔽中止时,不行屏蔽中止不受此影响,由于他不受GIE的影响,只受自己独自的使能位影响。在仓库中的操作原理相似。

14、MSP430单片机有几个需求软件铲除的中止标志?怎样铲除?
(1)铲除各个端口的外中止用:PxIFG,相应的方位0即可;
(2)铲除Timer中止用:TAIFG,TBIFG,相应的方位0即可;
答:
MSP430的16个外中止比方软件铲除Flag,在进入外中止后,首要要做的便是把相应的PxIFG清0;
而守时器Timer中止是主动铲除Flag;
还有在中止嵌套的时分会用到,在进入中止后,MCU会主动把大局中止位GIE清零,这样在进入本中止后就不会再相应其他中止,若要进行中止嵌套,有必要在进入中止后把GIE再置1.

15、MCS-51系列单片机的有几个中止源?各中止标志是怎样发生的?怎样铲除各中止标志?
答:
规范51有5个中止向量(不算复位),别离是外部中止0,守时器0,外部中止1,守时器1,串行口;总共有6个中止标志,串行口的发送和承受同享一个中止向量。
各个终端标志发生状况如下:
外部中止能够设置边缘触发或许电平触发,边缘触发进入中止程序后硬件主动清中止标志,电平触发需求软件清标志位;
守时器T0,T1计数溢动身生中止,进入中止程序硬件主动清标志位;
串行口发送完结或许接纳到数据就触发中止,由所以两个中止标志同享一个中止向量,所以需求在中止程序里由软件判别是发送中止仍是承受中止,而且只能由软件清标志位;

以上是规范51的中止体系,52由于多了一个T2守时器(T2守时器跟T0,T1功用相差很大,T2要强壮许多),因而多了一个中止向量2个中止标志(溢出中止和T2外部中止),T2中止标志有必要由软件铲除标志位
中止使能坐落IE寄存器
各中止标志坐落相应的模块操控寄存器里面
模块 位位置 位称号 阐明
T1 TCON.7 TF1 T1溢出标志
T0 TCON.5 TF0 T0溢出标志
T2 T2CON.7 TF2 T2溢出中止标志
T2CON.6 EXF2 T2外部中止标志
外部中止1 TCON.3 IE1 外部中止1标志
外部中止0 TCON.1 IE0 外部中止0标志
串行口 SCON.1 TI 发送中止标志
SCON.0 RI 承受中止标志

16、MCS51单片机的汇编言语的中止服务程序最多有几个?
答:一般来说有5个对:2个外中止 ,2个守时器中止, 1个串口中止。
可是单片机的中止服务资源是依据硬件的结构设计,会有不同的数量和类型的中止服务,,,因而中止并不是对言语来讲的,而是关于硬件资源来讲的。比方52有6个中止。
依据言语编译器来讲,我就举例个人感觉最好的开发51大系列的开发环境Keil,其编译器最多支撑32个中止服务,,,,因而中止对编译来说,是一个“模仿”的概念。

17、单片机中止改动频率,为什么几个输出频率无法改动? 程序如下?
#include
#define uchar unsigned char
#define uint unsigned int
uchar T,t1;
unsigned char data table[5] = {486,236,151,111,86} ;
sbit CLK=P2^3 ;
sbit EN=P2^0 ;
void init();
void main()
{
init();
}
void init()
{
EN=1;
T=0;
TMOD=0x01;
EA=1;
TR0=1;
ET0=1;
t1=table[T];
TH0=(65536-t1)/256;
TL0=(65536-t1)%256;
}
void timer0() interrupt 1
{
TMOD=0x01;
EA=1;
TR0=1;
ET0=1;
t1=table[T];
TH0=(65536-t1)/256;
TL0=(65536-t1)%256;
CLK=~CLK;
}
答:
T你只付了0值,怎样会改动频率呢?你在主函数里加个T的赋值句子就行了,例如:while(T){T–;delay1s();}

18、单片机中止程序的书写过程?
答:
规范办法:
void 函数名(void)interrupt n using m
{函数体句子}
n —-中止编号
m—–要运用作业寄存器组号

19、我想知道单片机的蜂鸣器音乐程序中止是怎样呼应的?从main主程序中怎样到中止程序?详细过程是啥?谢谢!
#include
sbit speaker = P1^5;
unsigned char timer0h, timer0l, time;
//————————————–
//单片机晶振选用11.0592MHz
// 频率-半周期数据表 高八位 本软件共保存了四个八度的28个频率数据
code unsigned char FREQH[] = {
0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低声1234567
0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF}; //超高音 1234567
// 频率-半周期数据表 低八位
code unsigned char FREQL[] = {
0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低声1234567
0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567
0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16}; //超高音 1234567
//————————————–
//世上只需妈妈好数据表 要想演奏不同的乐曲, 只需求修正这个数据表
code unsigned char sszymmh[] = {5,1,1,5,1,1,6,1,2,5,1,2,1,2,2,7,1,4,5,1,1,5,1,1,6,1,2,5,1,2,2,2,2,1,2,4,
5,1,1,5,1,1,5,2,2,3,2,2,1,2,2,7,1,2
};
//————————————–
void t0int() interrupt 1 //T0中止程序,操控发音的腔调
{
TR0 = 0; //先封闭T0
speaker = !speaker; //输出方波, 发音
TH0 = timer0h; //下次的中止时刻, 这个时刻, 操控腔调凹凸
TL0 = timer0l;
TR0 = 1; //发动T0
}
//————————————–
void delay(unsigned char t) //延时程序,操控发音的时刻长度
{
unsigned char t1;
unsigned long t2;
for(t1 = 0; t1 < t; t1++) //两层循环, 共延时t个半拍
for(t2 = 0; t2 < 8000; t2++); //延时期间, 可进入T0中止去发音
TR0 = 0; //封闭T0, 中止发音
}
//————————————–
void song() //演奏一个音符
{
TH0 = timer0h; //操控腔调
TL0 = timer0l;
TR0 = 1; //发动T0, 由T0输出方波去发音
delay(time); //操控时刻长度
}
//————————————–
void main(void)
{
unsigned char k, i;
TMOD = 1; //置T0守时作业办法1
ET0 = 1; //开T0中止 IE=0x82;
EA = 1; //开CPU中止
while(1) {
i = 0;
time = 1;
while(time) {
k = sszymmh[i] + 7 * sszymmh[i + 1] – 1;
//第i个是音符, 第i+1个是第几个八度
timer0h = FREQH[k]; //从数据表中读出频率数值
timer0l = FREQL[k]; //实践上, 是守时的时刻长度
time = ssz
ymmh[i + 2]; //读出时刻长度数值
i += 3;
song(); //宣布一个音符
}
}
}
答:
你看main()函数就行了,首要进行k、i的界说,然后是界说中止的类型(程序顶用的是守时器中止),这个守时器有点特别,它的效果是界说频率的,频率距离小则腔调高,反之腔调低。这个频率便是时刻的倒数呗,所以TH的值越大,腔调越高;TL的值越小,腔调越低。接着往下走,while(1) 便是等候中止的意思,这个程序中的守时器中止没有设置初值,所以中止简直没有等候,不时触发(要是有等候时刻,音乐不就连不上了么)。综上:这个守时器中止完结两个使命:1、使单片机不时触发(等候时刻简直为0);2、操控了音符的演奏频率。
再往下 while(time) 的循环便是为演奏的音符赋值的操作了。

20、单片机中止该什么时分进如?
答:
中止看是外部中止、守时器仍是串行口中止了。
假定是外部中止,便是p3.2、p3.3检测到这两个口电平改动时(假定这两个口接上按键,那么当按键按下时标明发生中止),然后跳到中止程序履行。
假定是守时器中止的话,有个中止标志位TFx(x标明0或许1),比方说你设置一个1S的守时器程序,你以50ms为基准,20次发生1s的时刻,然后当50ms一过,标志位就发生改动,进入守时器中止程序履行!
串行口中止也是相同有一个标志位,承受或许发送数据满了今后,标志位就发生改动,然后进入中止履行!

21、PIC单片机AD中止什么时分敞开,对AD中止应该怎样了解。
答:
AD模数转化,是把模仿电压数值采样进来,然后转化成数字信号。这一采样和转化是需求时刻的。并不是一开AD就能读到数字信号数据。
一般来说其时刻都只需几微秒到几百微秒(依据设置不同而定)。假定单片机没有其他作业的时分,能够用循环等候的办法等AD转化完毕(转化完毕后DONE位会被置位)。但假定你的单片机还有其他作业,那就没必要在等候它上面花费时刻。能够开AD操作后,持续履行其他程序。而转化完毕后,AD中止能够暂时断开现有炒作,而把AD数据读进来。这便是AD中止的效果。

22\51单片机的五个中止别离在什么时分(什么状况)履行里面的程序!
答:
外部中止0 :P3.2口有低电平(IT0=0)/ 下降沿(IT0=1)。
外部中止1 :P3.3口有低电平(IT1=0)/ 下降沿(IT1=1)。
守时器0中止:当守时器0计数到FFFF溢出时
守时器1中止:当守时器1计数到FFFF溢出时
串口中止:串口接纳到一帧。或发送完一帧数据都会发生中止。
你网上找一下TCON和SCON。什么条件让中止标志位的值改动。 那么就会进入中止服务程序去。

23、51单片机,假定中止函数比较长,履行到一半又触发了这个中止,程序会中止从头履行,仍是履行完毕后呼应中
答:
51单片机中,中止分凹凸两个优先级,高优先级的中止能打断低优先级的中止。
但同级中止是不能打断同级中止的!不管该中止函数有多长,在履行到一半这个中止又发生了,仍是要比及该中止函数履行完毕,并再履行了一条主程序指令后才会再次进入该中止。
不过,若楼主刚好在这个低优先级中止服务程序中修正了该中止为高优先级,那么假定该中止函数比较长,履行到一半又触发了这个中止,则该中止函数就会被从头从头开端履行(中止嵌套)。这是由于除串口中止以外的其他中止,在 CPU 呼应该中止,程序转入该中止函数前就现已将该中止的中止标志清零了。
别的,51的串口中止比较特别,由于需求软件铲除串口中止标志,所以只需在未清串口中止标志前,是不会发生上述这样的中止嵌套的。

24、求51单片机程序,两个计数器,主要是中止函数的函数名以及初始化设置
答:
void into_into() interrupt 1 守时器0中止进口函数
{
。。。。中止服务程序。。。。
TH0=0;//
TL0=0;// 从头给T0赐值
}
void into_into() interrupt 3 守时器1中止进口函数
{
。。。。中止服务程序。。。。
TH1=0;//
TL1=0;// 从头给T1赐值
}
void to_to()
{
TMOD=0x11; //顶时器T0和T1作业办法1
TH0=0;//
TL0=0;// T0赐初值
TH1=0;//
TL1=0// T1赐初值
TR0=1;// 开端记数
ET0=1;// 答应T0中止
TR1=1;// 开端记数
ET1=1;// 答应T1中止
EA=1; // 翻开总中止
}
void main()
{
INIT_T0(); //守时器中止初始化
while(1)
{
………..
}

25、讨教一个单片机中止的问题:比方来了一个脉冲,开端中止,但中止里的程序履行到一半时,又来了一个脉冲,请问这时中止里的程序是从头开端呢仍是持续呢?
我的意思是程序就一个中止A,来了一个脉冲,A履行,A履行到一半时,又来了一个脉冲,告诉A履行。这时A是从头履行仍是先不理睬呢?
答:
需求详细状况详细剖析,由于不同的单片机在中止机制上有纤细的不同,需求查他的材料。
一般来说,一个中止源恳求中止,对CPU来说,是一次性的做了一个“中止挂号”。假定其时因条件不满足(例如CPU正在“关中止”,即没有翻开“中止答应”),而没有呼应中止,则挂号信息还在,这样,将来一旦翻开了中止答应,依然会呼应,仅仅晚了一点罢了。
而中止呼应今后,有必要有办法把这个“中止挂号”消除去。有的CPU的功用是:只需呼应了这个中止,挂号就主动消除了。也有的CPU不能主动铲除挂号,有必要在中止服务程序中编入“铲除中止挂号”的操作,不然,一旦翻开了中止答应,它又会重复发生中止。

现在的大多数单片机里,中止操控器和CPU是在同一个芯片中,它能够做到主动消除中止挂号。而曩昔许多种CPU,所配用的中止操控器是别的一个芯片,天然就无法主动消除了。

也有的CPU中有别的一种“不挂号”的中止恳求。它有必要由外界(宣布中止恳求的那个设备)来坚持一向不断恳求,比及呼应中止的时分,再设法(例如,在中止服务程序中宣布一个输出信号)告诉那个设备吊销恳求。

大多数的CPU中,一旦呼应中止进入了服务程序,就把“中止答应”关掉了。故此刻假定又有下一个中止恳求来了,不能当即呼应,只能挂一个号,等今后“开中止”时才干再呼应。假定程序员期望能够“嵌套中止”(即在一次中止服务程序的履行半途又进入了另一个中止服务程序),就需求在服务程序内编入“开中止”的操作。

“嵌套中止”原则上答应“自己嵌套自己”,也便是说,一次中止服务程序的履行半途又被打断并进入了和自己相同的中止服务程序,并自始至终履行一遍,完毕后回来到从前打断的那一点,并持续履行后半截服务程序。这种状况会发生什么效果,是需求程序员自己考虑的。

也有的CPU具有“优先次第”机制,能够在某一级的中止服务程序里制止优先级不比自己高的其他中止来打断自己。一起,也提供给程序员有“抛弃优先权”以及“修正优先级”的灵活性。
而被优先机制暂时“屏蔽”的那些较低优先级的中止恳求,相同挂号仍在,今后高优先级的中止完毕今后,还能呼应。

不过需求留意,大多数的CPU中,“中止挂号”是只能挂一个的。也便是说,在前一次的中止恳求所挂的号还没有被铲除曾经,又来了下一个中止恳求,那么,第二个挂号是挂不上的。

不过某些处理器中,中止挂号或许分红几个层次:CPU里面是一层,外围针对各个详细的设备,还有别的一级“准备挂号”,那就比较杂乱了。

别的多说几句:上面现已说,程序员能够自己决议你的中止服务程序答应仍是不答应“嵌套”。

假定不答应,您能够选用关中止的办法,或许运用优先机制,来屏蔽同一中止源的第二个中止恳求。
这样,第二个中止就不会被呼应。但它仍能够挂上一个号(只需它发生在上一个中止挂号现已被铲除去今后的时刻)。然后,中止服务程序完毕时,一般都会开中止并开释优先级屏蔽。然后,第二个中止恳求就会被呼应,所以再一次履行中止服务程序。

假定答应“嵌套”,那就会如我上面所说:
一次中止服务程序的履行半途又被打断并进入了和自己相同的中止服务程序,并自始至终履行一遍,完毕后回来到从前打断的那一点,并持续履行后半截服务程序。

26、我用51单片机守时/计数器1计数为什么不计数?想让它记数发生中止让蜂鸣器响。
sbit fengming=P1^6;
void main()
{
TMOD=0x50;
EA=1;
ET1=1;
TH1=0xff;//来一次中止记一次数
TL1=0xff;
TR1=1;
}
void time1(void) interrupt 3
{
fengming=0;
}

答:
不知道是你在网页上打错了,仍是怎样回事。
void time1(void) interrupt 3——-》void timer1(void) interrupt 3

主程序最终,要加个死循环:while(1){};

还有,你在这用了办法1,这个办法在你进中止后,TH1和TL1会变成0000H。你不对他从头赋值,你要等FFFFH次计数,才会进中止。

27\MCS-51 单片机守时器/计数器1的中止进口地址是: 一共有四个A. 0003H B. 000BH C. 0013H D. 001BH,到底是是哪一个?
\答:答案是D.1BH
由于:
外中止0——03h
守时器0——0bh
外中止1——13h
守时器1——1bh
串口———23h
请背熟

28、我看许多程序都是主程序进入while(1),就死在while(1)里了,然后等候外中止。那么现在的问题是我想让它进入外中止完过后,越过while(1),履行下边的程序,该怎样办?
while里面用break吗?不知道好使欠好使,还有标志位我看是硬件主动清零,查询标志应该不能用吧,那该怎样办呢?
答:
完毕while(1)句子最好的办法便是运用break来跳出死循环,要害便是挑选适宜的flag(标志位),假定说中止标志位是硬件主动清零的话,那么楼主无妨在中止服务子程序中自己参加一个标志位:假定用汇编言语的话,PSW中的F0位就能够很好的运用;假定用C的话,就能够随意界说一个位变量,如bit a=0;。也便是说,楼主需求在程序中界说一个位变量a,在中止服务子程序中将a置1,退出中止后查询a是否为1,例如:if(a) {a=0;break;}这样就跳出了while句子了。
比方说,假定楼主想写一个等候按键按下中止的程序,就能够用while(!a);而不用while(1)句子了。

29、我用外部中止1,中止一次显现下一个数,数码管显现没问题。可是我用P3-3口用导线衔接,触摸一次地线,松开一次,这时分数码管显现会乱跳,有时分加两次数,有时分加好多次数,横竖便是不稳定。假定p3-3口经过按键接地的话,按一次按键一般状况会加一次数,但有时分也是不稳定,或许中止好几次。
程序如下:
#include
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar times;
uchar i=0;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x–)
for(y=112;y>0;y–);
}

void main()
{

EA=1;
EX1=1;
IT1=1;
while(1)
{
P1=table[i];
P2=0x00;
}
}

void into() interrupt 2
{ delay(1000);
i++;
if(i==10) i=1;

}

答:
是颤动的问题。
应该采撤销抖办法,硬件、软件办法皆可。
—-
楼主在中止函数中,延时,时刻看来很是不短!
可是延时后,并没有检测按键是否还在按下,这就不能算是软件消抖。

30、 (1) 为什么单片机有两个外部中止0答应位?有什么效果?
(2)在51内核单片机中,当答应呼应外部中止0的中止恳求时,其特别功用寄存器ie中的位有必要为1 es exo ea et0?

答:
(1)两个中止是由于一般的单片机有两个中止源,能够完结两级中止嵌套,在完结杂乱功用上两级中止嵌套很有用。

(2)
EA–总中止答应位,有必要为1
ES–串行中止答应位,不用开,为0
EX0–外部中止0答应位,应为1
ET0–守时计数溢出中止答应位,不用开,为0

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/319773.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部