代碼如下
#include<reg52.h>
#include<intrins.h>
//#define GUDING //固定失控值/自由自定
#define u8 unsigned char
#define u16 unsigned int //*******晶振設(shè)定*******//
#define u32 unsigned long int //內(nèi)置 12Mhz 16Mhz 24Mhz//
#define WZ12Mhz 1 // 0 1 0 0 //
#define WZ16Mhz 0 // 0 0 1 0 //
#define WZ24Mhz 0 // 0 0 0 1 //
sfr IAP_DATA=0xc2; //**********************//
sfr IAP_ADDRH=0xc3;
sfr IAP_ADDRL=0xc4;
sfr IAP_CMD=0xc5;
sfr IAP_TRIG=0xc6;
sfr IAP_CONTR=0xc7;
sfr P1M0=0x92;//單片機IO口配置寄存器地址
sfr P3M0=0xb2;
//定義指示燈
sbit LED=P3^0;
sbit bind=P3^7;
//定義8個通道輸出
sbit CH1=P1^7;
sbit CH2=P1^6;
sbit CH3=P1^5;
sbit CH4=P1^4;
sbit CH5=P1^3;
sbit CH6=P1^2;
sbit CH7=P1^1;
sbit CH8=P1^0;
//定義無線模塊的管腳
sbit GIO=P3^2;
sbit MDI=P3^3;
sbit SCK=P3^4;
sbit CSN=P3^5;
u8 code A7105_regs[]={ //模塊寄存器設(shè)定表
0xff, 0x42, 0x00, 0x14, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x00, 0x50,
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x0f,
0x13, 0xc3, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00,
0x01, 0x0f, 0xff,
};
u8 code tx_channels[16][16]={ //跳頻表
{0x0a, 0x5a, 0x14, 0x64, 0x1e, 0x6e, 0x28, 0x78, 0x32, 0x82, 0x3c, 0x8c, 0x46, 0x96, 0x50, 0xa0},
{0xa0, 0x50, 0x96, 0x46, 0x8c, 0x3c, 0x82, 0x32, 0x78, 0x28, 0x6e, 0x1e, 0x64, 0x14, 0x5a, 0x0a},
{0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x46, 0x96, 0x1e, 0x6e, 0x3c, 0x8c, 0x28, 0x78, 0x32, 0x82},
{0x82, 0x32, 0x78, 0x28, 0x8c, 0x3c, 0x6e, 0x1e, 0x96, 0x46, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a},
{0x28, 0x78, 0x0a, 0x5a, 0x50, 0xa0, 0x14, 0x64, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96},
{0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x64, 0x14, 0xa0, 0x50, 0x5a, 0x0a, 0x78, 0x28},
{0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x3c, 0x8c, 0x32, 0x82, 0x46, 0x96, 0x14, 0x64},
{0x64, 0x14, 0x96, 0x46, 0x82, 0x32, 0x8c, 0x3c, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50},
{0x50, 0xa0, 0x46, 0x96, 0x3c, 0x8c, 0x28, 0x78, 0x0a, 0x5a, 0x32, 0x82, 0x1e, 0x6e, 0x14, 0x64},
{0x64, 0x14, 0x6e, 0x1e, 0x82, 0x32, 0x5a, 0x0a, 0x78, 0x28, 0x8c, 0x3c, 0x96, 0x46, 0xa0, 0x50},
{0x46, 0x96, 0x3c, 0x8c, 0x50, 0xa0, 0x28, 0x78, 0x0a, 0x5a, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64},
{0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x5a, 0x0a, 0x78, 0x28, 0xa0, 0x50, 0x8c, 0x3c, 0x96, 0x46},
{0x46, 0x96, 0x0a, 0x5a, 0x3c, 0x8c, 0x14, 0x64, 0x50, 0xa0, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82},
{0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0xa0, 0x50, 0x64, 0x14, 0x8c, 0x3c, 0x5a, 0x0a, 0x96, 0x46},
{0x46, 0x96, 0x0a, 0x5a, 0x50, 0xa0, 0x3c, 0x8c, 0x28, 0x78, 0x1e, 0x6e, 0x32, 0x82, 0x14, 0x64},
{0x64, 0x14, 0x82, 0x32, 0x6e, 0x1e, 0x78, 0x28, 0x8c, 0x3c, 0xa0, 0x50, 0x5a, 0x0a, 0x96, 0x46},
};
u32 id; //對碼ID
u8 chanrow,chancol,chanoffset,channel;
u8 txid[21]={0,0,0,0,0,220,5,220,5,232,3,220,5,220,5,220,5,220,5,220,5};
u8 packet[21];
u8 Htemp[8]={5,5,3,5,5,5,5,5};
u8 Ltemp[8]={220,220,232,220,220,220,220,220};
u8 ch=0;
u16 mss;
bit hch,cb;
#if WZ12Mhz //延時定義
void Delay1ms(){ //@12.000MHz
unsigned char i, j;
_nop_();
_nop_();
i = 10;
j = 83;
do
{
while (--j);
} while (--i);
}
#elif WZ16Mhz
void Delay1ms(){ //@18.432MHz
unsigned char i, j;
_nop_();
_nop_();
i = 18;
j = 234;
do{
while (--j);
} while (--i);
}
#elif WZ24Mhz
void Delay1ms(){ //@24.000MHz
unsigned char i, j;
_nop_();
_nop_();
i = 24;
j = 84;
do{
while (--j);
} while (--i);
}
#else
void Delay1ms() { //@5.5296MHz
unsigned char i, j;
_nop_();
_nop_();
i = 6;
j = 93;
do{
while (--j);
} while (--i);
}
#endif
void delay_ms(u16 i){
while(i--)
Delay1ms();
}
void IapIdle(){
IAP_CONTR = 0; //Close IAP function
IAP_CMD = 0; //Clear command to standby
IAP_TRIG = 0; //Clear trigger register
IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
IAP_ADDRL = 0; //Clear IAP address to prevent misuse
}
u8 EEPROM_read(u8 addr){
u8 dat; //Data buffer
IAP_CONTR = 0x82; //Open IAP function, and set wait time
IAP_CMD = 0x01; //Set ISP/IAP/EEPROM READ command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = 0; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
dat = IAP_DATA; //Read ISP/IAP/EEPROM data
IapIdle(); //Close ISP/IAP/EEPROM function
return dat; //Return Flash data
}
void EEPROM_write(u8 addr,u8 dat){
IAP_CONTR = 0x82; //Open IAP function, and set wait time
IAP_CMD = 0x02; //Set ISP/IAP/EEPROM PROGRAM command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = 0; //Set ISP/IAP/EEPROM address high
IAP_DATA = dat; //Write ISP/IAP/EEPROM data
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
void EEPROM_clean(u8 addr){
IAP_CONTR = 0x82; //Open IAP function, and set wait time
IAP_CMD = 0x03; //Set ISP/IAP/EEPROM ERASE command
IAP_ADDRL = 0; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
void IDWR(bit wr){ // 1:保存 0:讀取
u8 i;
if(wr)EEPROM_clean(0),delay_ms(10);
for(i=0;i<21;i++){
if(wr){
EEPROM_write(i,txid[i]); }
// txid[i]=packet[i];}
else txid[i]=EEPROM_read(i);
}
}
void SPIwrite(u8 command){ //時序?qū)?br />
u8 n=8;
SCK=0;MDI=0;
while(n--) {
if(command&0x80)MDI=1;
else MDI=0;
SCK=1;_nop_();SCK=0;
command = command << 1;
}
MDI=1;
}
u8 SPIread(void){ //時序讀
u8 i,result=0;
for(i=0;i<8;i++) {
if(MDI==1)result=(result<<1)|0x01;
else result=result<<1;
SCK=1;_nop_();SCK=0;_nop_();
}return result;
}
void AREG_write(u8 address, u8 dat){//寫寄存器
CSN=0;
SPIwrite(address);
_nop_();
SPIwrite(dat);
CSN=1;
}
u8 AREG_read(u8 address){ //讀寄存器
u8 result;
CSN=0;
address |=0x40;
SPIwrite(address);
result = SPIread();
CSN=1;
return(result);
}
void A7105_WriteID(u32 ida) { //寫模塊ID
CSN=0;
SPIwrite(0x06);
SPIwrite((ida>>24)&0xff);
SPIwrite((ida>>16)&0xff);
SPIwrite((ida>>8)&0xff);
SPIwrite((ida>>0)&0xff);
CSN=1;
}
void Read_Packet(){ //讀數(shù)據(jù)包
u8 i;
CSN=0;
SPIwrite(0x45);
for (i=0;i<21;i++)packet[i]=SPIread();
CSN=1;
}
void Strobe(u8 address){ //模塊設(shè)定
CSN=0;
SPIwrite(address);
CSN=1;
}
void bind_Flysky(){ //對頻
u8 i,counter1=255;
Strobe(0xA0);
Strobe(0xF0);
AREG_write(0x0F,0x00);//比發(fā)射低一頻道
Strobe(0xC0);
while(counter1){
delay_ms(10);
if(counter1&0x04)LED=1;
else LED=0;
if(GIO==0){
if((AREG_read(0x00)&0x60)==0){
Read_Packet();
// IDWR(1);//保存ID
for(i=0;i<21;i++)txid[i]=packet[i];
break;
}
else{
Strobe(0xA0);
Strobe(0xF0);
AREG_write(0x0F,0x00);
Strobe(0xC0);
continue;
}
}
else{
--counter1;
if (counter1==0)counter1=255;
}
}
}
void flysky_cb(){ //主循環(huán)
u8 i,x;
channel=tx_channels[chanrow][chancol]-chanoffset;//跳頻道
channel-=1;
Strobe(0xA0);
Strobe(0xF0);
AREG_write(0x0F,channel);//設(shè)定頻道
Strobe(0xC0);
chancol=(chancol+1)%16;
while(1){
if(mss>800){ //無信號1.5s后失控保護
#ifdef GUDING
Ltemp[2]=232;Htemp[2]=3;
#endif
for(i=0;i<8;i++){
#ifdef GUDING
if(i==2)continue;
Ltemp[i]=220;
Htemp[i]=5;
#else
Ltemp[i]=txid[2*i+5];
Htemp[i]=txid[2*i+6];
#endif
}
}
if(hch){ //大于2ms加跳
hch=0;LED=0;
chancol=(chancol+1)%16;
// channel=tx_channels[chanrow][chancol]-1-chanoffset;
break;
}
if (GIO==1)continue;
x=AREG_read(0x00);
if(x&0x60)continue;//數(shù)據(jù)檢驗
Read_Packet();//讀遙控數(shù)據(jù) ↓↓↓↓↓匹配ID
if (!(packet[1]==txid[1])&&!(packet[2]==txid[2])&&!(packet[3]==txid[3])&&!(packet[4]==txid[4]))continue;
mss=0;
if(cb){
for (i=0;i<8;i++){//輸出 1000~2000
EA=0;
x=packet[6+(2*i)];
if((x>=3)&&(x<=8) ){ //防止溢出
Ltemp[i]=packet[5+(2*i)];
Htemp[i]=x;
}
EA=1;
}
}
if(cb)LED=1;
break;
}
}
void flysky_init(){ //初始化
u8 i,k;
u16 HT;
P1M0=0xff;
P3M0=0x41;
TMOD=0x11;
IE=0x8a;
bind=1;CSN=1;MDI=1;SCK=0;
delay_ms(10);
AREG_write(0x00,0x00);
A7105_WriteID(0x5475c52A);
for (i = 0; i < 0x33; i++){
if(A7105_regs[i] != 0xff)
AREG_write(i, A7105_regs[i]);
}
Strobe(0xA0);
AREG_write(0x02,0x01);
while(AREG_read(0x02));
AREG_write(0x24,0x13);
AREG_write(0x26,0x3b);
AREG_write(0x0F,0x00);
AREG_write(0x02,0x02);
while(AREG_read(0x02));
AREG_write(0x0F,0xA0);
AREG_write(0x02,0x02);
while(AREG_read(0x02));
AREG_write(0x25,0x08);
Strobe(0xA0);
while(1){
LED=1;
delay_ms(500);
LED=0;
delay_ms(500);
if(bind==1){
IDWR(0); //讀取ID
cb=1;
if(txid[0]==0xaa)break;
else continue;
}
else{
bind_Flysky();//對頻
LED=1;
delay_ms(500);
LED=0;
delay_ms(500);
TR0=TR1=1;
cb=0;
break;
}
} //↓↓↓↓↓↓↓↓合拼ID
id=(txid[1]|((u32)txid[2]<<8)|((u32)txid[3]<<16)|((u32)txid[4]<<24));
chanrow=id%16;
chanoffset=(id&0xff)/16;
chancol=0;
if(chanoffset>9)chanoffset=9;
while(TR0){
if(bind){IDWR(1);LED=0;TR0=TR1=0;while(1){LED=1;delay_ms(1000);LED=0;delay_ms(1500);};}
flysky_cb();//4:1024 5:1280 6:1536 7:1792 8:2048
if(mss>5){mss=0;
for(i=0;i<8;i++){
if((i>3)||(i==2)){
Ltemp[i]=txid[2*i+5]=packet[2*i+5];
Htemp[i]=txid[2*i+6]=packet[2*i+6];
continue;
}
if((packet[2*i+6]<5)||(packet[2*i+6]>6)){
if(k&(1<<i)){k&=(0xfe<<i);LED=1;
HT=(u16)txid[2*i+5]|(u16)(txid[2*i+6]<<8);
if(packet[2*i+6]<5){if(HT>900)HT-=100;}
else if(HT<2000)HT+=100;
Ltemp[i]=txid[2*i+5]=HT&0xff;
Htemp[i]=txid[2*i+6]=(HT>>8)&0xff;}
}
else k|=(1<<i);
}
}
}
}
void main(){
flysky_init();
TR0=1; //跳頻定時器
TR1=1; //輸出定時器
while(1)flysky_cb();
}
void et0()interrupt 1{ //加跳定時器
#if WZ12Mhz
TH0 =248;TL0 =50; //@12Mhz 2ms +2
#elif WZ16Mhz
TH0 =244;TL0 =72; //@16Mhz 2ms
#elif WZ24Mhz
TH0 =240;TL0 =96; //@24Mhz 2ms
#else
TH0 =252;TL0 =102; //@5.5Mhz 2ms
#endif
hch=1;
mss++;
}
void et1()interrupt 3{ //輸出定時器
#if WZ12Mhz
#else
u16 HT;
#endif
P1=0;//全低電平
#if WZ12Mhz
TH1=255-Htemp[ch]; //252 3
TL1=255-Ltemp[ch]; //23 232
#elif WZ16Mhz
HT=(u16)Htemp[ch]<<8;
HT+=Ltemp[ch];
HT*=1.3;
TH1=255-(HT>>8);
TL1=255-(HT&0xff);
#elif WZ24Mhz
HT=(u16)Htemp[ch]<<8;
HT+=Ltemp[ch];
HT<<=1;
TH1=255-(HT>>8);
TL1=255-(HT&0xff);
#else
HT=(u16)Htemp[ch]<<8;
HT+=Ltemp[ch];
HT>>=1;
HT-=30;
TH1=255-(HT>>8);
TL1=255-(HT&0xff);
// TH1=255-(Htemp[ch]>>1);
// TL1=255-(Ltemp[ch]>>1);
// TH1=(65536-HT)>>8;
// TL1=(65536-HT)&0xff;
#endif
switch (ch) {
case 0: CH1=1;break;
case 1: CH2=1;break;
case 2: CH3=1;break;
case 3: CH4=1;break;
case 4: CH5=1;break;
case 5: CH6=1;break;
case 6: CH7=1;break;
case 7: CH8=1;break;
}
if(ch < 7)ch++;//8通道循環(huán)
else ch=0;
// }
/* else{ //PPM
if(CH5){
CH5=0; //0.4ms低電平
TH1=254;
TL1=112;
}
else{
CH5=1;
if(ch ==8){
ch = 0;
TH1=((22100-calc_rest)>>8)&0xff;
TL1=(22100-calc_rest)&0xff;
calc_rest=0;
}
else{
Servo_data[ch]-=400;
TL1=255-(Servo_data[ch]&0xff);
TH1=255-((Servo_data[ch]>>8)&0xff); //252 3
calc_rest+=Servo_data[ch];
ch++;
}
}
} */
}
|