si4431程序示例Word下载.docx
《si4431程序示例Word下载.docx》由会员分享,可在线阅读,更多相关《si4431程序示例Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
#defineSDI_setTRISC3//设置IO口的输入,数出的寄存器
#defineSCK_setTRISC4//设置IO口的输入,数出的寄存器
#defineSDN_setTRISC5//设置IO口的输入,数出的寄存器
#defineINPUT1
#defineOUTPUT0
unsignedcharcount_50hz;
unsignedcharItStatus1,ItStatus2;
unsignedcharrf_timeout;
unsignedcharrx_buf[15];
typedefstruct
{
unsignedcharreach_1s:
1;
unsignedcharrf_reach_timeout:
unsignedcharis_tx:
}FlagType;
FlagTypeFlag;
voidrx_data(void);
voidtx_data(void);
unsignedcharspi_byte(unsignedchardata);
unsignedcharspi_rw(unsignedcharaddr,unsignedchardata);
voidSI4432_init(void);
voiddelay_1ms(unsignedchartime);
voidport_init(void);
voidtimer_init(void);
voidmain()
{
unsignedchari,j,chksum;
OSCCON=0X70;
//使用内部晶振,8Mcrystal
WDTCON=0X00;
//看门狗设置
port_init();
//IO口初始化
SDN=1;
delay_1ms(10);
//RF模块复位
SDN=0;
delay_1ms(200);
//延时150msRF模块进入工作状态
SI4432_init();
//RF模块初始化
TX0_RX0;
//天线开关不在发射,接收状态
timer_init();
count_50hz=0;
Flag.reach_1s=0;
INTCON=0xc0;
//enableinterrupt
while
(1)
{
if(Flag.reach_1s)
{
Flag.reach_1s=0;
tx_data();
//每间隔一段时间,发射一包数据,并接收Acknowledge信号
}
if(!
Flag.is_tx)
if(!
nIRQ)
{
ItStatus1=spi_rw(0x03,0x00);
//清中断//readtheInterruptStatus1register
ItStatus2=spi_rw(0x04,0x00);
//清中断
SCK=0;
nSEL=0;
spi_byte(0x7f);
//从缓冲区读数据
for(i=0;
i<
10;
i++)
{
rx_buf[i]=spi_byte(0x00);
}
nSEL=1;
spi_rw(0x07|0x80,SI4432_PWRSTATE_READY);
//数据接收完成,退出接收模式,
chksum=0;
for(i=0;
9;
i++)//计算Checksum
chksum+=rx_buf[i];
if((chksum==rx_buf[9])&
&
(rx_buf[0]==0x41))
{
;
//数据收到了
}
else
rx_data();
//收到的数据不对,则要继续开始接收
}
}
}
}
voiddelay_1ms(unsignedchartime)
unsignedchari,k;
for(k=0;
k<
time;
k++)
{
for(i=0;
i<
130;
i++)
NOP();
}
}
voidtimer_init(void)
T1CON=0x31;
TMR1IE=1;
TMR1L=0x78;
//定时器中断初始化
TMR1H=0xec;
voidinterruptISR_timer(void)
unsignedchari;
if(TMR1IF)
TMR1L=0x78;
//20ms的定时器
TMR1H=0xec;
rf_timeout++;
if(rf_timeout==25)
Flag.rf_reach_timeout=1;
//发射0.5秒,接收3秒的Timeout定时器,发射,接收共用此Ram
count_50hz++;
if(count_50hz==50)//
{
count_50hz=0;
Flag.reach_1s=1;
//一秒的定时器
}
TMR1IF=0;
}
voidport_init(void)
ANSEL=0;
ANSELH=0;
//不使用MCU的AD
WPUA=0;
//没有上拉电阻
IOCA=0;
//没有IO口中断
nIRQ_set=INPUT;
SDO_set=INPUT;
nSEL_set=OUTPUT;
SDI_set=OUTPUT;
SCK_set=OUTPUT;
SDN_set=OUTPUT;
TRISB5=OUTPUT;
voidSI4432_init(void)
ItStatus1=spi_rw(0x03,0x00);
//清RF模块中断
ItStatus2=spi_rw(0x04,0x00);
spi_rw(0x06|0x80,0x00);
//关闭不需要的中断
spi_rw(0x07|0x80,SI4432_PWRSTATE_READY);
//进入Ready模式
spi_rw(0x09|0x80,0x7f);
//负载电容=12P
spi_rw(0x0a|0x80,0x05);
//关闭低频输出
spi_rw(0x0b|0x80,0xea);
//GPIO0当做普通输出口
spi_rw(0x0c|0x80,0xea);
//GPIO1当做普通输出口
spi_rw(0x0d|0x80,0xf4);
///GPIO2输出收到的数据
spi_rw(0x70|0x80,0x2c);
spi_rw(0x1d|0x80,0x40);
//使能afc
//1.2Kbpssetting
spi_rw(0x1c|0x80,0x16);
//下面的设置根据Silabs的Excel
spi_rw(0x20|0x80,0x83);
spi_rw(0x21|0x80,0xc0);
//
spi_rw(0x22|0x80,0x13);
//
spi_rw(0x23|0x80,0xa9);
spi_rw(0x24|0x80,0x00);
spi_rw(0x25|0x80,0x04);
spi_rw(0x2a|0x80,0x14);
spi_rw(0x6e|0x80,0x09);
spi_rw(0x6f|0x80,0xd5);
//1.2Kbpssettingend
spi_rw(0x30|0x80,0x8c);
//使能PH+FIFO模式,高位在前面,使能CRC校验
spi_rw(0x32|0x80,0xff);
//byte0,1,2,3作为头码
spi_rw(0x33|0x80,0x42);
//byte0,1,2,3是头码,同步字3,2是同步字
spi_rw(0x34|0x80,16);
//发射16个Nibble的Preamble
spi_rw(0x35|0x80,0x20);
//需要检测4个nibble的Preamble
spi_rw(0x36|0x80,0x2d);
//同步字为0x2dd4
spi_rw(0x37|0x80,0xd4);
spi_rw(0x38|0x80,0x00);
spi_rw(0x39|0x80,0x00);
spi_rw(0x3a|0x80,'
s'
);
//发射的头码为:
“swwx"
spi_rw(0x3b|0x80,'
w'
spi_rw(0x3c|0x80,'
spi_rw(0x3d|0x80,'
x'
spi_rw(0x3e|0x80,10);
//总共发射10个字节的数据
spi_rw(0x3f|0x80,'
//需要校验的头码为:
”swwx"
spi_rw(0x40|0x80,'
spi_rw(0x41|0x80,'
spi_rw(0x42|0x80,'
spi_rw(0x43|0x80,0xff);
//头码1,2,3,4的所有位都需要校验
spi_rw(0x44|0x80,0xff);
//
spi_rw(0x45|0x80,0xff);
spi_rw(0x46|0x80,0xff);
spi_rw(0x6d|0x80,0x07);
//设置为最大功率发射
spi_rw(0x79|0x80,0x0);
//不需要跳频
spi_rw(0x7a|0x80,0x0);
spi_rw(0x71|0x80,0x22);
//发射不需要CLK,FiFo,FSK模式
spi_rw(0x72|0x80,0x30);
//频偏为30KHz
spi_rw(0x73|0x80,0x0);
//没有频率偏差
spi_rw(0x74|0x80,0x0);
spi_rw(0x75|0x80,0x53);
//频率设置433.5
spi_rw(0x76|0x80,0x57);
spi_rw(0x77|0x80,0x80);
voidrx_data(void)
unsignedchari,chksum;
Flag.is_tx=0;
//进入Ready模式
delay_1ms(5);
//
TX0_RX1;
//设置天线开关
spi_rw(0x08|0x80,0x03);
//清发射,接收缓冲区
spi_rw(0x08|0x80,0x00);
spi_rw(0x07|0x80,SI4432_PWRSTATE_RX);
//RF模块进入接收模式
spi_rw(0x05|0x80,SI4432_Rx_packet_received_interrupt);
//RF模块收到整包数据后,产生中断
//清掉现有的中断标志
voidtx_data(void)
unsignedchari;
Flag.is_tx=1;
//rf模块进入Ready模式
TX1_RX0;
//设置天线开关的方向
//延时5ms,让系统稳定
//清发射,接收缓冲区
spi_rw(0x34|0x80,40);
//发射40个Nibble的前导码
for(i=0;
spi_rw(0x7f|0x80,tx_test_data[i]);
//将要发射的数据载入缓冲区
spi_rw(0x05|0x80,SI4432_PACKET_SENT_INTERRUPT);
//整包数据发射完后,产生中断
spi_rw(0x07|0x80,SI4432_PWRSTATE_TX);
//进入发射模式
rf_timeout=0;
Flag.rf_reach_timeout=0;
while(nIRQ)//等待中断
if(Flag.rf_reach_timeout)
SDN=1;
//如果0.5秒还没有中断,则RF模块工作不正常,重新复位并初始化模块
delay_1ms(10);
SDN=0;
delay_1ms(200);
SI4432_init();
break;
//则强制跳出
rx_data();
//rf发射完成,进入接收模式
unsignedcharspi_byte(unsignedchardata)
for(i=0;
i<
8;
i++)//控制SCK和SDI,发射一个字节的命令,同事读取1个字节的数据
{//没有包括nSEL的控制
if(data&
0x80)
SDI=1;
else
SDI=0;
data<
<
=1;
SCK=1;
if(SDO)
data|=0x01;
data&
=0xfe;
SCK=0;
return(data);
//-------------------------------------------
unsignedcharspi_rw(unsignedcharaddr,unsignedchardata)
SCK=0;
nSEL=0;
i++)
if(addr&
addr<
asm("
NOP"
nSEL=1;
SCK=1;