在DIP STC89C58RC+能正常工作 但在QFP STC11F16XE卻不行 能寫進 別的功能都正常 只是進不了中斷 請高人指點下問題出在那里 下面是原程序
#include "AT89x52.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit WuXian_IN = P3^2;
sbit OK_LED = P1^7;
//=========================================================================
void InitTimer0(void)
{
TMOD = 0x11; //定時器1,定時器0用模式1 16位計時用,12T
EA = 1; //全部中斷使能
ET0=1; //定時器中斷使能
}
//========================================================================
void delay(uchar z)
{
uchar x,y;
for(x=z;z>0;z--)
for(y=200;y>0;y--);
}
void main(void)
{
InitTimer0();
WuXian_IN=0;
// IT0=0; //電平解發方式
EX0 = 1; //外部中斷使能
// EA=1; //允許外部中斷0中斷
while(1);
}
//========================================================================
void ex0(void) interrupt 0
{
//PT2262發碼為窄高+寬低+窄高+寬低=0 /寬高+窄低+寬高+窄低=1 /窄高+寬低+寬高+窄低=F
//數值表示: 00 = 0 / 11 = 1 / 01 = F
//反碼表示: 11 = 0 / 00 = 1 / 10 = F(本例所用)
bit err = 0;
uchar I = 0; //用來記錄位數,正常會收到24位
uchar TL,TH; //用來記錄每位的低電平總時長
uchar MA1,MA2,MA3; //用來記錄地址碼(占16位)和鍵碼(占8位)
uchar TimeCount;
uint L,M;
EX0 = 0; //暫停外部中斷
TR1 = 1; //啟動定時器計數器1
if(TimeCount > 0) //當按鍵按下釋放后該值不在賦值就同通過遞減直到該值等于0
{
TimeCount--; //等于0后表示按鍵釋放
}
while(WuXian_IN == 0); //如果為0一直等待,等待高電平出現 P3.2
while(I < 24) //共接收24位
{
while(WuXian_IN == 0); //等待高電平到來
TL = TL1;
TH = TH1;
TH1 = TL1 = 0; //記錄低電平長度并初始化高電平頭
L = TH;
L = ((L << 8) + TL); //將計時器的高低8位合并
if(I == 0) //處理同步位
{
if(L > 2360) //確認是引導頭(判斷同步位低電平時長31a)
{
M = L / 31; //M即4a亦即是窄電平的時長
}
else //不符合規則(出錯)
{
I = TR1 = TH1 = TL1 = 0;
err = 1;
break;
}
}
else
{
//短555 長1666
//4.7M的振蕩電阻時同步位的低電平時長為L=15378uS;即31a
//4.7M的振蕩電阻時窄電平時長為M=492uS;即4a
//4.7M的振蕩電阻時寬電平時長為1488uS即12a
//以下語句即判斷窄電平與寬電平的寬度是否合格
if(((L < M - M / 4) && (L > M + M / 4)) || ((L < M * 3 - M / 2) && (L > M * 3 + M / 2)))
{//如果窄電平小于4a與大小4a或寬電平小于12a與大小12a則表示出錯
I = TR1 = TH1 = TL1 = 0;
err = 1;
break;
}
}
while(WuXian_IN == 1); //等待低電平到來
TH = TH1;
TL = TL1;
TH1 = TL1 = 0;
L = TH;
L = ((L << 8) + TL); //將計時器的高低8位合并
//以下語句即判斷是窄電平是否合格(4.7M的振蕩電阻時窄電平時長為492uS即4a)
if(((L > (M - M / 4)) && (L < (M + M / 4))))//如果此時為4a則本位為0 短492uS
{
I++;
MA1 <<= 1; //本位置0
}
//以下語句即判斷寬電平是否合格(4.7M的振蕩電阻時寬電平時長為1488uS即12a)
else if(((L > (M * 3 - M / 2)) && (L < (M * 3 + M / 2))))////如果此時為12a則本位為1 長1488uS
{
I++;
MA1 <<= 1;
MA1++; //本位置1
}
else //已不是4a也不是12a則不符合規表示出錯
{
I = 0;
TR1 = TH1 = TL1 = 0;
err = 1;
break;
}
if(I == 8)
{
MA3 = MA1; //每二位對應PT2262的一個引腳,bit7/bit6二位對應PT2262的1腳,類推
//對應PT2262的1~4腳 / 11 = 接+ / 00 = 接地 / 01 = 懸空
//P1 = MA3; //送P1口顯示方便調試
}
if(I == 16)
{
MA2 = MA1; //每二位對應PT2262的一個引腳,bit7/bit6二位對應PT2262的5腳,類推
//對應PT2262的5~8腳 / 11 = 接+ / 00 = 接地 / 01 = 懸空
//P0 = MA2; //送P1口顯示方便調試
}
if(I == 24) //24位已收完則解碼結束
{
if(TimeCount == 0) //為0表示是新的一次按下對其進行處理,如過該值大于0表示已經按下不在處理
{
switch(MA1)
{
case 0xC0: //PT2262的10腳按鍵按下時
P1_0 = ~P1_0;
delay(10);
P1_0 = ~P1_0;
break;
case 0x30: //PT2262的11腳按鍵按下時
P1_1 = ~P1_1;
delay(10);
P1_1 = ~P1_1;
break;
case 0x0C: //PT2262的12腳按鍵按下時
P1_2 = ~P1_2;
delay(10);
P1_2 = ~P1_2;
break;
case 0x03: //PT2262的13腳按鍵按下時
P1_3 = ~P1_3;
delay(10);
P1_3 = ~P1_3;
break;
}
}
OK_LED = !OK_LED; //解碼正確后取反一次
delay(200);
TimeCount = 30; //PT2262每按一次會發出4組相同的編碼防止按鍵沒放開直在取反,保證按1次只做1次處理
}
}
TR1 = TH1 = TL1 = 0;
EX0 = 1;
}
|