SI4432中断问题,求助。
大家好,我在调试si4432的过程中,SPI可以读写寄存器,并且读取返回值正确。但是发现NIRQ端始终是低电平,也就是一直处于中断,读取中断寄存器复位中断也无济于事。恳请大家给解释下。谢谢。忘记说了,我用的是AVR的atmega88pa,不知道AVR端与NIRQ端连接的pin是否需要内部上拉电阻。 上程序我给你看。用了很久的SI4432没。没发现你说的问题。 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; }
}
}
} 原理图如下。 我用的开发环境是AVR Studio4.19. 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) #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)) 给你传个我用的把。这太多了,没看出来问题。
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: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;
}
}
} mega64的程序也跟这个差不多。不同的就是中断里不用清标志,这个是深圳华普微电子的RF22-23B的模块。其实IC就是SI4432,只是他们自己封IC的时候做了一些小小的改动,CHPA和CPOL那里改了下,还有就是发送和接收天线切换那里的有效电平改了下。这个程序是用的硬件SPI,如果要用模拟SPI的话可以去他们的网站上下载。 lalapunk1983 发表于 2013-6-5 18:24 static/image/common/back.gif
mega64的程序也跟这个差不多。不同的就是中断里不用清标志,这个是深圳华普微电子的RF22-23B的模块。其实IC ...
多谢了,已经搞定了,项目继续进行中。 碰到跟楼主一样的问题?请教楼主是那设置出了问题,也给这个贴结下贴 quentin121 发表于 2013-7-12 07:33 static/image/common/back.gif
碰到跟楼主一样的问题?请教楼主是那设置出了问题,也给这个贴结下贴
哥们,看下我有个关于si4432官方demo的帖子就明白了。用官方的demo很容易调通。 我现在也遇到这样的问题了,求解决方法。 我也遇到这个问题了。只能接收一次,之后IRQ引脚 一直拉低。不知道楼主具体怎么解决的? IRQ脚需要配置为上拉输入
页:
[1]