51單片機中斷細節的一些問題。
interrupt0:外部中斷0
interrupt1:定時器中斷0
interrupt2:外部中斷
interrupt3:定時器中斷1
interrupt4:串口
using 0 是第0組寄存器; using 1 是第1組寄存器; using 2 是第2組寄存器; using 3 是第3組寄存器;
51單片機內的寄存器是R0--R7(不是R0-R3)
R0-R7在數據存儲器里的實際地址是由特殊功能寄存器PSW里的RS1、RS0位決定的。
using 0時設置 RS1=0,RS0 =0,用第0組寄存器,R0--R7的在數據存儲區里的實際地址是00H-07H。R0(00H)....R7(07H)
using 1時設置 RS1=0,RS0 =1,用第1組寄存器,R0--R7的在數據存儲區里的實際地址是00H-07H。R0(08H)....R7(0FH)
using 2時設置 RS1=1,RS0 =0,用第2組寄存器,R0--R7的在數據存儲區里的實際地址是08H-0FH。R0(10H)....R7(17H)
using 3時設置 RS1=1,RS0 =1,用第3組寄存器,R0--R7的在數據存儲區里的實際地址是00H-07H。R0(18H)....R7(1FH)
EA是總中斷允許位,
EX是外部中斷允許位
ET是內部定時器/計數器中斷允許位,
TR定時器/計數器啟動位,它們都是高電平1有效。
TH、TL分別指定時器/計數器的高8位和低8位(后面加0/1表示定時器/計數器0/1,如TH0=255表示給定時器0的高八位賦初值255)。
這里附上SG90舵機的中斷程序:
/********TIME0中斷服務程序************/
void Time0_Int(void) interrupt 1 {
TH0 = (65536 - 92)/256;
TL0 = (65536 - 92)%256; //重裝初值
if(Time0_OutCounter < Angle0) //判斷0.1ms的次數是否小於角度標識
PWM0 = 1;
else
PWM0 = 0;
Time0_OutCounter = Time0_OutCounter+1; //溢出標志位:加1 //次數始終保持為200,即保持周期為20ms
if(Time0_OutCounter == 200)
{
Time0_OutCounter = 0;
flag0 = 1; //一個周期結束標志 }
else flag0 = 0;
}
void Timer0_Init( void ) { TMOD=0x01; //定時器0工作於方式1:16位定時器
TH0 = (65536 - 92)/256;
TL0 = (65536 - 92)%256; ////裝入初值:定時0.1ms溢出,晶振為11.0592MHz
EA = 1; //開總中斷
ET0 = 1; //允許定時器0中斷
TR0 = 1; //開定時器0 }
void MostLeft_Servo0( void ) {
unsigned char i;
for(i=21;i>=6;i--)
{ while(flag0 != 1);
Angle0 = i;
Time0_OutCounter = 0;
}
}
void Servo0_Init( void )
{ Timer0_Init(); }
//舵機右滿舵
void MostRight_Servo0( void )
{ unsigned char i;
for(i=6;i<=21;i++)
{
while(flag0 != 1);
Angle0 = i;
Time0_OutCounter = 0; }
}
void delay10ms(unsigned int x)
{
unsigned int i;
while(x--)for(i=0;i<125;i++);
}