搜索
bottom↓
回复: 17

51调试si4432程序源码 完整程序文件

[复制链接]

出0入0汤圆

发表于 2011-8-16 16:03:36 | 显示全部楼层 |阅读模式
/*
* 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();
                }        
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2011-8-16 16:05:24 | 显示全部楼层
网速太慢,整个文件没能传上,改天继续吧。

出0入0汤圆

 楼主| 发表于 2011-8-17 13:22:40 | 显示全部楼层
完整程序文件如下:点击此处下载 ourdev_668447OEXN7G.rar(文件大小:59K) (原文件名:RFtest51_1.rar)

出0入0汤圆

发表于 2011-8-19 19:53:45 | 显示全部楼层
请问一下楼主,你的这个测试实际距离有多远?我的一直不理想,距离好近,就几十米……

出0入0汤圆

 楼主| 发表于 2011-8-21 15:28:46 | 显示全部楼层
回复【3楼】lwcode
-----------------------------------------------------------------------

回复【3楼】lwcode
-----------------------------------------------------------------------

测试距离跟硬件设计关系很大啊!

出0入0汤圆

 楼主| 发表于 2011-8-22 08:23:47 | 显示全部楼层
回复【4楼】aabbccdd
-----------------------------------------------------------------------

si4432是一款很不错的无线芯片。采用Silicon Labs EZRadioPRO系列ISM频段无线芯片SI4432,在240-960 MHZ频段下最大输出功率可以达到+20DBm。

出0入0汤圆

发表于 2011-11-9 00:49:50 | 显示全部楼层
回复【6楼】yyzhen
-----------------------------------------------------------------------

问下楼主 你这程序是能通讯吗? 看了你的SPI读写程序,有点疑问 看SI4432 SPI读写这应该使用 SPI模式0 CKPOL=0, CKPHA=0


(原文件名:QQ截图未命名.jpg)

tDS Data setup time 20 时钟在低电平数据建立过程
tDH Data hold time 20  时钟在高电平数据保持过程

出0入0汤圆

发表于 2011-11-13 21:52:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-14 13:44:34 | 显示全部楼层
mark!

出0入0汤圆

 楼主| 发表于 2011-11-17 08:52:05 | 显示全部楼层
欢迎加入我创建的单片机技术交流群,群号:92381027
无论你是擅长51,avr还是msp430单片机的,用c语言编程都是相通的,欢迎加入。相互学习

出0入0汤圆

发表于 2011-12-17 18:29:45 | 显示全部楼层
多谢楼主的分享,好好学习下!

出0入0汤圆

发表于 2012-2-25 00:54:52 | 显示全部楼层
正在调试中...使用你的代码已经可以发送了

出0入0汤圆

发表于 2012-2-25 09:02:08 | 显示全部楼层
mark!!

出0入0汤圆

发表于 2012-2-27 15:47:41 | 显示全部楼层
MARK!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 05:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表