本人是刚学msp430149的新人,用买的学习版的光盘里的示例程序来控制nrf905收发。现在出现了三个问题,希望有经验的各位能帮忙解答下,万分感谢各位。我现在具体的问题是运行程序后,用频谱仪看不到调制好的波形,(有可能是探笔好像有最高探测频率,没有340Mhz,但也有可能没影响)但是SCK和MOSI、MISO引脚有方波,但是只出现一秒,就没了,过了半分钟或重新摆置探笔,就会又出现,而且发送程序里发送寄存器是有数据的,DATABUF里数值也是按照程序正常移动变化。SPI口不知道有没有正常工作。没试过运行相关的程序。接收程序的接受缓存器没有应该接受的数据,全是零。而且出现在while (CheckDR()==0)里出不来。不知道是不是没接受到还是像以前前辈的一个帖子(在下面)里说的那样需要再加个5V的电压。还是根本没有发送出去导致接受不到了。
在以前的帖子里看到:
void RxPacket(unsigned char *RxBuf)
{
while (CheckDR()==0);
char i;
TRX_CE_0;
CSN_0;
使用了一个子函数。这时return 0;虽然可以在while (CheckDR()==0);处等待了,但是一直检测不到return 1;不知道是数据没接收到,还是没发送出来。从头再来!调试发送数据。直接将断点打在发送完成,测量DR状态, DR为高电平说明数据发送完成,0K!
再看接收数据,总是在CheckDR(void)函数出不来,很怀疑。因为DR是nRF905接收到有效数据后给MCU的,MCU检测DR = 1后开始通过SPI口把数据移到寄存器内。所以,问题锁定到P2IN&0x40脚。索性不管它,将5v 电源和 仿真器一起给处理器供电,(之前是为了调试只用仿真器供电的)奇迹出现了,竟然单步执行可以顺利通过。OK!
这段话,我有现在有三个问题:1、我无法同时将5V电源和仿真器一起给处理器供电,如果一起加的话,就出现can't find the device这之类的错误,我使用的仿真器是USB型JTAG仿真器。说是不支持外部供电,USB供电就行。具体的类型见上传的图片。
问题2、在很多调试的帖子里看到:测试nRF905模块是否正常工作
对于发射机 进入发射状态31脚1.5V 23脚1.2V 19脚1.8V
对于接收机 进入接收状态31脚1.2V 23脚1.2V 19脚0V
这个管脚指的是msp430的管脚么?还是无线模块的管脚?无线模块没有32或者23管脚
问题3、之前说过检查SCLK MOSI和MIS0引脚有没有方波。。我用频谱仪看了(由于没有示波器),对于发射机,它们三个管脚是有方波的,但是出现一会就没了,大概一秒,然后过个大概半分钟或者重新摆放探头笔,又会出现方波。DR引脚用交流电压表测试大概是200mv。对于接收机,AM、MISO、CD、DR、MOSI、SCK没有任何波形或电压。
问题4:通过软件的方法测试905是否正常工作更有效。 方法是:配置一个寄存器,先写进去数据,在读出来。如果读写数据一致说明905SPI 通信Ok。但是我不会编程实现?我是在发送的程序里改main修改了一下,其他的都不变,不知这样正不正确?
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; //禁止看门狗
InitSys();
nRF905_IO_set();
LED_IO_set();
Config905();
LED1_1 ; LED2_1 ;
while(1)
{
SpiWrite(0X20);
Delay(200); Delay(200); Delay(200);
Spiread() ;
}
}
我使用的学习板和nrf905模块
[C] 纯文本查看 复制代码
发送程序[C] 纯文本查看 复制代码
#include //==============================================================================#define uchar unsigned char#define uint unsigned int#define uclong unsigned long//==================TXEN,TRX_CE,PWR_0 为收发模式控制端口======================#define TXEN_0 P6OUT &=~BIT0 //输出0#define TXEN_1 P6OUT |= BIT0 //输出1//==============================================================================#define TRX_CE_0 P6OUT &=~BIT1#define TRX_CE_1 P6OUT |= BIT1//==============================================================================#define PWR_0 P6OUT &=~BIT2#define PWR_1 P6OUT |= BIT2//===================================主入从出===================================#define MISO_0 P5OUT &=~BIT2 #define MISO_1 P5OUT |= BIT2 //==================================主出从入====================================#define MOSI_0 P5OUT &=~BIT1 #define MOSI_1 P5OUT |= BIT1 //===================================SPI时钟端口================================#define SCK_0 P5OUT &=~BIT3 #define SCK_1 P5OUT |= BIT3 //===================================SPI使能端口=================================#define CSN_0 P5OUT &=~BIT0#define CSN_1 P5OUT |= BIT0//==================================以下为状态端口==============================//===========================AM 地址匹配=======================================#define AM_0 P6OUT &=~BIT4 #define AM_1 P6OUT |= BIT4//=================================DR 数据接收状态==============================#define DR_0 P6OUT &=~BIT3#define DR_1 P6OUT |= BIT3//=====================================CD 载波侦听状态==========================#define CD_0 P6OUT &=~BIT5#define CD_1 P6OUT |= BIT5//==============================================================================#define LED1_0 P2OUT &=~BIT1 //输出0#define LED1_1 P2OUT |= BIT1 //输出1#define LED2_0 P2OUT &=~BIT2 //输出0#define LED2_1 P2OUT |= BIT2 //输出1//===========================NRF905:SPI指令=====================================#define WC0x00#define RC0x10#define WTP0x20#define RTP0x21#define WTA0x22#define RTA0x23#define RRP0x24//==========================32字节发送数据收发缓冲区============================#define TxRxBuf_Len 32unsigned char TxRxBuf[TxRxBuf_Len]={ 0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,};char TxAddress[4]={0xcc,0xcc,0xcc,0xcc};char DATA_BUF;//==========================NRF905:10寄存器配置================================unsigned char RFConf[11]={ WC, //SPI写操作命令 0x4c, //CH_NO,配置频段在430MHZ 0x0C, //输出功率为10db,不重发,节电为正常模式 0x44, //地址宽度设置,为4字节 0x20,0x20, //接收发送有效数据长度为32字节 0xCC,0xCC,0xCC,0xCC, //接收地址 0x58, //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振};/*****************************************************************************系统初始化******************************************************************************/void InitSys(){ unsigned int iq0; _DINT(); BCSCTL1 &=~XT2OFF; do { IFG1 &= ~OFIFG;// 清除振荡器失效标志 for (iq0 = 0xFF; iq0 > 0; iq0--);// 延时,等待XT2起振 } while ((IFG1 & OFIFG) != 0);// 判断XT2是否起振 BCSCTL2 =SELM1+SELS; //MCLK,SMCLK时钟为XT2//???USART0}//===========================初始化nRF905=======================================void nRF905_IO_set(void){ P6DIR |= 0x07; P6DIR &= 0x8F; P6SEL&=0x84; P2DIR |= 0xFF; P2DIR &= 0xFF; P2SEL&=0xFF; P5DIR |= 0xC0; P5DIR |= 0xFB; P5SEL&=0xF0; CSN_1; // Spi disableSCK_0; // Spi clock line init lowPWR_1; // nRF905 power onTRX_CE_0;// Set nRF905 in standby modeTXEN_0;// set radio in Rx mode}//==============================================================================void LED_IO_set(void){ // P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换 }//==========================延时================================================void Delay(uchar n){uint i;while(n--)for(i=0;i<80;i++);}//=========================NRF905 SPI读函数(IO模拟SPI时序)==================unsigned char SpiRead(void){unsigned char i;for (i=0;i<8;i++){DATA_BUF=DATA_BUF<<1;SCK_1;if ((P5IN&0x04))//读取最高位,保存至最末尾,通过左移位完成整个字节{DATA_BUF|=0x01;}else{DATA_BUF&=~(0x01);}SCK_0; } return DATA_BUF;}//=========================NRF905 SPI读写函数(IO模拟SPI时序)==================void SpiWrite(unsigned char send){unsigned char i;DATA_BUF=send;for (i=0;i<8;i++){if (((DATA_BUF&0x80) != 0))//总是发送最高位 { MOSI_1; }else { MOSI_0; }SCK_1;DATA_BUF=DATA_BUF<<1;SCK_0;}}//==================================初始化NRF905================================void Config905(void){uchar i;CSN_0;// Spi enable for write a spi commandfor (i=0;i<11;i++)// Write configration words 写放配置字{ SpiWrite(RFConf);}CSN_1;//关闭SPI}//=========================NRF905装载地址+数据打包+数据发送=====================void TxPacket(void){uchar i;CSN_0;SpiWrite(WTP);// 待发数据装载命令for (i=0;i<32;i++){ SpiWrite(TxRxBuf);}CSN_1; // 关闭SPIDelay(1);CSN_0;// 打开SPISpiWrite(WTA);// 写入地址要和接收方地址一样for (i=0;i<4;i++)// 4字节地址{ SpiWrite(TxAddress);}CSN_1;//关闭SPITRX_CE_1;// Set TRX_CE high,start Tx data transmissionDelay(10);// while (DR!=1);TRX_CE_0;// Set TRX_CE low}//==================================发送模式初始化-=============================void SetTxMode(void){TRX_CE_0;TXEN_1;Delay(1); // Delay for mode change(>=650us)}//==================================数据发送===================================void TX(void){ SetTxMode();TxPacket();}//==================================主函数=====================================void main(void){ WDTCTL = WDTPW + WDTHOLD; //禁止看门狗 InitSys(); nRF905_IO_set(); LED_IO_set(); Config905(); LED1_1 ; LED2_1 ;while(1) { TX(); P2OUT=P6OUT; Delay(200); Delay(200); Delay(200);LED1_0 ; Delay(200); Delay(200); Delay(200); Delay(200); Delay(200); LED1_1; }}接收程序
[C] 纯文本查看 复制代码
#include //==============================================================================#define uchar unsigned char#define uint unsigned int#define uclong unsigned long//==================TXEN,TRX_CE,PWR_0 为收发模式控制端口======================#define TXEN_0 P6OUT &=~BIT0 //输出0#define TXEN_1 P6OUT |= BIT0 //输出1//==============================================================================#define TRX_CE_0 P6OUT &=~BIT1#define TRX_CE_1 P6OUT |= BIT1//==============================================================================#define PWR_0 P6OUT &=~BIT2#define PWR_1 P6OUT |= BIT2//===================================主入从出===================================#define MISO_0 P5OUT &=~BIT2 #define MISO_1 P5OUT |= BIT2 //==================================主出从入====================================#define MOSI_0 P5OUT &=~BIT1 #define MOSI_1 P5OUT |= BIT1 //===================================SPI时钟端口================================#define SCK_0 P5OUT &=~BIT3 #define SCK_1 P5OUT |= BIT3 //===================================SPI使能端口=================================#define CSN_0 P5OUT &=~BIT0#define CSN_1 P5OUT |= BIT0//==================================以下为状态端口==============================//===========================AM 地址匹配=======================================#define AM_0 P6OUT &=~BIT4 #define AM_1 P6OUT |= BIT4//=================================DR 数据接收状态==============================#define DR_0 P6OUT &=~BIT3#define DR_1 P6OUT |= BIT3//=====================================CD 载波侦听状态==========================#define CD_0 P6OUT &=~BIT5#define CD_1 P6OUT |= BIT5//==============================================================================#define LED1_0 P2OUT &=~BIT1 //输出0#define LED1_1 P2OUT |= BIT1 //输出1#define LED2_0 P2OUT &=~BIT2 //输出0#define LED2_1 P2OUT |= BIT2 //输出1//===========================NRF905:SPI指令=====================================#define WC 0x00#define RC 0x10#define WTP 0x20#define RTP 0x21#define WTA 0x22#define RTA 0x23#define RRP 0x24//==========================收发数据缓冲区========= ============================#define TxRxBuf_Len 32unsigned char TxRxBuf[TxRxBuf_Len];//==========================NRF905:10寄存器配置================================unsigned char RFConf[11]={ WC, //SPI写操作命令 0x4c, //CH_NO,配置频段在430MHZ 0x0C, //输出功率为10db,不重发,节电为正常模式 0x44, //地址宽度设置,为4字节 0x20,0x20, //接收发送有效数据长度为32字节 0xCC,0xCC,0xCC,0xCC, //接收地址 0x58, //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振};char TxAddress[4]={0xcc,0xcc,0xcc,0xcc};char DATA_BUF;/*****************************************************************************系统初始化******************************************************************************/void InitSys(){ unsigned int iq0; _DINT(); BCSCTL1 &=~XT2OFF; do { IFG1 &= ~OFIFG;// 清除振荡器失效标志 for (iq0 = 0xFF; iq0 > 0; iq0--);// 延时,等待XT2起振 } while ((IFG1 & OFIFG) != 0);// 判断XT2是否起振 BCSCTL2 =SELM1+SELS; //MCLK,SMCLK时钟为XT2}//==============================================================================//===========================初始化nRF905=======================================void nRF905_IO_set(void){ P6DIR |= 0x07; P6DIR &= 0x8F; P6SEL&=0x84; P2DIR |= 0x07; P2DIR &= 0x8F; P2SEL&=0x84; P5DIR |= 0xC0; P5DIR |= 0xFB; P5SEL&=0xF0; CSN_1; // Spi disableSCK_0; // Spi clock line init lowPWR_1; // nRF905 power onTRX_CE_0;// Set nRF905 in standby modeTXEN_0;// set radio in Rx mode}//==============================================================================void IO_set(void){ //P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换}//==========================延时================================================void Delay(uchar n){uint i;while(n--)for(i=0;i<80;i++);}//=========================NRF905 SPI读函数(IO模拟SPI时序)==================unsigned char SpiRead(void){unsigned char i;for (i=0;i<8;i++){DATA_BUF=DATA_BUF<<1;SCK_1;if ((P5IN&0x04))//读取最高位,保存至最末尾,通过左移位完成整个字节{DATA_BUF|=0x01;}else{DATA_BUF&=~(0x01);}SCK_0; } return DATA_BUF;}//=========================NRF905 SPI读写函数(IO模拟SPI时序)==================void SpiWrite(unsigned char send){unsigned char i;DATA_BUF=send;for (i=0;i<8;i++){if (((DATA_BUF&0x80) != 0))//总是发送最高位 { MOSI_1; }else { MOSI_0; }SCK_1;DATA_BUF=DATA_BUF<<1;SCK_0;}}//==================================初始化NRF905================================void Config905(void){uchar i;CSN_0;// Spi enable for write a spi commandfor (i=0;i<11;i++)// Write configration words 写放配置字{ SpiWrite(RFConf);}CSN_1;//关闭SPI}//=========================NRF905装载地址+数据打包+数据发送=====================void TxPacket(void){uchar i;CSN_0;SpiWrite(WTP);// 待发数据装载命令for (i=0;i<32;i++){ SpiWrite(TxRxBuf);}CSN_1; // 关闭SPIDelay(1);CSN_0;// 打开SPISpiWrite(WTA);// 写入地址要和接收方地址一样for (i=0;i<4;i++)// 4字节地址{ SpiWrite(TxAddress);}CSN_1;//关闭SPITRX_CE_1;// Set TRX_CE high,start Tx data transmissionDelay(1);// while (DR!=1);TRX_CE_0;// Set TRX_CE low}//==================================发送模式初始化-=============================void SetTxMode(void){TRX_CE_0;TXEN_1;Delay(1); // Delay for mode change(>=650us)}//==================================数据发送===================================void TX(void){ SetTxMode();TxPacket();}//=========DR检测,当 收到数据后DR置1,当把数据读出来后DR清0=====================unsigned char CheckDR(void)//检查是否有新数据传入 Data Ready{if ((P2IN&0x40)){return 1;}else{return 0;}}//==============================================================================void SetRxMode(void){TXEN_0;TRX_CE_1;Delay(1); // delay for mode change(>=650us)}//=================================数据接收=====================================void RxPacket(void){ char i; Delay(1); Delay(100); TRX_CE_0; CSN_0;// SPI使能(Spi enable for write a spi command) Delay(1); SpiWrite(RRP); // 读SPI数据命令(Read payload command)for (i = 0 ;i < 32 ;i++) { TxRxBuf=SpiRead();// Read data and save to buffer } CSN_1; Delay(10); TRX_CE_1;}//==========================NRF905数据接收流程================================void RX(void){ SetRxMode();// Set nRF905 in Rx mode while (CheckDR()==0); Delay(10); RxPacket();// Recive data by nRF905 Delay(10);}//======================?????==============================================void init_uart0(void) {//====================串口工作模式设置======================================== U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0 U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当 CHAR=1时为8位数据 //不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置======================================== U0TCTL=0x00; //U0TCTL包含串口0发送功能操作 U0TCTL +=SSEL0; //波特率发生器选择ACLK //#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。。。。+M0)/8) UBR0_0=0x03; //UBR0_0为串口0波特率整数部分低地址 UBR1_0=0x00; //UBR1_0为串口0波特率整数部分高地址 UMCTL_0=0x4A; //UBR1_0为串口0波特率小数部分高地址 //===================串口收发使能控制========================================= ME1 |= UTXE0; //串口0发送功能使能 ME1 |= URXE0; //串口0接收功能使能 //===================串口中断使能控制========================================= IE1 |= URXIE0; //串口0接收中断使能// IE1 |= UTXIE0; //串口0发送中断使能//===================端口第二功能使能========================================= P3SEL |=BIT4; //设置P3。4为UART0 的TXD P3SEL |=BIT5; //设置P3。5为UART0 的RXD P3DIR |=BIT4; //设置P3。4为输出 }//==============================================================================void R_S_Byte(char R_Byte){ while((IFG1&UTXIFG0)==0);//???????? TXBUF0=R_Byte;}//========================延时约5ms=============================================void Delay5ms(void){ uint i=40000; while (i != 0) { i--; }}//==================================主函数=====================================void main(void){ char i; WDTCTL = WDTPW + WDTHOLD; //禁止看门狗 InitSys(); nRF905_IO_set(); IO_set(); init_uart0(); //串口初始化 Config905(); // NRF905初始化 while(1) { RX(); //P2OUT=P6OUT; if((TxRxBuf[0]==0x01)&&(TxRxBuf[31]==0x32))//校验 { for(i=0;i<32;i++) { R_S_Byte(TxRxBuf); Delay(100); } } }}
0
|
3个回答
|
|
|