OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 综合技术 » 物联网技术 » 分享得到的一个“穿墙王”程序源码完整程序文件

共17条 1/2 1 2 跳转至

分享得到的一个“穿墙王”程序源码完整程序文件

菜鸟
2013-12-25 17:02:59    评分

最近在与深圳世强的FAE帮助下在利用他们提供Si4438样片和开发板在开发无线抄表方案。搜Si4438的资料,看到阿莫论坛上有朋友分享的si4432 51调试程序源码(原帖链接http://www.amobbs.com/thread-4969312-1-1.html



其实Si4438si4432的升级版,硬件特性上有很多提升,为中国智能电表市场定制的,只支持470-510MHz频段,所以价格、功耗和尺寸都有降低。不知道坛子里有没有熟悉这两款芯片的?有在做这个项目的可以试一试这个程序,还没有认真研读过代码,也不太了解Si4432,不知道代码是否兼容,改天请教世强的专家两款芯片在硬件、寄存器配置、管脚兼容以及软件上的兼容性,也欢迎大家讨论下!~



/*
* Copyright (c) 2011, 
* All rights reserved.
*
* 当前版本:1.0
* 作者:杨永贞QQ534117529
* 开始日期:2011年8月10日
*
*/
#include <reg51.h>
#include <string.h>
#include "radio.h"
#include"spi.h"
#include"uart.h"
#define  U8 unsigned char
#define SEND_OUT_MESSAGE_WITH_ACK      "NEED_ACK"
#define SEND_OUT_MESSAGE_NO_ACK        "NO_ACK"
#define SEND_OUT_ACK                   "ACK!"


#define SEND_OUT_MESSAGE_WITH_ACK_LEN   8
#define SEND_OUT_MESSAGE_NO_ACK_LEN     6
#define SEND_OUT_ACK_LEN                4
#define SNED_OUT_MSG_MAX_LEN            8       //It is the maxium length of the send out packet.


extern idata U8 ItStatus1,ItStatus2;
void delay_ms(unsigned int ms)
{
        unsigned int i;
        unsigned char j;
        for(i=0;i<ms;i++)
        {
                for(j=0;j<200;j++);
                for(j=0;j<102;j++);
        } 
}
void Init_Device(void)
{
//   Reset_Sources_Init();
//   PCA_Init();
  //  Port_IO_Init();   // Oscillator_Init();
  // Timer0_Init();
    SPI_Init();
        EA = 1; //Enable Gloable interruption.


        //启动射频模块,模块的SDN引脚拉低后必须延时至少30ms,实际上可以直接把SDN引脚接地,这样就不用在程序中初始化了;
        RF_SDN=0;
        delay_ms(30);
        delay_ms(30);
//        RF_SDN = 0;
//        DelayMs(30);
//        NSEL = 1;
//        SCLK = 0;


           SpiWriteRegister(0x0B, 0xCA);
           SpiWriteRegister(0x0C, 0xCA);
           SpiWriteRegister(0x0D, 0xCA);


        //1.Blink the LED to show that the initialization is finished.
        //2.Wait for more than 16ms to wait for the radio chip to work correctly.
//        TurnOnAllLEDs();


//        DelayMs(20);
        delay_ms(20);
//        TurnOffAllLEDs();
}


void main(void)
{
        U8 length,temp8, *str, sendLen;
        U8 payload[10];


        //Initialize the MCU: 
        UART_Init(); 
        Init_Device();
        UART_Send_Str("MCU初始化完毕....\n");
        //读取中断状态寄存器清除中断标志以便释放NIRQ引脚
        //如果中断来了,那么NIRQ引脚会被拉低;如果这时候中断状态寄存器0x03和0x04被读取,那么NIRQ引脚会被释放恢复高电平
        ItStatus1 = SpiReadRegister(0x03);                                                                                                        //read the Interrupt Status1 register
        ItStatus2 = SpiReadRegister(0x04);                                                                                                        //read the Interrupt Status2 register
        
        //SW reset,软件复位这个模块主控芯片   
    SpiWriteRegister(0x07, 0x80);                                                                                                                //write 0x80 to the Operating & Function Control1 register 
//        DelayMs(20);
        delay_ms(20);
        delay_ms(20);
        //wait for POR interrupt from the radio (while the nIRQ pin is high)
        //wait for chip ready interrupt from the radio (while the nIRQ pin is high)
        //等待软复位完成,当软复位完成后有中断发生。客户也可以在这里直接延时至少20ms而不用等待中断来;等待至少20ms后复位完成,这时候必须读中断状态寄存器释放中断引脚
        while ( NIRQ == 1);  
        //read interrupt status registers to clear the interrupt flags and release NIRQ pin
        ItStatus1 = SpiReadRegister(0x03);                                                                                                        //read the Interrupt Status1 register
        ItStatus2 = SpiReadRegister(0x04);                                                                                                        //read the Interrupt Status2 register
        
        //根据不同的射频参数初始化射频模块;
    RF_init();
        UART_Send_Str("RF芯片si4432初始化完毕....\n");
        //Enable two interrupts: 
        // a) one which shows that a valid packet received: 'ipkval'
        // b) second shows if the packet received with incorrect CRC: 'icrcerror'
        //设置中断使能寄存器,这里设置为只有当有效的数据包被接收或者接收到的数据包数据CRC校验出错才来中断;具体设置参考0x05和0x06寄存器 
        SpiWriteRegister(0x05, 0x03);                                                                                                                        //write 0x03 to the Interrupt Enable 1 register
        SpiWriteRegister(0x06, 0x00);                                                                                                                        //write 0x00 to the Interrupt Enable 2 register


        //output dummy data.
        PB1_TX = 1;
        PB2_TX = 1;


        str = SEND_OUT_MESSAGE_WITH_ACK;
        sendLen = SEND_OUT_MESSAGE_WITH_ACK_LEN;


        //设置模块处于接收状态,当没有按键按下的时候一直处于接收状态,等待接收数据
        RFSetRxMode();
        UART_Send_Str("模块处于接收状态....\n");
        /*MAIN Loop*/
        while(1)
        {


                //当按键被按下就有一个数据包被发出;
            if(PB1_TX == 0)
                {
                        while( PB1_TX == 0 );
                        UART_Send_Str("按键按下,开始发送....\n");
                        RFFIFOSendData(sendLen, str);
                        //after packet transmission set the interrupt enable bits according receiving mode
                        //Enable two interrupts: 
                        // a) one which shows that a valid packet received: 'ipkval'
                        // b) second shows if the packet received with incorrect CRC: 'icrcerror' 
                        //设置中断使能寄存器,这里设置为只有当有效的数据包被接收或者接收到的数据包数据CRC校验出错才来中断;具体设置参考0x05和0x06寄存器 
                        SpiWriteRegister(0x05, 0x03);                                                                                                 //write 0x03 to the Interrupt Enable 1 register
                        SpiWriteRegister(0x06, 0x00);                                                                                                 //write 0x00 to the Interrupt Enable 2 register
                        //发射完毕后设置模块让它又工作在接收状态下;
                        RFSetRxMode();
                        UART_Send_Str("发送完毕,恢复到接收状态....\n");
                }




                //check whether interrupt occured
                //查询中断是否到来,如果中断来了,根据我们前面中断使能寄存器的设置,说明有效数据包已经收到,或者收到的数据包CRC校验出错;
                //如果客户采用中断触发的方式,那么服务程序必须包括这些内容。在中断服务程序中必须判断被使能的那些中断的状态位是否被置位,然后根据不同的
                //状态位进行处理
                if( NIRQ == 0 )
                {
                
                  //设置模块处于空闲模式,处理收到的数据包,不继续接收数据
                        RFSetIdleMode();
                 UART_Send_Str("中断来了....\n");
                        /*CRC Error interrupt occured*/
                        //判断是否由于CRC校验出错引发的中断;在RFSetIdleMode中已经读出了中断状态寄存器的值
                        if( (ItStatus1 & 0x01) == 0x01 )
                        {
                                //reset the RX FIFO
                                //如果是CRC校验出错,那么接收FIFO复位;
                             SpiWriteRegister(0x08, 0x02);                                                                                                //write 0x02 to the Operating Function Control 2 register
                    SpiWriteRegister(0x08, 0x00);                                                                                                //write 0x00 to the Operating Function Control 2 register
                                //blink all LEDs to show the error
                                //闪灯提示,客户移植代码的时候这个闪灯操作根据不同客户不同操作
                        //        TurnOnAllLEDs();
                        //        DelayMs(2);
                                UART_Send_Str("CRC校验出错中断....\n");
                        //        TurnOffAllLEDs();
                        }


                        /*packet received interrupt occured*/
                        //判断是否是数据包已经被正确接收。
                        if( (ItStatus1 & 0x02) == 0x02 )
                        {
                                //Read the length of the received payload
                                //数据包已经被正确接收,读取收到的数据包长度
                                length = SpiReadRegister(0x4B);                                                                                        //read the Received Packet Length register
                                //根据长度判断相应的操作。客户可以不做这些,而直接从FIFO读出收到的数据;
                                //check whether the received payload is not longer than the allocated buffer in the MCU
                                if(length <= SNED_OUT_MSG_MAX_LEN)
                                {
                                        //Get the reeived payload from the RX FIFO
                                        //直接从FIFO中读取收到的数据。客户只要读出FIFO的数据就算收到数据。
                                        for(temp8=0;temp8 < length;temp8++)
                                        {
                                                payload[temp8] = SpiReadRegister(0x7F);                                                //read the FIFO Access register
                                        }
                                
                                        for(temp8=0;temp8 < length;temp8++)
                                        {
                                                UART_Send_Byte(payload[temp8]);        //向串口发送接收到的数据
                                        }
                         UART_Send_Str("向串口发送接收到的数据....\n");
                                        //check whether the acknowledgement packet received
                                        //判断是否是预先设定的数据;一般应用情况客户可以不理会这个,这个判断只是我们demo板的应用。客户只要读出FIFO的数据就算收到数据;
                                        if(( length == SEND_OUT_ACK_LEN ) || (length == SEND_OUT_MESSAGE_NO_ACK_LEN))
                            {
                                    if((memcmp(&payload[0], SEND_OUT_ACK, SEND_OUT_ACK_LEN - 1) == 0 )
                                                || (memcmp(&payload[0], SEND_OUT_MESSAGE_NO_ACK, SEND_OUT_MESSAGE_NO_ACK_LEN - 1) == 0))
                                                   {
                                          //blink LED2 to show that ACK received
                                             //        RxLEDOn();
                                                        //Show the Rx LED for about 10ms
                                                        UART_Send_Str("数据包已经被正确接收....\n");
                                                //        DelayMs(2);
                                                     //        TurnOffAllLEDs();
                                                }
                                        }


                                        //check whether an expected packet received, this should be acknowledged
                                        //判断是否是需要发送回答信号的数据包。这个只是根据收到的数据做的不同操作,在客户那里可能是根据收到的数据做的特定的操作,例如控制某个开关
                                        if( length == SEND_OUT_MESSAGE_WITH_ACK_LEN ) 
                            {
                                                //必须发送应答信号,启动发送
                                    if( memcmp(&payload[0], SEND_OUT_MESSAGE_WITH_ACK, SEND_OUT_MESSAGE_WITH_ACK_LEN - 1) == 0 )
                                           {
                                         //blink LED2 to show that the packet received
                                                     //RxLEDOn();
                                                        //Show the Rx LED for about 10ms
                                                //        DelayMs(2);
                                                        UART_Send_Str("发送应答....\n");
                                                     //        TurnOffAllLEDs();


                                                        //发送应答信号。
                                                        /*send back an acknowledgement*/
                                                        RFFIFOSendData(SEND_OUT_ACK_LEN, SEND_OUT_ACK);


                                                        //after packet transmission set the interrupt enable bits according receiving mode
                                                        //Enable two interrupts: 
                                                        // a) one which shows that a valid packet received: 'ipkval'
                                                        // b) second shows if the packet received with incorrect CRC: 'icrcerror' 
                                                        SpiWriteRegister(0x05, 0x03);                                                                 //write 0x03 to the Interrupt Enable 1 register
                                                        SpiWriteRegister(0x06, 0x00);                                                                 //write 0x00 to the Interrupt Enable 2 register
                                                        //read interrupt status registers to release all pending interrupts
                                                        ItStatus1 = SpiReadRegister(0x03);                                                        //read the Interrupt Status1 register
                                                        ItStatus2 = SpiReadRegister(0x04);                                                        //read the Interrupt Status2 register
                                                }
                                        }
                                }
                       }
                        //reset the RX FIFO
                       SpiWriteRegister(0x08, 0x02);                                                                                                        //write 0x02 to the Operating Function Control 2 register
                SpiWriteRegister(0x08, 0x00);                                                                                                        //write 0x00 to the Operating Function Control 2 register
                        RFSetRxMode();
                }         
        }
}

 




院士
2013-12-25 20:51:19    评分
2楼
没有使用贴代码功能?

高工
2013-12-25 22:06:48    评分
3楼
修饰一下,帅多了、

菜鸟
2013-12-27 11:44:02    评分
4楼
4432应该是兼容的吧? Si4438与Si446x收发器产品引脚兼容以及软件兼容哦(是针对全球部署智能电表和智能电网产品而设计的sub-GHz ISM频段产品)。

菜鸟
2014-01-02 14:34:25    评分
5楼

多谢版主帮修饰,确实好看多了!


回LS的: 并不完全兼容,下面是我请世强的杨工提供的采用Si4438的部分代码,大家可以参考下,完整的代码可以找深圳世强的FAE杨工要。大家可以对比研究下。

 

#include "compiler_defs.h"
#include "c8051f960_defs.h"
#include "hardware_defs.h"
#include "control_IO.h"
#include "spi.h"
#include "Si446x_B0_defs.h"
#include "ezrp_next_api.h"
#include "modem_params.h"
// Define capacitor bank value
#define CAP_BANK_VALUE    0x48    // Capacitor bank value for adjusting the XTAL frequency
                                  // Note that it may varies on different test cards
/*------------------------------------------------------------------------*/
/*            GLOBAL variables                        */
/*------------------------------------------------------------------------*/
// Set up modem parameters database; data is retrieved from modem_params.h header file which is
// automatically generated by the WDS (Wireless Development Suite)
SEG_CODE U8 ModemTrx1[] = {7, MODEM_MOD_TYPE_7};
SEG_CODE U8 ModemTrx2[] = {5, MODEM_CLKGEN_BAND_5};
SEG_CODE U8 ModemTrx3[] = {11, SYNTH_PFDCP_CPFF_11};
SEG_CODE U8 ModemTrx4[] = {12, FREQ_CONTROL_INTE_12};
SEG_CODE U8 ModemRx1[] = {11, MODEM_MDM_CTRL_11};
SEG_CODE U8 ModemRx2[] = {14, MODEM_BCR_OSR_1_14};
SEG_CODE U8 ModemRx3[] = {12, MODEM_AFC_GEAR_12};
SEG_CODE U8 ModemRx4[] = {5, MODEM_AGC_CONTRL_5};
SEG_CODE U8 ModemRx4_1[] = {7, MODEM_AGC_WINDOW_SIZE_7};
SEG_CODE U8 ModemRx5[] = {9, MODEM_FSK4_GAIN1_9};
SEG_CODE U8 ModemRx6[] = {8, MODEM_OOK_PDTC_8};
SEG_CODE U8 ModemRx7[] = {8, MODEM_RAW_SEARCH_8};
SEG_CODE U8 ModemRx8[] = {6, MODEM_ANT_DIV_MODE_6};
SEG_CODE U8 ModemRx9[] = {13, MODEM_CHFLT_RX1_CHFLT_COE13_7_0_13};
SEG_CODE U8 ModemRx10[] = {13, MODEM_CHFLT_RX1_CHFLT_COE4_7_0_13};
SEG_CODE U8 ModemRx11[] = {13, MODEM_CHFLT_RX2_CHFLT_COE13_7_0_13};
SEG_CODE U8 ModemRx12[] = {13, MODEM_CHFLT_RX2_CHFLT_COE4_7_0_13};
/*------------------------------------------------------------------------*/
/*            LOCAL function prototypes                         */
/*------------------------------------------------------------------------*/
void MCU_Init(void);
/*------------------------------------------------------------------------*/
/*            MAIN function                             */
/*------------------------------------------------------------------------*/
void main(void)
{
  SEGMENT_VARIABLE(wDelay, U16, SEG_XDATA);
  SEGMENT_VARIABLE(bButtonNumber, U8, SEG_XDATA);
  BIT fValidPacket;
  //initialize the MCU peripherals
  MCU_Init();
  InitIO();
  // Reset the radio
  EZRP_PWRDN = 1;
  // Wait ~300us (SDN pulse width)
  for(wDelay=0; wDelay<330; wDelay++);
  // Wake up the chip from SDN
  EZRP_PWRDN = 0;
  // Wait for POR (power on reset); ~5ms
  for(wDelay=0; wDelay<5500; wDelay++);
  // Start the radio
  abApi_Write[0] = CMD_POWER_UP;          // Use API command to power up the radio IC
  abApi_Write[1] = 0x01;              // Write global control registers
  abApi_Write[2] = 0x00;              // Write global control registers
  bApi_SendCommand(3,abApi_Write);        // Send command to the radio IC
  // Wait for boot
  if (vApi_WaitforCTS())                // Wait for CTS
  {
    while (1) {}    // Stop if radio power-up error
  }
  // Read ITs, clear pending ones
  abApi_Write[0] = CMD_GET_INT_STATUS;      // Use interrupt status command
  abApi_Write[1] = 0;               // Clear PH_CLR_PEND
  abApi_Write[2] = 0;               // Clear MODEM_CLR_PEND
  abApi_Write[3] = 0;               // Clear CHIP_CLR_PEND
  bApi_SendCommand(4,abApi_Write);        // Send command to the radio IC
  bApi_GetResponse(8, abApi_Read );         // Make sure that CTS is ready then get the response
  // Set TRX parameters of the radio IC; data retrieved from the WDS-generated modem_params.h header file
  bApi_SendCommand(ModemTrx1[0],&ModemTrx1[1]);       // Send API command to the radio IC
  vApi_WaitforCTS();                    // Wait for CTS
  bApi_SendCommand(ModemTrx2[0],&ModemTrx2[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemTrx3[0],&ModemTrx3[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemTrx4[0],&ModemTrx4[1]);
  vApi_WaitforCTS();
  // Set Rx parameters of the radio IC
  bApi_SendCommand(ModemRx1[0],&ModemRx1[1]);       // Send API command to the radio IC
  vApi_WaitforCTS();                    // Wait for CTS
  bApi_SendCommand(ModemRx2[0],&ModemRx2[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx3[0],&ModemRx3[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx4[0],&ModemRx4[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx4_1[0],&ModemRx4_1[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx5[0],&ModemRx5[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx6[0],&ModemRx6[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx7[0],&ModemRx7[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx8[0],&ModemRx8[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx9[0],&ModemRx9[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx10[0],&ModemRx10[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx11[0],&ModemRx11[1]);
  vApi_WaitforCTS();
  bApi_SendCommand(ModemRx12[0],&ModemRx12[1]);
  vApi_WaitforCTS();
  // Enable packet received and CRC error interrupt only
  abApi_Write[0] = CMD_SET_PROPERTY;      // Use property command
  abApi_Write[1] = PROP_INT_CTL_GROUP;    // Select property group
  abApi_Write[2] = 4;               // Number of properties to be written
  abApi_Write[3] = PROP_INT_CTL_ENABLE;   // Specify property
  abApi_Write[4] = 0x01;                   // INT_CTL: PH interrupt enabled
  abApi_Write[5] = 0x18;              // INT_CTL_PH: PH PACKET_RX & CRC2_ERR interrupt enabled
  abApi_Write[6] = 0x00;              // INT_CTL_MODEM: -
  abApi_Write[7] = 0x00;              // INT_CTL_CHIP_EN: -
  bApi_SendCommand(8,abApi_Write);        // Send API command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Configure Fast response registers
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_FRR_CTL_GROUP;      // Select property group
  abApi_Write[2] = 4;               // Number of properties to be written
  abApi_Write[3] = PROP_FRR_CTL_A_MODE;     // Specify property (1st)
  abApi_Write[4] = 0x04;              // FRR A: PH IT pending
  abApi_Write[5] = 0x06;              // FRR B: Modem IT pending
  abApi_Write[6] = 0x0A;              // FRR C: Latched RSSI
  abApi_Write[7] = 0x00;              // FRR D: disabled
  bApi_SendCommand(8,abApi_Write);        // Send API command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  //Set packet content
  //Set preamble length
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_PREAMBLE_GROUP;     // Select property group
  abApi_Write[2] = 1;               // Number of properties to be written
  abApi_Write[3] = PROP_PREAMBLE_CONFIG_STD_1;  // Specify property
  abApi_Write[4] = 20;              // 20 bits preamble detection threshold
  bApi_SendCommand(5,abApi_Write);        // Send API command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Set preamble pattern
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_PREAMBLE_GROUP;     // Select property group
  abApi_Write[2] = 1;               // Number of properties to be written
  abApi_Write[3] = PROP_PREAMBLE_CONFIG;      // Specify property
  abApi_Write[4] = 0x31;              // Use `1010` pattern, length defined in bytes
  bApi_SendCommand(5,abApi_Write);        // Send API command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Set sync word
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_SYNC_GROUP;       // Select property group
  abApi_Write[2] = 3;               // Number of properties to be written
  abApi_Write[3] = PROP_SYNC_CONFIG;        // Specify property
  abApi_Write[4] = 0x01;              // SYNC_CONFIG: 2 bytes sync word
  abApi_Write[5] = 0xB4;              // SYNC_BITS_31_24: 1st sync byte: 0x2D; NOTE: LSB transmitted first!
  abApi_Write[6] = 0x2B;              // SYNC_BITS_23_16: 2nd sync byte: 0xD4; NOTE: LSB transmitted first!
  bApi_SendCommand(7,abApi_Write);        // Send command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // General packet config (set bit order)
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_PKT_GROUP;        // Select property group
  abApi_Write[2] = 1;               // Number of properties to be written
  abApi_Write[3] = PROP_PKT_CONFIG1;        // Specify property
  abApi_Write[4] = 0x00;              // Payload data goes MSB first
  bApi_SendCommand(5,abApi_Write);        // Send command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Set RSSI latch to sync word
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_MODEM_GROUP;        // Select property group
  abApi_Write[2] = 1;               // Number of properties to be written
  abApi_Write[3] = PROP_MODEM_RSSI_CONTROL;   // Specify property
  abApi_Write[4] = 0x12;              // RSSI average over 4 bits, latch at sync detect
  bApi_SendCommand(5,abApi_Write);        // Send API command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Configure the GPIOs
  abApi_Write[0] = CMD_GPIO_PIN_CFG;        // Use GPIO pin configuration command
#ifdef ONE_SMA_WITH_RF_SWITCH
  // If RF switch is used
  // Select Tx state to GPIO2, Rx state to GPIO0
  abApi_Write[1] = 0x21;              // Configure GPIO0 as Rx state
  abApi_Write[2] = 0x13;              // Configure GPIO1 as Tx data
  abApi_Write[3] = 0x20;              // Configure GPIO2 as Tx state
  abApi_Write[4] = 0x10;              // Configure GPIO3 as Tx data CLK
#else
  abApi_Write[1] = 0x10;              // Configure GPIO0 as Tx data CLK
  abApi_Write[2] = 0x13;              // Configure GPIO1 as Tx data
  abApi_Write[3] = 0x20;              // Configure GPIO2 as Tx state
  abApi_Write[4] = 0x21;              // Configure GPIO3 as Rx state
#endif
  bApi_SendCommand(5,abApi_Write);        // Send command to the radio IC
  vApi_WaitforCTS();
  // Adjust XTAL clock frequency
  abApi_Write[0] = CMD_SET_PROPERTY;        // Use property command
  abApi_Write[1] = PROP_GLOBAL_GROUP;       // Select property group
  abApi_Write[2] = 1;               // Number of properties to be written
  abApi_Write[3] = PROP_GLOBAL_XO_TUNE;     // Specify property
  abApi_Write[4] = CAP_BANK_VALUE;        // Set cap bank value to adjust XTAL clock frequency
  bApi_SendCommand(5,abApi_Write);        // Send command to the radio IC
  vApi_WaitforCTS();                // Wait for CTS
  // Read ITs, clear pending ones
  abApi_Write[0] = CMD_GET_INT_STATUS;  // Use interrupt status command
  abApi_Write[1] = 0;           // Clear PH_CLR_PEND
  abApi_Write[2] = 0;           // Clear MODEM_CLR_PEND
  abApi_Write[3] = 0;           // Clear CHIP_CLR_PEND
  bApi_SendCommand(4,abApi_Write);    // Send command to the radio IC
  bApi_GetResponse(8,abApi_Read);     // Get the response
  // Start Rx
  abApi_Write[0] = CMD_START_RX;      // Use start Rx command
  abApi_Write[1] = 0;           // Set channel number
  abApi_Write[2] = 0x00;          // Start Rx immediately
  abApi_Write[3] = 0x00;          // 8 bytes to receive
  abApi_Write[4] = 0x08;          // 8 bytes to receive
  abApi_Write[5] = 0x00;          // No change if Rx timeout
  abApi_Write[6] = 0x03;          // Ready state after Rx
  abApi_Write[7] = 0x03;          // Ready state if Rx invalid
  bApi_SendCommand(8,abApi_Write);    // Send API command to the radio IC
  vApi_WaitforCTS();            // Wait for CTS
  // Turn off LEDs
  ClearLed(1);
  ClearLed(2);
  ClearLed(3);
  ClearLed(4);
  while(1)
  {
    if(EZRP_NIRQ == 0)
    {
      // Read PH IT registers to see the cause for the IT
      abApi_Write[0] = CMD_GET_PH_STATUS;   // Use packet handler status command
      abApi_Write[1] = 0x00;          // Dummy byte for a proper CTS response
      bApi_SendCommand(2,abApi_Write);    // Send command to the radio IC
      bApi_GetResponse(1,abApi_Read);     // Make sure that CTS is ready then get the response
      if((abApi_Read[0] & 0x10) == 0x10)    // Check if packet received
      {// Packet received
        // Get RSSI
        bApi_GetFastResponseRegister(CMD_FAST_RESPONSE_REG_C,1,abApi_Read);
        // Read the FIFO
        bApi_ReadRxDataBuffer(8,abApi_Read);
        fValidPacket = 0;
        // Check the packet content
        if ((abApi_Read[0]=='B') && (abApi_Read[1]=='U') && (abApi_Read[2]=='T') && (abApi_Read[3]=='T') && (abApi_Read[4]=='O') && (abApi_Read[5]=='N'))
        {
          bButtonNumber = abApi_Read[6] & 0x07; // Get button info
          if((bButtonNumber > 0) && (bButtonNumber < 5))
          {
            SetLed(bButtonNumber);          // Turn on the appropriate LED
            for(wDelay=0; wDelay<30000; wDelay++);  // Wait to show LED
            ClearLed(bButtonNumber);        // Turn off the corresponding LED
            fValidPacket = 1;
          }
        }
        // Packet content is not what was expected
        if(fValidPacket == 0)
        {
          SetLed(1);                // Blink all LEDs
          SetLed(2);
          SetLed(3);
          SetLed(4);
          for(wDelay=0; wDelay<30000; wDelay++);
          ClearLed(1);
          ClearLed(2);
          ClearLed(3);
          ClearLed(4);
        }
      }
      // Read ITs, clear pending ones
      abApi_Write[0] = CMD_GET_INT_STATUS;  // Use interrupt status command
      abApi_Write[1] = 0;           // Clear PH_CLR_PEND
      abApi_Write[2] = 0;           // Clear MODEM_CLR_PEND
      abApi_Write[3] = 0;           // Clear CHIP_CLR_PEND
      bApi_SendCommand(4,abApi_Write);    // Send command to the radio IC
      bApi_GetResponse(8,abApi_Read);     // Get the response
      // Start Rx
      abApi_Write[0] = CMD_START_RX;      // Use start Rx command
      abApi_Write[1] = 0;           // Set channel number
      abApi_Write[2] = 0x00;          // Start Rx immediately
      abApi_Write[3] = 0x00;          // 8 bytes to receive
      abApi_Write[4] = 0x08;          // 8 bytes to receive
      abApi_Write[5] = 0x00;          // No change if Rx timeout
      abApi_Write[6] = 0x03;          // Ready state after Rx
      abApi_Write[7] = 0x03;          // Ready if Rx invalid
      bApi_SendCommand(8,abApi_Write);    // Send API command to the radio IC
      vApi_WaitforCTS();            // Wait for CTS
    }
  }
}

 


菜鸟
2014-01-10 10:27:23    评分
6楼

关于Si4438,可以看看这个文章,里面可能有介绍,不过没有讲具体的方案细节——世强Silicon labs方案助力无线抄表从模块到终端的“穿越”http://www.eeworld.com.cn/wltx/2013/1219/article_12016.html


菜鸟
2014-01-15 17:20:02    评分
7楼

很好的分享,可惜不做无线抄表好多年~~~


高工
2014-01-17 15:54:50    评分
8楼
楼主,记得下次用起插入代码功能啊。

菜鸟
2014-01-17 17:38:23    评分
9楼

为什么不用世强提供的完整解决方案?收发器+MCU都可以用他们家的方案呗(貌似瑞萨也是他们家在提供分销业务哦,瑞萨的MCU在电表上应用很普及!)


专家
2014-01-17 22:46:43    评分
10楼

共17条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]