si4432调试出了问题,求助。
本帖最后由 crazydog2009 于 2013-3-18 20:04 编辑朋友用M48做了个4432控制的,他的可以通信了,我把代码拿了过来,改了一下,但却发现我的接收模块的GPIO0一直有输出,我把GPIO0定义为输出接收到的信号。但我的发射模块还没有打开,如果说信号是从外面来的,我把433频率改成315,或者其它值,GPIO0还是会有波形出来,但没启动接收功能就不会有!下面是一些代码和我截下来的图,大虾帮参详下,谢谢啊。把spi_rw(WRITE_REG + 0x75, 0x47);//频率设置 434改成多少都没有用,GPIO0都有数据。
// Demo 程序适用范围: Si4431, Si4432, Si4431PA
// RF 模块的参数设置为: FSK,433.92MHz, 1.2KBPS, +/-10PPM, 频偏:30KHz, 调制带宽:61.2KHz
// 使能AFC,使能CRC, PH + FIFO 模式
// 每秒钟发射的固定测试数据为: 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x6d,
// 0x6d = (0x41 +0x42 +0x43 +0x44 +0x45 +0x46 +0x47 + 0x48 +0x49)
// MCU : Microchip high performance 8 bit MCU :PIC16F689
#include"config.h"
const unsigned char tx_test_data = {0xaa,0x55,0xaa,0x66,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
//const unsigned char tx_test_data = {0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x6d};// 每秒发射的固定内容的测试信号,第10个数据是前9个数据的校验和
#define WRITE_REG 0x80
#define READ_REG 0
unsigned char count_50hz;
unsigned char rx_buf;
unsigned char ItStatus1, ItStatus2;
unsigned char rf_timeout;
typedef struct
{
unsigned char reach_1s : 1;
unsigned char rf_reach_timeout : 1;
unsigned char is_tx : 1;
} FlagType;
FlagType Flag;
void rx_data(void);
void tx_data(void);
unsigned char spi_byte(unsigned char data);
unsigned char spi_rw(unsigned char addr, unsigned char data);
void SI4432_init(void);
void delay_1ms(unsigned int time);
void port_init(void);
void timer_init(void);
void delay_1ms(unsigned int time)
{
unsigned int i,k;
for(k = 0; k< time; k++)
{
for(i = 0; i<5000; i++)
{
;
}
}
}
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF(void)
{
TIM4_SR=0;
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; //一秒 的定时器
}
}
void fSi4432IOInit(void)
{
nIRQ_set= INPUT;
SDO_set = INPUT;
nSEL_set= OUTPUT;
SDI_set = OUTPUT;
SCK_set = OUTPUT;
SDN_set = OUTPUT;
nSEL_CR1 = OUTPUT;
SDI_CR1 = OUTPUT;
SCK_CR1 = OUTPUT;
SDN_CR1 = OUTPUT;
// TRISB5= OUTPUT;
}
void strobe()
{
TIM2_CCR1L = 0x50;
delay_1ms(100);
TIM2_CCR1L = 0;
delay_1ms(300);
}
void quick()
{
TIM2_CCR1L = 0x50;
delay_1ms(50);
TIM2_CCR1L = 0;
delay_1ms(50);
TIM2_CCR1L = 0x50;
delay_1ms(50);
TIM2_CCR1L = 0;
delay_1ms(300);
}
#define DEBUG
//*****************************************************************
void SI4432_init(void)
{
#ifdef DEBUG
spi_rw(WRITE_REG + 0x07, 0x80); //恢复所有寄存器为默认值
delay_1ms(500);
spi_rw(READ_REG + 0x03, 0x00); //清除所有中断标志
spi_rw(READ_REG + 0x04, 0x00); //清除所有中断标志
spi_rw(WRITE_REG + 0x05, 0x00); //清除所有中断使能
spi_rw(WRITE_REG + 0x06, 0x00);//清除所有中断使能
spi_rw(WRITE_REG + 0x06, 0x80);//使能同步字侦测
spi_rw(WRITE_REG + 0x07, 0x01);//进入 Ready 模式
spi_rw(WRITE_REG + 0x09, 0x7f);//负载电容= 12P
spi_rw(WRITE_REG + 0x0a, 0x05);//关闭低频输出
spi_rw(WRITE_REG + 0x0b, 0xf4);//GPIO 0 当做普通输出口
spi_rw(WRITE_REG + 0x0c, 0xea);//GPIO 1 当做普通输出口
spi_rw(WRITE_REG + 0x0d, 0xea);//GPIO 2 输出收到的数据
spi_rw(WRITE_REG + 0x70, 0x2c);
spi_rw(WRITE_REG + 0x1d, 0x40);//使能 afc
// 1.2K bps setting
spi_rw(WRITE_REG + 0x1c, 0x27);//IF滤波带宽
spi_rw(WRITE_REG + 0x20, 0x68);
spi_rw(WRITE_REG + 0x21, 0x01);//
spi_rw(WRITE_REG + 0x22, 0x3A);//
spi_rw(WRITE_REG + 0x23, 0x93);//
spi_rw(WRITE_REG + 0x24, 0x01);//
spi_rw(WRITE_REG + 0x25, 0x30);//
spi_rw(WRITE_REG + 0x2a, 0x19);
spi_rw(WRITE_REG + 0x6e, 0x4E);
spi_rw(WRITE_REG + 0x6f, 0xA5);
//1.2K bps setting end
spi_rw(WRITE_REG + 0x30, 0x8c);//使能PH+ FIFO模式,高位在前面,使能CRC校验
spi_rw(WRITE_REG + 0x32, 0xff);//byte 0,1,2,3 作为头码
spi_rw(WRITE_REG + 0x33, 0x42);//byte 0,1,2,3 是头码,同步字3,2 是同步字
spi_rw(WRITE_REG + 0x34, 16); //发射16个Nibble的Preamble
spi_rw(WRITE_REG + 0x35, 0x20);//需要检测4个nibble的Preamble
spi_rw(WRITE_REG + 0x36, 0x2d);//同步字为 0x2dd4
spi_rw(WRITE_REG + 0x37, 0xd4);
spi_rw(WRITE_REG + 0x38, 0x00);
spi_rw(WRITE_REG + 0x39, 0x00);
spi_rw(WRITE_REG + 0x3a, 's'); //发射的头码为:"swwx"
spi_rw(WRITE_REG + 0x3b, 'w');
spi_rw(WRITE_REG + 0x3c, 'w');
spi_rw(WRITE_REG + 0x3d, 'x');
spi_rw(WRITE_REG + 0x3e, 10); //总共发射TxBuf_Len个字节的数据
spi_rw(WRITE_REG + 0x3f, 's'); //需要校验的头码为:"swwx"
spi_rw(WRITE_REG + 0x40, 'w');
spi_rw(WRITE_REG + 0x41, 'w');
spi_rw(WRITE_REG + 0x42, 'x');
spi_rw(WRITE_REG + 0x43, 0xff);//头码1,2,3,4 的所有位都需要校验
spi_rw(WRITE_REG + 0x44, 0xff);//
spi_rw(WRITE_REG + 0x45, 0xff);//
spi_rw(WRITE_REG + 0x46, 0xff);//
spi_rw(WRITE_REG + 0x6d, 0x00);//发射功率设置0x00:+1dBM0x01:+2dBM0x02:+5dBM0x03:+8dBM0x04:+11dBM0x05:+14dBM0x06:+17dBM0x07:+20dBM
spi_rw(WRITE_REG + 0x79, 0x0); //不需要跳频
spi_rw(WRITE_REG + 0x7a, 0x0); //不需要跳频
spi_rw(WRITE_REG + 0x71, 0x22);//发射不需要CLK,FiFo,FSK模式
spi_rw(WRITE_REG + 0x72, 0x30);//频偏为 30KHz
spi_rw(WRITE_REG + 0x73, 0x0); //没有频率偏差
spi_rw(WRITE_REG + 0x74, 0x0); //没有频率偏差
spi_rw(WRITE_REG + 0x75, 0x47);//频率设置 434
spi_rw(WRITE_REG + 0x76, 0x7D);//
spi_rw(WRITE_REG + 0x77, 0x00);
TX0_RX0; // 天线开关不在发射,接收状态
#else
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, 0xF4); // GPIO 0 接收到的数据输出
spi_rw(0x0c|0x80, 0xea); //GPIO 1 当做普通输出口
// spi_rw(0x0d|0x80, 0xf4);// /GPIO 2 输出收到的数据
spi_rw(0x0d|0x80, 0xea);// /GPIO 2 当做普通输出口
spi_rw(0x70|0x80, 0x2C);
spi_rw(0x1d|0x80, 0x40);// 使能 afc
////////////////////////////////////////////////////////////////////////
// 1.2K bps setting
/*
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, 0x1E);//?
spi_rw(0x6e|0x80, 0x09);//..
spi_rw(0x6f|0x80, 0xd5);//...*/
//1.2K bps setting end
spi_rw(0x1c|0x80, 0x1B); // 下面的设置根据Silabs 的Excel
spi_rw(0x20|0x80, 0xD0); //
spi_rw(0x21|0x80, 0x00); //
spi_rw(0x22|0x80, 0x9D);//
spi_rw(0x23|0x80, 0x49); //
spi_rw(0x24|0x80, 0x00); //
spi_rw(0x25|0x80, 0x34); //
spi_rw(0x2a|0x80, 0x19);//
spi_rw(0x6e|0x80, 0x4E);//
spi_rw(0x6f|0x80, 0xA5);//
///////////////////////////////////////////////////////////////
spi_rw(0x30|0x80, 0x88); // 使能PH+ FIFO模式,高位在前面,disableCRC校验
// spi_rw(0x30|0x80, 0x00);// 使能PH+ FIFO模式,高位在前面,禁能CRC校验,禁止包处理
// spi_rw(0x32|0x80, 0xff);// byte0, 1,2,3 作为头码
spi_rw(0x32|0x80, 0x00);// 不检测帧头
// spi_rw(0x33|0x80, 0x42);//byte 0,1,2,3 是头码,同步字3,2 是同步字
spi_rw(0x33|0x80, 0x0a);//不发射帧头,帧头不包括包长度,只有同步字3 2
spi_rw(0x34|0x80, 16);// 发射16个Nibble的Preamble
// spi_rw(0x34|0x80, 3);// 发射16个Nibble的Preamble
spi_rw(0x35|0x80, 0x20);// 需要检测4个nibble的Preamble
// spi_rw(0x35|0x80, 0x08);// 需要检测1个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, 'w');
// spi_rw(0x3d|0x80, 'x');
spi_rw(0x3e|0x80, 3);// 总共发射10个字节的数据
// spi_rw(0x3e|0x80, 4);// 总共发射4个字节的数据
// spi_rw(0x3f|0x80, 's'); // 需要校验的头码为:”swwx"
// spi_rw(0x40|0x80, 'w');
// spi_rw(0x41|0x80, 'w');
// spi_rw(0x42|0x80, 'x');
// 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(0x43|0x80, 0x00);// 头码1,2,3,4 的所有位都不需要校验
spi_rw(0x44|0x80, 0x00);//
spi_rw(0x45|0x80, 0x00);//
spi_rw(0x46|0x80, 0x00);//
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, 0x60);// 频偏为 30KHz *
spi_rw(0x73|0x80, 0x0);// 没有频率偏差 *
spi_rw(0x74|0x80, 0x0);// 没有频率偏差 *
spi_rw(0x75|0x80, 0x53);// 频率设置 433.36 *
// spi_rw(0x76|0x80, 0x64);// *
spi_rw(0x76|0x80, 0x54);//
spi_rw(0x77|0x80, 0x00);//*
#endif
}
//***************************************************************
void rx_data(void)
{
// unsigned char i, chksum;
Flag.is_tx = 0;
spi_rw(0x07|0x80, SI4432_PWRSTATE_READY); //进入 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模块收到整包数据后,产生中断
ItStatus1 = spi_rw(0x03,0x00); //清掉现有的中断标志
ItStatus2 = spi_rw(0x04,0x00); //清掉现有的中断标志
}
void tx_data(void)
{
unsigned char i;
Flag.is_tx = 1;
spi_rw(0x07|0x80, SI4432_PWRSTATE_READY); // rf 模块进入Ready 模式
TX1_RX0; //设置天线开关的方向
delay_1ms(5); // 延时 5ms, 让系统稳定
spi_rw(0x08|0x80, 0x03);//
spi_rw(0x08|0x80, 0x00);// 清发射,接收缓冲区
// spi_rw(0x34|0x80, 40);// 发射40个Nibble 的前导码
spi_rw(0x34|0x80, 16);// 发射16个Nibble 的前导码
spi_rw(0x3e|0x80, 3);// 总共发射10个字节的数据
for (i = 0; i<10; i++)
{
spi_rw(0x7f|0x80, tx_test_data); // 将要发射的数据载入缓冲区
}
spi_rw(0x05|0x80, SI4432_PACKET_SENT_INTERRUPT); // 整包数据发射完后,产生中断
ItStatus1 = spi_rw(0x03,0x00); // 清RF模块中断
ItStatus2 = spi_rw(0x04,0x00);
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 发射完成,进入接收模式
}
unsigned char spi_byte(unsigned char data)
{
unsigned char i;
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;
else
data &= 0xfe;
SCK = 0;
}
return (data);
}
//-------------------------------------------
unsigned char spi_rw(unsigned char addr, unsigned char data)
{
unsigned char i;
SCK = 0;
nSEL = 0;
for (i = 0; i < 8; i++)
{
if (addr & 0x80)
SDI = 1;
else
SDI = 0;
addr <<= 1;
SCK = 1;
asm("NOP");
SCK= 0;
}
for (i = 0; i < 8; i++)
{
if (data & 0x80)
SDI = 1;
else
SDI = 0;
data <<= 1;
SCK = 1;
if (SDO)
data |= 0x01;
else
data &= 0xfe;
SCK = 0;
}
nSEL = 1;
SCK= 1;
return (data);
}
// song end
GPIO输出正常的,没有问题。 看了楼主的帖子,小弟目前也在做这个。希望楼主能提供完整的demo程序一份以供参考。{:3_60:} 再次追问,如果GPIO用来控制天线开关,是设置为0xEA,还是0xF4,请楼主赐教 都是正常的
路过,留个脚印
页:
[1]