fanice 发表于 2013-6-4 17:50:14

SI4432中断问题,求助。

大家好,我在调试si4432的过程中,SPI可以读写寄存器,并且读取返回值正确。但是发现NIRQ端始终是低电平,也就是一直处于中断,读取中断寄存器复位中断也无济于事。恳请大家给解释下。谢谢。

fanice 发表于 2013-6-4 17:58:45

忘记说了,我用的是AVR的atmega88pa,不知道AVR端与NIRQ端连接的pin是否需要内部上拉电阻。

lalapunk1983 发表于 2013-6-4 18:27:13

上程序我给你看。用了很久的SI4432没。没发现你说的问题。

fanice 发表于 2013-6-4 18:30:12

lalapunk1983 发表于 2013-6-4 18:27 static/image/common/back.gif
上程序我给你看。用了很久的SI4432没。没发现你说的问题。

多谢了!程序如下:
//*************************************************************
//函数名:void RfChipInit(void)
//功能:芯片初始化
//参数: 无
//*************************************************************

void RfChipInit(void)
{                                                                                                                                       
        Si446x_enable;
        _delay_ms(20);

        //ItStatus1 = SpiRfReadRegister(0x03);        //read the Interrupt Status1 register
        //ItStatus2 = SpiRfReadRegister(0x04);        //read the Interrupt Status2 register
        //SpiRfWriteRegister(0x07, 0x80);                   //write 0x80 to the Operating & Function Control1 register
        //_delay_ms(10);

        ItStatus1 = SpiRfReadRegister(0x03);//read the Interrupt Status1 register
        ItStatus2 = SpiRfReadRegister(0x04);//read the Interrupt Status2 register
        SpiRfWriteRegister(0x07, 0x80);   //write 0x80 to the Operating & Function Control1 register
        while ( Read_446x_IRQ == 1);
        ItStatus1 = SpiRfReadRegister(0x03);   //read the Interrupt Status1 register
        ItStatus2 = SpiRfReadRegister(0x04);   //read the Interrupt Status2 register       
        while ( Read_446x_IRQ == 1);
        ItStatus1 = SpiRfReadRegister(0x03);               
        ItStatus2 = SpiRfReadRegister(0x04);       

        /*设置RF 参数:中断频率(center frequency)、发射数据速率(transmit data rate)和发射偏差(transmit deviation)*/
        /*set the center frequency to 433 MHz*/
        SpiRfWriteRegister(0x75, 0x53);
        SpiRfWriteRegister(0x76, 0x4b);
        SpiRfWriteRegister(0x77, 0x00);
        /*set the center frequency to 868 MHz*/
        //SpiRfWriteRegister(0x75, 0x73);
        //SpiRfWriteRegister(0x76, 0x64);
        //SpiRfWriteRegister(0x77, 0x00);
        /*set the desired TX data rate 4.8K*/
        SpiRfWriteRegister(0x6E, 0x27);
        SpiRfWriteRegister(0x6F, 0x52);
        SpiRfWriteRegister(0x70, 0x24);

        /*set the desired TX deviation */
        SpiRfWriteRegister(0x72, 0x18);

        /*接收的GFSK 调制数据配置调制解调器参数*/
        SpiRfWriteRegister(0x1C, 0x1D);
        SpiRfWriteRegister(0x20, 0xA1);
        SpiRfWriteRegister(0x21, 0x20);
        SpiRfWriteRegister(0x22, 0x4E);
        SpiRfWriteRegister(0x23, 0xA5);
        SpiRfWriteRegister(0x24, 0x00);
        SpiRfWriteRegister(0x25, 0x1B);
        SpiRfWriteRegister(0x1D,0x40);
        /*set the TX power to MAX*/
        SpiRfWriteRegister(0x6D, 0x0f);                //20DBM

        /*配置接收数据包处理器(packet handler)*/
        SpiRfWriteRegister(0x35, 0x28); //write 0x28 to the Preamble Detection Control register
        SpiRfWriteRegister(0x34, 0x0A);        //write 0x0A to the Preamble Length register

        /*禁止桢头字节(本示例中未用),设置同步字长度为两个字节*/
        SpiRfWriteRegister(0x33, 0x02);        //write 0x02 to the Header Control2 register
        /*Disable the receive header filters*/
        SpiRfWriteRegister(0x32, 0x00 ); //write 0x00 to the Header Control1 register

        /*设置同步字样式(pattern)为0x2DD4*/
        /*Set the sync word pattern to 0x2DD4 */
        SpiRfWriteRegister(0x36, 0x2D); //write 0x2D to the Sync Word 3 register
        SpiRfWriteRegister(0x37, 0xD4); //write 0xD4 to the Sync Word 2 register

        /*Enable the receive packet handler and CRC-16 (IBM) check*/
        SpiRfWriteRegister(0x30, 0x8D); //write 0x8D to the Data Access Control register

        /*enable FIFO mode and GFSK modulation*/
        SpiRfWriteRegister(0x71, 0x63);//write 0x63 to the Modulation Mode Control 2 register

        /*set the GPIO's according the testcard type*/
        SpiRfWriteRegister(0x0C, 0x12);        //write 0x12 to the GPIO1 Configuration(set the TX state)
        SpiRfWriteRegister(0x0D, 0x15);        //write 0x15 to the GPIO2 Configuration(set the RX state)

        /*设置AGC 和ADC 参数*/
        SpiRfWriteRegister(0x6A, 0x0B); //write 0x0B to the AGC Override 2 register
        SpiRfWriteRegister(0x68, 0x04);
        SpiRfWriteRegister(0x1F, 0x03);

        /*set Crystal Oscillator Load Capacitance register*/
        SpiRfWriteRegister(0x09, 0x68); //write 0x68 to the CrystalOscillatorLoadCapacitance register
}

