#include<STC15W408AS.H>
#include<intrins.h> //包含_nop_()函數定義的頭文件
#define uchar unsigned char
#define uint unsigned int
//#define CCP_S0 0x10 //P_SW1.4
//#define CCP_S1 0x20 //P_SW1.5
#define LED_Port P1
#define CMD_IDLE 0 //空閑模式
#define CMD_READ 1 //IAP字節讀命令
#define CMD_PROGRAM 2 //IAP字節編程命令
#define CMD_ERASE 3 //IAP扇區擦除命令
//#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
//#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
#define IAP_ADDRESS 0x0000 //測試地址
sbit led1 = P1^4;
sbit led2 = P1^3;
sbit led3 = P1^2;
//sbit led4 = P3^3;
//sbit led5 = P1^3; //p1.3
//sbit led6 = P3^1;
//sbit led7 = P3^0;
//sbit led8 = P1^7;
//sbit led9 = P5^5;
//sbit led10= P5^4;
//sbit IRIN=P3^2; //紅外接收器數據線
sbit IR_Out = P3^2;
uchar num,sum,mode;
sbit IR_Flag = P1^1;
unsigned char dat[4] = {0,0,0,0};
void led();
void key();
void IapIdle();
uchar IapReadByte(uint addr);
void IapProgramByte(uint addr, uchar dat);
void IapEraseSector(uint addr);
void delay(uint z)
{
uint x,y;
for(x=0;x<50;x++)
for(y=z;y>0;y--);
}
void main()
{
P1M0=0xFF;
P1M1=0x00;
P3M0=0x00;
P3M1=0x00;
P5M0=0xFF;
P5M1=0x00;
ACC = P_SW1;
//ACC &= ~(CCP_S0|CCP_S1); //CCP_S0=0 CCP_S1=0
P_SW1 = ACC; //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
CCON = 0; //初始化PCA控制寄存器
//PCA定時器停止
//清除CF標志
//清除模塊中斷標志
CL = 0; //復位PCA寄存器
CH = 0;
CMOD = 0x02; //設置PCA時鐘源
//禁止PCA定時器溢出中斷
PCA_PWM0 = 0x00; //PCA模塊0工作于8位PWM
CCAP0H = CCAP0L = 0xFF; //PWM0的占空比為87.5% ((100H-20H)/100H)
CCAPM0 = 0x42; //PCA模塊0為8位PWM模式
CR = 1; //PCA定時器開始工作
//EA =1;
//EX0=1;
//IT0=1;
//IRIN=1;
IR_Out = 1;
TMOD = 0x01; // 定時器0,方式1
IT0 = 1; // 外部中斷0,下降沿觸發
EX0 = 1; // 準許外部中斷
EA = 1; // CPU準許中斷
led1=led2=led3=0;
//sum=IapReadByte(0x0010);
//num=IapReadByte(0x0020);
mode=IapReadByte(0x0030);
while(1)
{
key();
switch(mode)
{
case 0x01:led1=led2=led3=0;break;
case 0x02:CCAP0H = CCAP0L = 0x00;led();key();break;
case 0x03:CCAP0H = CCAP0L = 0x96;led();key();break;
case 0x04:CCAP0H = CCAP0L = 0xD2;led();key();break;
default :led1=led2=led3=0;break;
}
}
}
void Int0() interrupt 0
{
unsigned char i,j;
EX0 = 0; // 關閉外部中斷0
IR_Flag = 0; // 執行中斷程序時,LED燈亮
i = 10; // 0.793ms延時,運行10次
while( --i )
{
TH0 = 0xfc; // 定時0.793ms,延時0.793ms*10=7.93ms
TL0 = 0xe7;
TR0 = 1;
while( !TF0 );
TF0 = 0;
TR0 = 0; // 這7.93ms期間只要IR_Out變高電平,就非合法的紅外信號,跳出
if( IR_Out )
{
EX0 = 1; // 準許中斷
return ;
}
}
// 程序進行到這里,表明是合法的紅外信號(利用9ms判斷)
while( !IR_Out ); // 等待9ms低電平過去
// 程序進行到這里,表明經過9ms低電平
TH0 = 0xf6;
TL0 = 0xff;
TR0 = 1;
while( !TF0 );
TF0 = 0;
TR0 = 0; // 延時2.305ms
// IR_Out 為低表明是連發碼,不予理睬,跳出
if( !IR_Out )
{
EX0=1;
return;
}
// 程序進行到這里,表明是引導碼,等待4.5ms高電平的過去
while( IR_Out );
for(i=0; i<4; i++) // 開始接收用戶碼
{
for(j=0; j<8; j++)
{
while( !IR_Out ); // 等待低電平過去
dat[i] >>= 1; // 把上次的數據位右移一位
TH0 = 0xfc;
TL0 = 0xe7;
TR0 = 1;
while( !TF0 );
TR0=0;
TF0=0; //延時0.793ms
// 若為數據"1",則延時后IR_Out為高電平
if( IR_Out )
{
dat[i] |= 0x80; // 所有數據位1放最高位
while( IR_Out );// 等待高電平過去
}
}
}
//LED_Port = dat[2];
num = dat[2];
EX0=1; // 開中斷
return;
}
給一個給你參考下,最近我弄的,芯片是用STC15W408AS 內部頻率110.592M |