第一次使用无线通信的芯片,第一次接触SPI总线时序,第一次遇到芯片有问题,很多的第一次,所以最后成功了我觉得很有意义,收获了很多,有必要用寥寥数字来记录一下。最开始老板给的是一个NRF401的芯片,后来网上一查,这玩意早停产了,不过发现其操作和硬件接口非常简单,编程应该也非常简单,于是乎三下两下的接好电路,编好程序,上电一跑,晕了!完全没反应,一开始还怀疑自己的程序或者硬件电路哪里错了,DEBUG,查资料搞了好几天,最后确定自己没有搞错。于是乎,又把401拿掉,直接用2根导线把两块板子的串行口接好,然后奇迹出现了,如同我设想的那样运行。好吧,终于可以确定这2块不知放了多少年布满飞尘的401是坏的了。然后上网继续寻找替代品,淘宝上一搜人气最高的是NRF24L01,本来还想买905的,不过哥相信群众,于是买了2块NRF24L01回来。这个芯片的接口是SPI的接口,的确让我郁闷了一阵,以前从来没接触过这个玩意,而且一般的单片机哪有SPI接口,身边的一块ARM板倒是有不过只有一块啊,于是又硬着头皮去看如何用普通IO口模拟出SPI的时序来操作NRF24L01,等搞明白了芯片也寄到了,又是一阵捣鼓,接好线,相当多的线,编好程序,相对401来说很长的程序。一上电,又晕了,还是没反应。然后就是无止境的调试,修改程序,整整花了一周多时间后终于遇到了曙光啊!一个网上的高手帮我用他那边的示波器分析了一下我的程序波形,说没有问题啊,然后另一个高手告诉我应该怎样来一步一步地调试这些芯片,比如先给芯片寄存器写一个值然后马上读出来,看是否写操作正确,等等。这个经验之谈真是犹如黑夜里的一盏明灯啊,让我豁然开朗,马上照高手指点的一搞,结果出来了。2块NRF24L01的其中一块根本写不进去数据,完全是坏的,哎!人品啦!(我承认是我太傻太天真了,以为老板发货的时候都会先帮我检查一遍)马上和淘宝上的老板沟通了一下,让我把坏的寄过去他检查如果确实是他们的原因他们负责再给我寄一个过来,同时包邮费。好吧,我又等,等了一周老板来电话了通知我确实是他们的问题给我寄了一块坏的芯片,并给我重新寄来了一块好的。然后继续等啊等,又是一周,东西终于来了。这次哥颤抖着以迅雷不及掩耳盗铃儿响叮当之势再一次接好线,下好以前写好的程序,谢天谢地谢亚龙啊,这次总算测试通过,两块芯片都是好的了。今天自己又写了一个发送与接收单工通信的测试程序,跑了一下。恩,效果不错,看到接收端不停得把收到的数据显示在电脑上时内牛满面啊!这其中也有个小插曲,一开始接收的数组被我定义在了code段,结果发送端都能正确收到接收的应答信号,但接收端就是不能把数据写进接收数组里面,程序编译也通过。后来一想才明白CODE内的代码是下载到flash中的,是修改不了的。最后改成data修饰,终于能正常运行了。当初我曾请一个调出来的网友把他的程序借我参考下,但他说这是公司的商业机密,不能给,哎,为了以后的同仁少走弯路,我把我调好的测试程序放上来。#includereg52.h#includeintrins.h#defineMODE0//MODE=1时为发送代码MODE=0时为接收代码typedefunsignedcharuchar;//****************************************IO端口定义***************************************sbitMISO=P2^3;sbitMOSI=P2^2;sbitSCK=P2^1;sbitCE=P2^5;sbitCSN=P2^0;sbitIRQ=P3^2;sbitled=P1^2;//******************************************************************************************ucharbdatasta;//状态标志sbitRX_DR=sta^6;sbitTX_DS=sta^5;sbitMAX_RT=sta^4;//*********************************************NRF24L01*************************************#defineTX_ADR_WIDTH5//5uintsTXaddresswidth#defineRX_ADR_WIDTH5//5uintsRXaddresswidth#defineTX_PLOAD_WIDTH32//32uintsTXpayload#defineRX_PLOAD_WIDTH32//32uintsTXpayloaducharconstTX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//本地地址ucharconstRX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收地址ucharcodeTx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据ucharRx_Buf[RX_PLOAD_WIDTH];//接收数据//***************************************NRF24L01寄存器指令*******************************************************#defineREAD_REG0x00//读寄存器指令#defineWRITE_REG0x20//写寄存器指令#defineRD_RX_PLOAD0x61//读取接收数据指令#defineWR_TX_PLOAD0xA0//写待发数据指令#defineFLUSH_TX0xE1//冲洗发送FIFO指令#defineFLUSH_RX0xE2//冲洗接收FIFO指令#defineREUSE_TX_PL0xE3//定义重复装载数据指令#defineNOP0xFF//保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#defineCONFIG0x00//配置收发状态,CRC校验模式以及收发状态响应方式#defineEN_AA0x01//自动应答功能设置#defineEN_RXADDR0x02//可用信道设置#defineSETUP_AW0x03//收发地址宽度设置#defineSETUP_RETR0x04//自动重发功能设置#defineRF_CH0x05//工作频率设置#defineRF_SETUP0x06//发射速率、功耗功能设置#defineSTATUS0x07//状态寄存器#defineOBSERVE_TX0x08//发送监测功能#defineCD0x09//地址检测#defineRX_ADDR_P00x0A//频道0接收数据地址#defineRX_ADDR_P10x0B//频道1接收数据地址#defineRX_ADDR_P20x0C//频道2接收数据地址#defineRX_ADDR_P30x0D//频道3接收数据地址#defineRX_ADDR_P40x0E//频道4接收数据地址#defineRX_ADDR_P50x0F//频道5接收数据地址#defineTX_ADDR0x10//发送地址寄存器#defineRX_PW_P00x11//接收频道0接收数据长度#defineRX_PW_P10x12//接收频道0接收数据长度#defineRX_PW_P20x13//接收频道0接收数据长度#defineRX_PW_P30x14//接收频道0接收数据长度#defineRX_PW_P40x15//接收频道0接收数据长度#defineRX_PW_P50x16//接收频道0接收数据长度#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置/******************************************延时函数********************************************************///长延时voidDelay(unsignedints){unsignedinti,j;for(i=0;i1000;i++)for(j=0;js;j++);}//短延时voiddelay_ms(unsignedintx){unsignedinti,j;i=0;for(i=0;ix;i++){j=108;;while(j--);}}/************************************IO口模拟SPI总线代码************************************************/ucharSPI_RW(ucharbyte){ucharbit_ctr;for(bit_ctr=0;bit_ctr8;bit_ctr++){MOSI=(byte&0x80);byte=(byte1);SCK=1;byte|=MISO;//led=MISO;Delay(150);SCK=0;}return(byte);}ucharSPI_RW_Reg(ucharreg,ucharvalue)//向寄存器REG写一个字节,同时返回状态字节{ucharstatus;CSN=0;status=SPI_RW(reg);SPI_RW(value);CSN=1;return(status);}ucharSPI_Read(ucharreg){ucharreg_val;CSN=0;SPI_RW(reg);reg_val=SPI_RW(0);CSN=1;return(reg_val);}ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes){ucharstatus,byte_ctr;CSN=0;//SetCSNlow,initSPItranactionstatus=SPI_RW(reg);//Selectregistertowritetoandreadstatusbytefor(byte_ctr=0;byte_ctrbytes;byte_ctr++)//thenwriteallbyteinbuffer(*pBuf)SPI_RW(*pBuf++);CSN=1;//SetCSNhighagainreturn(status);//returnnRF24L01statusbyte}#ifMODE/*******************************发*****送*****模*****式*****代*****码*************************************/voidTX_Mode(void){CE=0;SPI_RW_Reg(FLUSH_TX,0x00);SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//WritesTX_AddresstonRF24L01SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//RX_Addr0sameasTX_AdrforAuto.AckSPI_RW_Reg(WRITE_REG+EN_AA,0x01);//EnableAuto.Ack:Pipe0SPI_RW_Reg(WRITE_REG+EN_RXADDR