//*************************************************************
//函数名:void RFTransmitMessage(u8 *DataMessage,u8 Length)
//功能: 发送一个数据结构
//参数: MESSAGE 结构体
//*************************************************************
void RFTransmitMessage(unsigned char *DataMessage,unsigned char Length)
{
        //SET THE CONTENT OF THE PACKET       
        SpiRfWriteRegister(0x3E, Length);        //write 8 to the Transmit Packet Length register               

        //fill the payload into the transmit FIFO
        SpiRfWriteBurst(0x7F, DataMessage, Length);

        //Disable all other interrupts and enable the packet sent interrupt only.
        //This will be used for indicating the successfull packet transmission for the MCU
        SpiRfWriteRegister(0x05, 0x04);                //write 0x04 to the Interrupt Enable 1 register       
        SpiRfWriteRegister(0x06, 0x00);                //write 0x00 to the Interrupt Enable 2 register       

        //Read interrupt status regsiters. It clear all pending interrupts and the nIRQ pin goes back to high.
        ItStatus1 = SpiRfReadRegister(0x03);        //read the Interrupt Status1 register
        ItStatus2 = SpiRfReadRegister(0x04);        //read the Interrupt Status2 register

        //enable transmitter
        //The radio forms the packet and send it automatically.
        SpiRfWriteRegister(0x07, 0x09);//write 0x09 to the Operating Function Control 1 register

        //enable the packet sent interupt only
        SpiRfWriteRegister(0x05, 0x04);                        //write 0x04 to the Interrupt Enable 1 register               

        //wait for the packet sent interrupt
        //The MCU just needs to wait for the 'ipksent' interrupt.
        while(Read_446x_IRQ == 1);

        //read interrupt status registers to release the interrupt flags
        ItStatus1 = SpiRfReadRegister(0x03);        //read the Interrupt Status1 register
        ItStatus2 = SpiRfReadRegister(0x04);        //read the Interrupt Status2 register

        //wait a bit for showing the LED a bit longer


}
//*************************************************************
//函数名:void RFReceiveReady(void)
//功能: 进入接收数据状态
//参数: 无
//*************************************************************
void RFReceiveReady(void)
{
        //enable receiver chain
        SpiRfWriteRegister(0x07, 0x05);//write 0x05 to the Operating Function Control 1 register

        //Enable two interrupts:
        // a) one which shows that a valid packet received: 'ipkval'
        // b) second shows if the packet received with incorrect CRC: 'icrcerror'
        SpiRfWriteRegister(0x05, 0x03); //write 0x03 to the Interrupt Enable 1 register
        SpiRfWriteRegister(0x06, 0x00); //write 0x00 to the Interrupt Enable 2 register

        //read interrupt status registers to release all pending interrupts
        ItStatus1 = SpiRfReadRegister(0x03);//read the Interrupt Status1 register
        ItStatus2 = SpiRfReadRegister(0x04);//read the Interrupt Status2 register
}
//*************************************************************
//函数名:void RFGetBuffer(u8 * buff)
//功能: 对取buff 数据
//参数: 字符串指针
//*************************************************************
void RFGetBuffer(unsigned char *buff)
{
        unsigned char k;
        //wait for the packet sent interrupt
        //The MCU just needs to wait for the 'ipksent' interrupt.
        while(Read_446x_IRQ == 1);

        //wait for the interrupt event
        if( Read_446x_IRQ == 0 )
        {
                //read interrupt status registers
                ItStatus1 = SpiRfReadRegister(0x03);//read the Interrupt Status1 register
                ItStatus2 = SpiRfReadRegister(0x04);//read the Interrupt Status2 register

                //packet received interrupt occurred
                if( (ItStatus1 & 0x02) == 0x02 )
                {
                        //disable the receiver chain
                        SpiRfWriteRegister(0x07, 0x01);//write 0x01 to the Operating Function Control 1 register

                        //Read the length of the received payload
                        k= SpiRfReadRegister(0x4B) ; //读取数据长度

                        //Get the received payload from the RX FIFO
                        SpiRfReadBurest(0x7F, buff, k); //读取fifo 数据


                        if(buff==0x55){}                          //确定是不是对方发出来的
                        //{ P_2_LED = ~P_2_LED; }
                }
        }
}

