crazydog2009 发表于 2013-3-18 20:01:27

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





rf_smart 发表于 2013-3-31 10:15:46

GPIO输出正常的,没有问题。

hmilyxfcy 发表于 2013-6-3 12:57:22

看了楼主的帖子,小弟目前也在做这个。希望楼主能提供完整的demo程序一份以供参考。{:3_60:}

hmilyxfcy 发表于 2013-6-3 20:46:16

再次追问,如果GPIO用来控制天线开关,是设置为0xEA,还是0xF4,请楼主赐教

syp910 发表于 2014-2-21 15:33:13

都是正常的

wsammy880 发表于 2015-2-23 21:54:41

路过,留个脚印
页: [1]
查看完整版本: si4432调试出了问题,求助。