各位大侠,小弟最近在使用ax5051射频芯片进行收发通讯,目前遇到下面两个问题:
1、接受每次开机接收数据的时候都要重新软件复位才行,不知道是什么原因。
2、在发送完转化接收的时候前面两包数据会丢失,收不到数据,不知道什么原因造成的,有大神是否愿意指导,如果方便也可以进行合作形式。谢谢!!
代码如下:
#include <ax8052f151.h>
#include <libmftypes.h>
#include <libmfradio.h>
#include <libmfflash.h>
#include <libmfwtimer.h>
#include <libmfuart0.h>
#include "../COMMON/uart.h"
//#include "../COMMON/adc_example.h"
/*********定义AX5051PWRMODE寄存器各种模式*****************/
#define POWERDOWN 0
#define VREGON 4
#define STANDBY 5
#define SYNTHRX 8
#define FULLRX 9
#define SYNTHTX 0X0C
#define FULLTX 0X0D
#define ADC_BUFFER_SIZE 40
#define TX_PREAMBLE 29
/*************定义DMA相关的参数*************/
struct DMA_descriptor{
void __xdata *bufaddr;
uint16_t buflen;
uint16_t actlen;
struct DMA_descriptor __xdata *bdaddr;
};
volatile __bit dmaflag;
uint8_t __xdata adcbuffer[ADC_BUFFER_SIZE];//定义ADC采样的数据存放数组
static __xdata struct DMA_descriptor dma_bd_adc;
//void start_DMA1 (struct DMA_descriptor * descriptor);
static __xdata struct DMA_descriptor dma_bd_adc;
uint8_t tx_count=0;
uint8_t chushi_tx_count=0;
static __autodata enum
{
axirq_idle,
axirq_hdlctxidle,
axirq_hdlctxpreamble,
axirq_txsync,
axirq_hdlctxpacket,
axirq_hdlctxcrc,
axirq_hdlctxpostamble,
axirq_hdlcrxidle,
axirq_hdlcrxpacket,
axirq_hdlcrxend,
axirq_wait
} axirq_state;
//***********接收-发送模切换***************
static __autodata enum
{
tx_queue, //准备启动发送
txrx_working, //正在发送或接收过程中
rx_queue,
} txrx_state; //准备启动接收
uint8_t timercount=0;
uint8_t timerbiaozhi=0;
static int8_t __autodata axirq_count;
uint8_t __xdata axirq_packet_tx[47]={0x00};
uint8_t axirq_packet_R[47]={0};
const uint8_t __code axradio_phy_preamble_txsynclen = 3;
const uint8_t __code axradio_phy_preamble_txsync[4] = { 0x55, 0x66, 0xaa, 0xcc };
const uint8_t __code axradio_phy_postamblelen = 5;
const uint8_t __code axradio_phy_postamble[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
uint8_t __autodata F;
/*********选择AX5051PWRMODE寄存器各种模式*****************/
void AX5051_powermode(uint8_t mode)
{
AX5051_PWRMODE = (mode&0xFF);
}
/**********延时函数*******/
void delay_1(uint32_t t)
{
while(t--);
}
/*********radio初始化*******************/
//#include "radiodefs.h"
__reentrantb uint8_t radio_reset_1(void) __reentrant
{
//uint8_t i;
RADIOFDATAADDR0 = 0x005 & 0xFF;
RADIOFDATAADDR1 = 0x0000;
RADIOFSTATADDR0 = 0x004 & 0xFF;
RADIOFSTATADDR1 = 0x0000 ;
return 1;
}
//******************************/
/***********AX8052单片机初始化配置**************/
void ax8052_set_registers(void)
{
GPIOENABLE = 0x00; //0000 0000 保持当前状态
DIRA = 0x00; //0000 0000
DIRB = 0x00; //0000 0000
DIRC = 0x00; //0000 0000
DIRR = 0x15; //0001 0101
PORTA = 0x00; //0000 0000
PORTB = 0x00; //0000 0000
PORTC = 0x00; //0000 0000
PORTR = 0xCB; //1100 1011
ANALOGA = 0x03; //0000 0011 PA0、PA1外接晶振
PALTA = 0x00; //0000 0000 不使能T0OUT、OC1、OC0、T1OUT、COMPO0、U1TX、T2OUT、COMPO1
PALTB = 0x00; //0000 0000 不使能U1TX、OC1、T2OUT、OC0、U0TX、T1OUT
PALTC = 0x00; //0000 0000 不使能T0OUT、COMPO1、U0TX、COMPO0、COMPO1
PINSEL = 0x00; //0000 0000
RADIOMUX = 0x4f; //0000 0111 PR0被OFF,IQO为PR5口,无线晶振源PC4口,PR0、PR2、PR3、PR4为射频的SPI端口 手册是错误的
RADIOACC = 0x00; //0000 0000 射频数据通道宽度为8bit,地址通道宽度为7bit,当前通道读,RC空闲
INTCHGA = 0x00; //0000 0000 端口中断控制
INTCHGB = 0x00; //0000 0000 端口中断控制
INTCHGC = 0x00; //0000 0000 端口中断控制
FRCOSCCONFIG = 0x08; //0000 1000 快速晶振源,晶振×2
FRCOSCKFILT = 0x00; //0000 0000
FRCOSCREF = 0x00; //0000 0000
LPOSCCONFIG = 0x41; //0100 0001 低功耗晶振源为FRCOSC,并×2,晶振为10.24KHz
LPOSCKFILT = 0x00; //0000 0000
LPOSCREF = 0x00; //0000 0000
WDTCFG = 0x00; //0000 0000
CLKCON = 0x00; //0000 0000 系统时钟源为FRCOSC,分频÷1,周期OFF
EXTIRQ = 0x00; //0000 0000 外部中断0,PB0,高电平有效,外部中断1,高电平有效,PB3引脚
GPIOENABLE = 0x01; //0000 0000
}
void ax8052_setup(void)
{
DPS = 0x00; //0000 0000 数据指针为DPTR0
PCON = 0x0C; //0000 1100 四轴飞行器模式,
IP = 0x00; //0000 0000 各个中断无优先级别
EIP = 0x00; //0000 0000 各个中断无优先级别
E2IP = 0x00; //0000 0000 各个中断无优先级别
LPXOSCGM = 0x00; //0000 0000 电容配置
}
/*************************AX5051相关参数初始化配置****************/
void AX5051_INIT(void)
{
AX5051_XTALOSC = 0x03; //0000 0011 表示晶振跨导为4ms
AX5051_IFMODE = 0x00; //0000 0000 必须设置为0000
AX5051_PINCFG1 = 0xf1; //1111 0001 SYSCLK静态输出为高电平,IRQ为输入
AX5051_PINCFG2 = 0xC0; //1100 0000 IRQI高电平中断,IRQE含中断信号,TST_PINS必须为11
AX5051_MODULATION = 0x04; //0000 0100 采用PSK调制模式
AX5051_ENCODING = 0x02; //0000 0010 不翻转数据,使能差分的编码/解码数据,不使能扰频器/解码器,不使能曼切斯特编码/解码
AX5051_FRAMING = 0x76; //0111 0110 不中断当前HDLC包,用RAW帧匹配模式,帧长为32位,接收查询帧/HDLC标志
AX5051_FREQ3 = 0x26; //0010 0110 载波频率915MHz,外接晶振24MHz
AX5051_FREQ2 = 0x20; //0010 0000 载波频率915MHz,外接晶振24MHz
AX5051_FREQ1 = 0x00; //0000 0000 载波频率915MHz,外接晶振24MHz
AX5051_FREQ0 = 0x01; //0000 0001 载波频率915MHz,外接晶振24MHz 最低位为1
AX5051_PLLLOOP = 0x05; //0000 0101 标准带宽50KHz,启动时间50us,发送/接收开关时间30us
AX5051_PLLRNGCLK = 0x03; //0000 0011 没找到对应的寄存器
AX5051_MODMISC = 0x03; //0000 0011 发送自动使能
AX5051_XTALCAP = 0x25; //0010 0101 晶振电容20pF
AX5051_PLLVCOI = 0x01; //0000 0001 VOC_I必须为001
AX5051_RFMISC = 0xB0; //1011 0000 没找到对应的寄存器
AX5051_REF = 0x23; //0010 0011 主模式参考电流,低功耗必须设置为0x25
AX5051_RXMISC = 0x35; //0011 0101 必须设置为0011 0101
AX5051_IFFREQHI = 0x15; //0001 0101 设置IF频率
AX5051_IFFREQLO = 0xD8; //1101 1000 设置IF频率
AX5051_PHASEGAIN = 0x03; //0000 0011 PSK模式相位跟踪循环为3
AX5051_FREQGAIN = 0x06; //0000 0110 PSK模式频率跟踪循环为6
AX5051_FREQGAIN2 = 0x06; //0000 0110 PSK模式频率跟踪循环为6
AX5051_AMPLGAIN = 0x06; //0000 0110 PSK模式振幅跟踪循环为6
AX5051_AGCATTACK = 0x14; //0001 0100 设置AGC增益减低速度为62500dB/s
AX5051_AGCDECAY = 0x11; //0001 0001 设置AGC增益加低速度为6250dB/s
}
/**************AX5051发送相关参数初始化配置***************/
void AX5051_TX_INIT(void)
{
AX5051_RFMISC = 0x80;
AX5051_FSKDEV2 = 0x00; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_FSKDEV1 = 0x00; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_FSKDEV0 = 0x00; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_TXPWR = 0x0F; //0000 1111 发送输出功率
AX5051_TXRATEHI = 0x02; //0000 0010 设定发送比特率250kbit/s,外接晶振24MHz
AX5051_TXRATEMID = 0xAA; //1010 1010 设定发送比特率250kbit/s,外接晶振24MHz
AX5051_TXRATELO = 0xAB; //1010 1011 设定发送比特率250kbit/s,外接晶振24MHz
}
/******************AX5051接收相关参数初始化配置*****************/
void AX5051_RX_INIT(void)
{
AX5051_FSKDEV2 = 0x66; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_FSKDEV1 = 0x66; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_FSKDEV0 = 0x02; //0000 0000 设置PSK频率偏移,h=0,所以为0
AX5051_ADCMISC = 0x01; //0000 0001 没找到对应的寄存器
AX5051_AGCTARGET = 0x0E; //0000 1110 没找到对应的寄存器
AX5051_AGCCOUNTER = 0x00; //0000 0000 接收信号长度RSSI1=38
AX5051_CICDECLO = 0x0F; //0000 1111 设置数字通道宽度为15
AX5051_DATARATEHI = 0x19; //0001 1001 设置数据速率为6554
AX5051_DATARATELO = 0x9A; //1001 1010 设置数据速率为6554
AX5051_TMGGAINHI = 0x00; //0000 0000 接收时间复位进取设置为205
AX5051_TMGGAINLO = 0xCD; //1100 1101 接收时间复位进取设置为205
AX5051_CRCINIT3 = 0x55; //0101 0101 设置CRC计算结果复位
AX5051_CRCINIT2 = 0x66; //0110 0110 设置CRC计算结果复位
AX5051_CRCINIT1 = 0xAA; //1010 1010 设置CRC计算结果复位
AX5051_CRCINIT0 = 0xCC; //1100 1100 设置CRC计算结果复位1432791756
}
/*******************PLLRANGING自动校正**************/
uint8_t ax5051_pllrange_1(uint8_t range)
{
uint8_t __autodata r, rcount = 10;
AX5051_PLLRANGING = (0x10 | (range & 0x0f)); // start value typical 0x08
do
{
delay_1(2000);
r = AX5051_PLLRANGING;
if (!(r & 0x10))
break;
} while (--rcount);
r &= 0x3F;
return r;
}
/*******发送头帧*************/
void set_ax5051_TX(void) __reentrant // initializes the TX process
{
AX5051_powermode(FULLTX); // REF=ON, OSC=ON, Synthesizer and tx running
delay_1(500);
//AX5051_FIFOCONTROL = 0x03; // prepare for preamble sending. Do not before RX direction is set
AX5051_FIFOCONTROL2 = 0x80; // AX5051_FIFOCONTROL2=0x80 clear FIFO
AX5051_FIFODATA = 0xFF;
AX5051_FIFODATA = 0xFF;
AX5051_FIFODATA = 0xFF;
AX5051_FIFODATA = 0xFF;
axirq_count = TX_PREAMBLE;
axirq_state=axirq_hdlctxpreamble; // start sending preambles
// txrx_state=tx_queue;
AX5051_IRQMASK = 0x02; //AX5051_IRQMASK=0x01 interrupt when fifo not full
PORTR |=0x20;//enable RIRQ
EA=1;
IE |= 0x10; // enable AX5051 IRQ
return;
}
/***************接收函数************/
void set_ax5051_RX(void) __reentrant // initializes the RX process
{
AX5051_powermode(FULLRX);
delay_1(500);
axirq_state=axirq_hdlcrxidle; // start to search a delimiter, the preamble is done by the AX5051 !!!
F =AX5051_FIFODATA;
F = AX5051_FIFODATA;
F = AX5051_FIFODATA;
F = AX5051_FIFODATA;
AX5051_IRQMASK = 0x01;
PORTR |=0x20;//enable RIRQ
EA=1;
IE |= 0x10; // enable AX5051 IRQ
return;
} // end set_ax5051_RX
/*******************DMA地址指向及通道置位****************/
void start_DMA1 (struct DMA_descriptor * descriptor){
DMA1ADDR = (uint16_t) descriptor;
DMA1CONFIG |= 0x80;
}
/***************ADC初始化设置******************/
void adc_init(void){
ADCCLKSRC =0x36;
ADCCH0CONFIG = 0xD9;
ADCTUNE0 = 0x01;
ADCTUNE1 = 0x06;
ADCTUNE2 = 0x00;
ADCCONV = 0x07;
DMA1CONFIG = 0x14;
PCON = 0x44;
LPXOSCGM = 0x8a;
LPOSCCONFIG = 0x41;
FRCOSCCONFIG = 0x08;
//GPIOENABLE = 0x01;
dmaflag = 0;
dma_bd_adc.bufaddr = adcbuffer;
dma_bd_adc.buflen = sizeof(adcbuffer) | 0x8000;
dma_bd_adc.actlen = sizeof(adcbuffer) | 0x8000;
dma_bd_adc.bdaddr = (struct DMA_descriptor __xdata *)0xffff;
EIE_7 = 1;
start_DMA1 (&dma_bd_adc);
}
/**********************ADC函数体******************/
uint32_t adc_work(void)
{
uint32_t vddio;
uint16_t i;
if (dmaflag)
{
vddio = 0;
for (i=0; i<ADC_BUFFER_SIZE; i++)
{
axirq_packet_tx[i+5] = adcbuffer;
}
dmaflag= 0;
return vddio;// 1;
}
return 0;
}
/****************DMA中断函数*****************/
void dma_irq(void) __interrupt INT_DMA
{
EIE_7 = 0;
DMA1CONFIG;
dmaflag = 1;
}
//1s定义原理 定时器计数1个数的时间 64/(24000000) 64分频
void timer_init(void)
{
DIRC = 0x07;
//DIRA |= 0x03;
ANALOGA |= 0x03;
T2CLKSRC = 0x3a;//0xB6;
T2MODE = 0x44;//0x43
//T0CNT=0X0080;
T2PERIOD =0X001;//0x3D09;//0x7a12;// //0xFFFF;////0xF424;
// T0STATUS = 0x40;
T2CNT=0X0BDa;
PCON = 0x44;
LPXOSCGM = 0x8a;
// LPOSCCONFIG = 0x41;
FRCOSCCONFIG = 0x33;
DPS =0;
//EA=1;
//EIE_2 = 1;
LPXOSCGM = 0x88;
GPIOENABLE = 0x03;
}
//***********定时器中断**********************
void timer_irq(void) __interrupt INT_TIMER2
{
PORTC_1=!PORTC_1;
timercount++;
EIE_2 = 0;
if(timercount==6)//6是1ms T2CNT=0X0BDa
{
timerbiaozhi=1;
timercount=0;
// PORTC_1 =1;
}
T2CNT=0X0BDa;
T2STATUS;
EIE_2 = 1;
}
/**********主函数****************/
void main(void)
{
// uint16_t u;
AX5051_powermode(STANDBY);
ax8052_set_registers();
ax8052_setup();
flash_apply_calibration();
uart0_trx_int();
adc_init();
timer_init();
radio_reset_1();
delay_1(720000);
AX5051_INIT();
AX5051_TX_INIT();
AX5051_RX_INIT();
AX5051_powermode(SYNTHTX);
AX5051_PLLRANGING=ax5051_pllrange_1(0x08);//设置pllranging选择VCO
axirq_state=axirq_hdlctxidle;//axirq_hdlcrxend;//接收初始流程
//axirq_state=axirq_hdlctxpreamble;//发送初始流程
txrx_state=tx_queue;
//txrx_state=rx_queue;
EA=1;
EIE_2 = 1;
while(1)
{
if(timerbiaozhi==1)
{
timerbiaozhi=0;
/*****************发送*********************/
if(txrx_state==tx_queue)
{
// AX5051_powermode(SYNTHTX);
AX5051_TX_INIT();
EA=1;
EIE_7=1;
start_DMA1 (&dma_bd_adc);
adc_work();
txrx_state=txrx_working;
axirq_packet_tx[0]=0x2d;
axirq_packet_tx[1]=0x33;
axirq_packet_tx[2]=0x34;
axirq_packet_tx[3]=0x00;
axirq_packet_tx[4]=0x01;
axirq_packet_tx[43]=chushi_tx_count;
axirq_packet_tx[44]=tx_count++;
axirq_packet_tx[45]=0xbb;
axirq_packet_tx[46]=0xcc;
delay_1(60000);
AX5051_powermode(SYNTHTX);
delay_1(60);
set_ax5051_TX();
}
/***************接收****************/
else if(txrx_state==rx_queue)
{
AX5051_RX_INIT();
AX5051_powermode(SYNTHRX);
txrx_state=txrx_working;
// rxdelaytimer=0;
delay_1(60);
set_ax5051_RX();
}
}
}
}
/**********************AX5051发送接收中断********************/
__interruptb(INT_RADIO) void axradio_isr(void) __interrupt(INT_RADIO)
{
register uint16_t w;
register uint8_t d;
PORTC_0=0;
//**************发送流程********************
switch (axirq_state)
{
case axirq_idle:
default:
AX5051_IRQMASK = 0x00;
axirq_state = axirq_idle;
return;
case axirq_hdlctxidle:
AX5051_IRQMASK = 0x00;
AX5051_powermode(SYNTHTX);
break;
/***********发送中断********************/
case axirq_hdlctxpreamble:
AX5051_FIFODATA = 0xFF;
axirq_count--;
if (axirq_count >= 0)
{
return;
}
axirq_state = axirq_txsync;
axirq_count = axradio_phy_preamble_txsynclen;
return;
case axirq_txsync:
AX5051_FIFODATA = axradio_phy_preamble_txsync[axirq_count--];
if (axirq_count >= 0)
return;
axirq_state = axirq_hdlctxpacket;
axirq_count = 0;
return;
case axirq_hdlctxpacket:
AX5051_FIFODATA = axirq_packet_tx[axirq_count++];
if (axirq_count < 47)
return;
axirq_state = axirq_hdlctxpostamble;
axirq_count = axradio_phy_postamblelen;
//AX5051_FIFOCONTROL = AX5051_HDLCCMD_RAWCLRCRC;
return;
case axirq_hdlctxpostamble:
AX5051_FIFODATA = axradio_phy_postamble[axirq_count--];
if (axirq_count >= 0)
return;
AX5051_IRQMASK = 0x00;
//delay_1(3000);
if(chushi_tx_count<30)
{
chushi_tx_count++;
txrx_state=tx_queue;
}
else
{
chushi_tx_count=0;
txrx_state=rx_queue;
}
//txrx_state=tx_queue;
//axradio_transmitrampdown();
// AX5051_powermode(SYNTHTX);
axirq_state = axirq_hdlctxidle;
// timerbiaozhi=0;
IE_4=0;
PORTC_0=1; // disable AX5051 IRQ
return;
//**************接收流程********************
/*****************接收中断********************/
case axirq_hdlcrxidle:
if (!(AX5051_FRAMING&0X80))
{
w=AX5051_FIFODATA;
return;
}
axirq_state = axirq_hdlcrxpacket;
hdlcnewrxbuf:
axirq_count = 0;
return;
case axirq_hdlcrxpacket:
d = AX5051_FIFODATA;
if (axirq_count < 47)
{
axirq_packet_R[axirq_count] = d; //write data into packet
//uart0_tx(d);
axirq_count++;
return;
}
uart0_tx(axirq_packet_R[44]);
axirq_state = axirq_hdlcrxend;
//txrx_state=rx_queue;
return;
case axirq_hdlcrxend:
AX5051_powermode(SYNTHRX);
AX5051_IRQMASK = 0x00;
//delay_1(3000);
if((axirq_packet_R[43]==0x1d)||(axirq_packet_R[43]==0x1e))
{
delay_1(300000);
txrx_state=tx_queue;
}
else
txrx_state=rx_queue;
IE_4=0;
break;
} // end switch
}
运行结果如下:
|