fanice 发表于 2013-6-4 18:31:39

原理图如下。

fanice 发表于 2013-6-4 18:33:23

我用的开发环境是AVR Studio4.19.

fanice 发表于 2013-6-4 18:37:44

void system_init(void)
{
        DDRB |= (1<<_446x_SDI)|(1<<_446x_SCLK)|(1<<_446x_nSEL);
        DDRB &=~(1<<_446x_SDO);
        PORTB |= (1<<_446x_nSEL)|(1<<_446x_SDI)|(1<<_446x_SCLK);

        DDRC = (1<<_446x_RXON)|(1<<_446x_TXON);
        PORTC= (1<<_446x_RXON)|(1<<_446x_TXON);

        DDRD |= (1<<_446x_SDN)|(1<<LED);
        DDRD &=~(1<<_446x_NIRQ);
        PORTD= (1<<_446x_SDN);//|(1<<_446x_NIRQ)

fanice 发表于 2013-6-4 18:46:49

#define _446x_SDO        PB4                //SPI MISO
#define _446x_SDI        PB3                //SPI MOSI
#define _446x_SCLK        PB5                //SPI SCK
#define _446x_nSEL        PB2                //SPI SS
#define _446x_SDN        PD6                //SDN=1时,芯片彻底关闭,寄存器清除。
#define _446x_NIRQ        PD7                //中断输出引脚
#define _446x_RXON        PC4                //内部链接GPI02
#define _446x_TXON        PC5                //内部链接GPI03
#define LED                        PD2                //指示灯

#define _446x_MISO        PINB
#define _446x_MOSI        PORTB
#define _446x_CSN        PORTB
#define _446x_SCK        PORTB
#define _446x_TDown        PORTD
#define _446x_IRQ        PIND
#define MLED                PORTD
#define _446x_rx        PORTC
#define _446x_tx        PORTC
//--------------------------------------------------------------------------------
#define Read_446x_MISO                (_446x_MISO & (1<<_446x_SDO))
#define Low_446x_MOSI                (_446x_MOSI &=~ (1<<_446x_SDI))
#define High_446x_MOSI                (_446x_MOSI |= (1<<_446x_SDI))
#define Low_446x_CSN                (_446x_CSN &=~ (1<<_446x_nSEL))
#define High_446x_CSN                (_446x_CSN |= (1<<_446x_nSEL))
#define Low_446x_SCK                (_446x_SCK &=~ (1<<_446x_SCLK))
#define High_446x_SCK                (_446x_SCK |= (1<<_446x_SCLK))
//---------------------------------------------------------------------------------
#define Low_446x_TDown                (_446x_TDown &=~ (1<<_446x_SDN))
#define High_446x_TDown                (_446x_TDown |= (1<<_446x_SDN))
#define Si446x_enable                (_446x_TDown &=~ (1<<_446x_SDN))
#define Si446x_disable                (_446x_TDown |= (1<<_446x_SDN))

#define Read_446x_IRQ                (_446x_IRQ & (1<<_446x_NIRQ))
#define Low_446x_rx                        (_446x_rx &=~ (1<<_446x_RXON))
#define High_446x_rx                (_446x_rx |= (1<<_446x_RXON))
#define Low_446x_tx                        (_446x_tx &=~ (1<<_446x_TXON))
#define High_446x_tx                (_446x_tx |= (1<<_446x_TXON))
#define MLED_ON                                (MLED |= (1<<LED))
#define MLED_OFF                        (MLED &=~ (1<<LED))

lalapunk1983 发表于 2013-6-5 18:09:28

给你传个我用的把。这太多了,没看出来问题。
void RF_spi_init(void)
{
        LPC_PINCON->PINSEL0 |= (0x03ul << 30);                                  // 设置P0.15脚为SCK脚
        LPC_PINCON->PINSEL1 &=~(0x03<<0);                                                               //片选脚做GPIO
        NSEL_INIT();                                                                                                     //输出
    LPC_PINCON->PINSEL1 |= (0x03 << 2)|(0x03 << 4);                         // 设置P0.17、P0.18,            
                                                                                          
    LPC_SPI->SPCCR=0x08;                                          
    LPC_SPI->SPCR   = (0 << 2)|(0 << 3)|(0 << 4)|(1 << 5)|(0 << 6)|(0 << 7); //CPHA=0,CPOL=0
        SDN_INIT();             //SDN 输出
        SDI_INIT();               //SDI 输入
        NIRQ_INIT();       //NIRQ输入
        TX_ANT_INIT();
        RX_ANT_INIT();
        DIS_TX_ANT();
        DIS_RX_ANT();
        LOW_SDN();
        HI_NSEL();                                    
}

unsigned char RF_spi_read(unsigned char address)      //指定地址读
{
        unsigned int temp=0;
        LOW_NSEL();                                                                        //拉低片选
        LPC_SPI->SPDR=address&0x7f;                                        //发送读地址,最高位为读写位
        while(0 == (LPC_SPI->SPSR & 0x80));                        //等待发送完成
        temp= LPC_SPI->SPSR;                                        //读寄存器清标志
        LPC_SPI->SPDR=0xff;                                                //发送哑数据产生时钟接收数据
        while(0 == (LPC_SPI->SPSR & 0x80));
    temp= LPC_SPI->SPSR;                                                //读寄存器清标志
        HI_NSEL();                                                                        //拉高片选
        temp = temp;                                                                //消除编译器警告
        return ((unsigned char)(LPC_SPI->SPDR));
}

void RF_spi_readNbyte(unsigned char address,unsigned char num,unsigned char *buf)
{
        unsigned char i=0;
        unsigned char temp=0;
        LOW_NSEL();
        LPC_SPI->SPDR=address&0x7f;                      //写地址
        while(0 == (LPC_SPI->SPSR & 0x80));                        //等待发送完成
        temp= LPC_SPI->SPSR;
        for(i=0;i<num;i++)
        {
                LPC_SPI->SPDR=0x00;         
                while(0 == (LPC_SPI->SPSR & 0x80));
            temp= LPC_SPI->SPSR;
                *buf++=(unsigned char)(LPC_SPI->SPDR);
        }
        HI_NSEL();
        temp = temp;
}

void RF_spi_write(unsigned char address,unsigned char dat)          //指定地址写指定数据
{
    unsigned int temp=0;
        LOW_NSEL();                                                                        //拉低片选
        LPC_SPI->SPDR=address|0x80;                                        //发送写地址,最高位为读写位
        while(0 == (LPC_SPI->SPSR & 0x80));                        //等待发送完成
    temp= LPC_SPI->SPSR;                                        //读寄存器清标志
        LPC_SPI->SPDR=dat;                                                //发送要写的数据
        while(0 == (LPC_SPI->SPSR & 0x80));
    temp= LPC_SPI->SPSR;                                                //读寄存器清标志
        HI_NSEL();                                                                        //拉高片选
        temp = temp;
}

lalapunk1983 发表于 2013-6-5 18:18:38

本帖最后由 lalapunk1983 于 2013-6-5 18:20 编辑

void Rfm_Habdle_ISR(void)
{
        unsigned char temp,i,j;
        if((LPC_GPIOINT->IO2IntStatF&RF_INT)!=0)                   //RF中断
        {
                ItStatus1 = RF_spi_read(0x03);               
                ItStatus2 = RF_spi_read(0x05);
                if(((ItStatus1&0x01)==0x01)&&((ItStatus2&0x01)==0x01))            //无线CRC校验错误
             {
                  to_rx_mode();
                   Clear_RF_IntFlag();
                  return;
             }
               else if(((ItStatus1&0x20)==0x20)&&((ItStatus2&0x20)==0x20))
                {
                        Clear_RF_IntFlag();
                        return;
                }
                else if(((ItStatus1&0x02)==0x02)&&((ItStatus2&0x02)==0x02))         //接收完成中断
                {
                        to_rx_mode();
                        Clear_RF_IntFlag();
                        return;
                }
                else if(((ItStatus1&0x10)==0x10)&&((ItStatus2&0x10)==0x10))   //接收将满,该中断
                {
                       
                        to_rx_mode();
                        Clear_RF_IntFlag();
                        return;              
                }
               else if(((ItStatus1&0x04)==0x04)&&((ItStatus2&0x04)==0x04))            //数据发送完成
              {
                  to_rx_mode();
                  return;
             }
                else                                                                                                     
                {
                        to_rx_mode();
                        Clear_RF_IntFlag();
                        return;
                }
        }
}

lalapunk1983 发表于 2013-6-5 18:24:09

mega64的程序也跟这个差不多。不同的就是中断里不用清标志,这个是深圳华普微电子的RF22-23B的模块。其实IC就是SI4432,只是他们自己封IC的时候做了一些小小的改动,CHPA和CPOL那里改了下,还有就是发送和接收天线切换那里的有效电平改了下。这个程序是用的硬件SPI,如果要用模拟SPI的话可以去他们的网站上下载。

fanice 发表于 2013-6-9 13:43:15

lalapunk1983 发表于 2013-6-5 18:24 static/image/common/back.gif
mega64的程序也跟这个差不多。不同的就是中断里不用清标志,这个是深圳华普微电子的RF22-23B的模块。其实IC ...

多谢了,已经搞定了,项目继续进行中。

quentin121 发表于 2013-7-12 07:33:25

碰到跟楼主一样的问题?请教楼主是那设置出了问题,也给这个贴结下贴

fanice 发表于 2013-7-12 16:10:21

quentin121 发表于 2013-7-12 07:33 static/image/common/back.gif
碰到跟楼主一样的问题?请教楼主是那设置出了问题,也给这个贴结下贴

哥们,看下我有个关于si4432官方demo的帖子就明白了。用官方的demo很容易调通。

红酒人生 发表于 2013-9-26 16:50:59

我现在也遇到这样的问题了,求解决方法。

ST_ATMEL_NXP 发表于 2014-8-6 21:55:02

我也遇到这个问题了。只能接收一次,之后IRQ引脚 一直拉低。不知道楼主具体怎么解决的?

YellowMid 发表于 2014-8-25 13:53:23

IRQ脚需要配置为上拉输入
页: [1]
查看完整版本: SI4432中断问题,求助。