LT8920是一超便宜的2.4GHz无线芯片,用来做小东西非常不错,废话不多说,直接上代码
#include "stc8_spi.h"
#include <intrins.h>
#include "lt8920.h"
#include "delay.h"
#include <stdio.h>
#include <string.h>
xdata u8 tx_buff[tx_buff_size];
data u8 rx_buff[rx_buff_size]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
xdata u8 RF_channel = 0;
xdata u8 address[8];
code u8 SyncAddr[8] = {'U','A','V','I','H','O','M','E'};
extern xdata float rcPitch, rcRoll , rcYaw,rcThrottle;
/*
struct LT8920_init_reg
{
u8 reg_addr;
u8 reg_data_h;
u8 reg_data_l;
};
struct LT8920_init_reg const LT8920_reg[] =
{ //Power-up reset value, Recommended value, Notes
{ 0, 0x6f, 0xe0 },//0x6fef, 0x6fe0
{ 1, 0x56, 0x81 },//0x5681, 0x5681
{ 2, 0x66, 0x17 },//0x6619, 0x6617
{ 4, 0x9c, 0xc9 },//0x5447, 0x9cc9
{ 5, 0x66, 0x37 },//0xf000, 0x6637
{ 7, 0x00, 0x30 },//0x0030, 0x0030,(2402MHz) Use for setting RF frequency, and to start/stop Tx/Rx packets;
{ 8, 0x6c, 0x90 },//0x71af, 0x6c90
{ 9, 0x48, 0x00 },//0x3000, 0x1840, Sets Tx power level, PA -12.2dbm,1840?
{10, 0x7f, 0xfd },//0x7fdd, 0x7fdd, Crystal osc.enabled.
{11, 0x00, 0x08 },//0x4008, 0x0008, RSSI enabled
{12, 0x00, 0x00 },//0x0000, 0x0000
{13, 0x48, 0xbd },//0x4855, 0x48bd
{22, 0x00, 0xff },//0xcoff, 0x00ff
{23, 0x80, 0x05 },//0x8005, 0x8005, Calibrate VCO before each and every Tx/Rx.
{24, 0x00, 0x67 },//0x307b, 0x0067
{25, 0x16, 0x59 },//0x1659, 0x1659
{26, 0x19, 0xe0 },//0x1883, 0x19e0
{27, 0x13, 0x00 },//0x9100, 0x1300, No crystal trim
{28, 0x18, 0x00 },//0x1800, 0x1800
//29, 0000x0, read-only, Stores p/n, version information
//30, 0xf413, read-only, Stores p/n, version information
//31, 0x1002, read-only, Stores p/n, version information
{32, 0x1a, 0x00 },//0x1806, 0x4800, Packet data type: NRZ, no FEC, BRCKL = 12div.by4=3MHz //1 byte preamble_len,64bit addr,bit trailer
{33, 0x3f, 0xc7 },//0x6307, 0x3fc7, Configures packet sequencing
{34, 0x20, 0x00 },//0x030b, 0x2000, Configures packet sequencing
{35, 0x05, 0x00 },//0x1300, 0x0300, AutoACK max Tx retries = 3//-- ReSend Timer=10?4?
{36, 'U', 'A' },//Choose unique sync words
{37, 'V', 'I' },//for each over-the-air
{38, 'H', 'O' },//network.
{39, 'M', 'E' },//Similar to a MAC address
{40, 0x44, 0x02 },//0x2107, 0x2102, Configure FIFO flag, sync threshold.
{41, 0xBC, 0x00 },//0xb800, 0xb000, CRC is ON, scramble is OFF, AUTO_ACK Enable, PKT Low Active
{42, 0xFD, 0xb0 },//0xfd6b, 0xfdb0, AutoACK off ??RX_ACK?? 176us
{43, 0x00, 0x0f },//0x000f, 0x000f, Configure scan_rssi.
{44, 0x01, 0x00 },//0x0100, 0x1000, Configure data rate
{45, 0x05, 0x52 },//0x0080, 0x0552, -- 62.5 kpbs
{50, 0x00, 0x00 }
};
*/
void LT8920_WREG(u8 addr, u8 reg_h, u8 reg_l)
{
SS = 0;
_nop_();
//send address
SPI(addr);
//send data
SPI(reg_h);
SPI(reg_l);
SS = 1;
}
//u16 LT8920_RREG(u8 addr)
//{
// u16 temp;
// u16 dat;
// SS = 0;
// //send address
// SPI(0x80 + addr);
// //read data
// temp = SPI(0xff);
// dat = temp << 8;
// temp = SPI(0xff);
// dat |= temp;
// SS = 1;
// return dat;
//}
//void FIFO_Write(u8 dat[], u8 len)
//{
// u8 n;
// if((len == 0) || (len > 64)) return;
// SS = 0;
// SPI(TXRX_FIFO_REG & WRITE_REG);
// SPI(len);
// for(n = 0; n < len; n++)
// {
// SPI(dat[n]);
// }
// SS = 1;
//}
u8 FIFO_Read(u8 dat[], u8 len)
{
u8 temp;
u8 n;
if(len > 64) return 0;
SS = 0;
SPI(TXRX_FIFO_REG | READ_REG);
temp = SPI(0xff);//len
for(n = 0; n <len; n++)
{
dat[n] = SPI(0xff);
}
SS = 1;
return temp;
}
//set rx or rx and RF channel
#define TX_EN 0x01
#define RX_EN 0x80
//enter tx mode, and set RF channel
//void LT8920_Tx_Frq(u8 ch)
//{
// if(ch > 0x3f)return;
// LT8920_WREG(7 , TX_EN, ch);//f = 2402 + ch
//}
//enter tx mode, and set RF channel
void LT8920_Rx_Frq(u8 ch)
{
if(ch > 0x3f)return;
LT8920_WREG(7 , 0x00, RX_EN + ch);//f = 2402 + ch
}
void LT8920_Address(u8 mac[])
{
LT8920_WREG(36, mac[0], mac[1]);
LT8920_WREG(37, mac[2], mac[3]);
LT8920_WREG(38, mac[4], mac[5]);
LT8920_WREG(39, mac[6], mac[7]);
}
//void LT8920_TxRx_OFF()
//{
// LT8920_WREG(7 , 0x00, 0x00);
//}
void LT8920_FIFO_CLP()//clear FIFO point
{
LT8920_WREG(52, 0x80, 0x80);
}
#define RAW_RSSI_ADDR 6
//u16 Get_RSSI_Value()
//{
// u16 rssi;
// rssi = LT8920_RREG(RAW_RSSI_ADDR);
// return (rssi >> 11);
//}
bit CRC_ERROR = 0;
bit FEC23_ERROR = 0;
u8 FRAMER_ST = 0;
bit SYNCWORD_RECV = 0;
bit PKT_FLAG = 0;
bit FIFO_FLAG = 0;
//void Get_RF_Status()
//{
// u16 temp;
// temp = LT8920_RREG(48);
// CRC_ERROR = temp & 0x8000;
// FEC23_ERROR = temp & 0x4000;
// FRAMER_ST = (temp >> 8) && 0xc0;
// SYNCWORD_RECV = temp & 0x0080;
// PKT_FLAG = temp & 0x0040;
// FIFO_FLAG = temp & 0x0020;
//}
//u16 Get_RF_ID_Ver() //address:29,30,31
//{
// u16 idv;
// idv = LT8920_RREG(30);
// return idv;
//}
void LT8920_Init()
{
SS = 1;
SCLK = 0;
RST_N = 0; //关闭芯片,电流<1uA,数字部分的值会失去
delay_ms(2);
RST_N = 1; //开启芯片,寄存器回复复位值
delay_ms(6);
LT8920_WREG(0, 0x6f, 0xe0);
LT8920_WREG(1, 0x56, 0x81);
LT8920_WREG(2, 0x66, 0x17);
LT8920_WREG(4, 0x9c, 0xc9);
LT8920_WREG(5, 0x66, 0x37);
// LT8920_WREG(7, 0x00, 0x30);//use for setting RF frequency, and to start/stop Tx/Rx packets
LT8920_WREG(8, 0x6c, 0x90);
LT8920_WREG(9, 0x18, 0x40);//set Tx power level
LT8920_WREG(10, 0x7f, 0xfd);//Crystal osc. enabled
LT8920_WREG(11, 0x00, 0x08);//RSSI enabled.
LT8920_WREG(12, 0x00, 0x00);
LT8920_WREG(13, 0x48, 0xbd);
LT8920_WREG(22, 0x00, 0xff);
LT8920_WREG(23, 0x80, 0x05);//Calibrate VCO before each and every Tx/Rx
LT8920_WREG(24, 0x00, 0x67);
LT8920_WREG(25, 0x16, 0x59);
LT8920_WREG(26, 0x19, 0xe0);
LT8920_WREG(27, 0x13, 0x00);//no crystal trim
LT8920_WREG(28, 0x18, 0x00);
LT8920_WREG(32, 0x48, 0x00);//3byte preabmle len,32bits MAC, 4bits trailer, Packet data type:NRZ, no FEC, BRCLK=12 div.by4=3MHz
LT8920_WREG(33, 0x3f, 0xc7);//Configure packet sequencing
LT8920_WREG(34, 0x20, 0x00);//Configure packet sequencing
LT8920_WREG(35, 0x03, 0x00);//AutoAck max Tx retries = 3
LT8920_WREG(36, address[0], address[1]);//MAC address
LT8920_WREG(37, address[2], address[3]);
// LT8920_WREG(38, address[4], address[5]);
// LT8920_WREG(39, address[6], address[7]);
LT8920_WREG(40, 0x21, 0x02);//Configure FIFO flag, sync threshold
LT8920_WREG(41, 0xb0, 0x00);//CRC on. SCRAMBLE off. 1st byte is packet length
LT8920_WREG(42, 0xfd, 0xb0);//AutoACK off.
LT8920_WREG(43, 0x00, 0x0f);//Configure sacn_rssi
LT8920_WREG(44, 0x04, 0x00);//Configure data rate: 1Mbps
LT8920_WREG(45, 0x05, 0x52);
LT8920_WREG(52, 0x80, 0x80);//清空FIFO读写指针,不清空数据
memset(rx_data, 0, rx_buff_size);
}
xdata int rx_data[9];
bit SW1 = 1;
bit SW2 = 1;
bit SW3 = 1;
bit SW4 = 1;
bit SW5 = 1;
bit SW6 = 1;
bit SW7 = 1;
bit SW8 = 1;
bit key1 = 1;
bit key2 = 1;
bit key3 = 1;
bit key4 = 1;
bit key5 = 1;
bit key6 = 1;
bit ch5 = 0;
bit ch6 = 0;
//code u8 signal_error_cnt = 0;
void rx_data_handle()
{
if(rx_buff[0] == 0xdc)//帧头
{
u8 check = 0;
u8 check2 = 0;
rx_buff[0] = 0;
check = (rx_buff[1]+rx_buff[2]+rx_buff[3]+rx_buff[4]+rx_buff[5]+rx_buff[6]+rx_buff[7]+rx_buff[8]+rx_buff[9]);
check2 = (rx_buff[10]+rx_buff[11]+rx_buff[12]+rx_buff[13]+rx_buff[14]+rx_buff[17]+rx_buff[18]);
if((check == rx_buff[16]) && (check2 == rx_buff[15]))//各通道和校验,每一个字节都要校验,不校验误码率高
{
rx_cnt ++;
rx_data[0] = rx_buff[1] * 256 + rx_buff[2]; //rc adc0 battery
rx_data[1] = rx_buff[3] * 256 + rx_buff[4]; //rc adc1 right rocker ↑↓
rx_data[2] = rx_buff[5] * 256 + rx_buff[6]; //rc adc2 right rocker ←→
rx_data[3] = rx_buff[7] * 256 + rx_buff[8]; //rc adc3 left rocker ↑↓
rx_data[4] = rx_buff[9] * 256 + rx_buff[10]; //rc adc4 left rocker ←→
rx_data[5] = rx_buff[11] * 256 + rx_buff[12];//rc adc5
rx_data[6] = rx_buff[13] * 256 + rx_buff[14];//rc adc6
rx_data[7] = rx_buff[15] * 256 + rx_buff[16];//rc adc7
rx_data[8] = rx_buff[17] * 256 + rx_buff[18];//key & sw
SW1 = rx_buff[17] & 0x80;
SW2 = rx_buff[17] & 0x40;
SW3 = rx_buff[17] & 0x20;
SW4 = rx_buff[17] & 0x10;
SW5 = rx_buff[17] & 0x08;
SW6 = rx_buff[17] & 0x04;
SW7 = rx_buff[17] & 0x02;
SW8 = rx_buff[17] & 0x01;
key1 = rx_buff[18] & 0x80;
key2 = rx_buff[18] & 0x40;
key3 = rx_buff[18] & 0x20;
key4 = rx_buff[18] & 0x10;
key5 = rx_buff[18] & 0x08;
key6 = rx_buff[18] & 0x04;
ch5 = rx_buff[18] & 0x02;
ch6 = rx_buff[18] & 0x01;
rcPitch = (float)(rx_data[1] - 2048)/104.8;//限制最大倾角为+-2048/102.4 = 10度
rcRoll = (float)(rx_data[2] - 2048)/104.8;
rcThrottle = (float)rx_data[3] / 4.096;//1000
rcYaw = (float)(rx_data[4] - 2048)/104.8;
if((rx_data[1] > 2000) && (rx_data[1] < 2100)) rcPitch = 0;//限制摇杆启动范围
if((rx_data[2] > 2000) && (rx_data[2] < 2100)) rcRoll = 0;
// if((rx_data[3] > 2000) && (rx_data[3] < 2100)) rcThrottle = 0;
if((rx_data[4] > 2000) && (rx_data[4] < 2100)) rcYaw = 0;
memset(rx_buff, 0, rx_buff_size);
}
}
}
void rx_data_out()
{
// uart1_sendByte(0x03);
// uart1_sendByte(0xfc);
// uart1_sendByte(rx_buff[1]);
// uart1_sendByte(rx_buff[0]);
// uart1_sendByte(rx_buff[3]);
// uart1_sendByte(rx_buff[2]);
// uart1_sendByte(rx_buff[5]);
// uart1_sendByte(rx_buff[4]);
// uart1_sendByte(rx_buff[7]);
// uart1_sendByte(rx_buff[6]);
// uart1_sendByte(rx_buff[9]);
// uart1_sendByte(rx_buff[8]);
// uart1_sendByte(rx_buff[11]);
// uart1_sendByte(rx_buff[10]);
// uart1_sendByte(rx_buff[13]);
// uart1_sendByte(rx_buff[12]);
// uart1_sendByte(rx_buff[15]);
// uart1_sendByte(rx_buff[14]);
// uart1_sendByte(rx_buff[17]);
// uart1_sendByte(rx_buff[17]);
// uart1_sendByte(rx_buff[18]);
// uart1_sendByte(0xfc);
// uart1_sendByte(0x03);
printf("Rx:%d R0:%u R1:%u R2:%u R3:%u R4:%u R5:%u R6:%u R7:%u R8:%x\n",(int)signal_cnt,
rx_data[0],rx_data[1],rx_data[2],rx_data[3],rx_data[4],rx_data[5],rx_data[6],rx_data[7],rx_data[8]);
}