⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrf905trx.c

📁 430单片机的NRF905的驱动 调试已经通过 保证可以使用 msp430f147
💻 C
字号:
#include <msp430x14x.h>
#include "BaseType.h"
#include <string.h>
#include <ctype.h>

#define	WaitKeyDw   100
#define WaitKeyUp   101
#define KeyDwTimes  30

#define WRC 0x00 //W_RF_CONFIG
#define RRC 0x10 //R_RF_CONFIG
#define WTP 0x20 //W_TX_PAYLOAD
#define RTP 0x21 //R_TX_PAYLOAD
#define WTA 0x22 //W_TX_ADDRESS
#define RTA 0x23 //R_TX_ADDRESS
#define RRP 0x24 //R_RX_PAYLOAD
#define RAD 0x40 //R_ADC_DATA 
#define WAC 0x44 //W_ADC_CONFIG
#define RAC 0x46 //R_ADC_CONFIG
#define WTU 0x50 //W_TEST_UNLOCK (use with data A5)
#define WTR 0x52 //W_TEST_REGISTER
#define RTR 0x53 //R_TEST_REGISTER
#define CC 0x80 //CHANNEL_CONFIG
#define SAV 0xC0 //START_ADC_CONV
#define HFREQ 1 // 0=433MHz, 1=868/915MHz 

#define POWER 3 // 0=min power...3 = max power

#define RFTxLen 16 //射频发送绶冲区长度
#define RFRxLen 16 //射频接收绶冲区长度

#define INT8U unsigned char
#define INT16U unsigned int
#define _nop_() _NOP()

INT8U Nrf9e5Config[10] = { 
0x6B, //频道设置

0x0C, //自动重发关,发送节电模式关,输出功率10dB,433.1MHZ

0x44, //收发地址都为4字节

RFRxLen, //接收数据长度,10字节

RFTxLen, //发送数据长度,10字节

0xE7,
0xE7,
0xE7,
0xE7, //地址

0xDF //16位校验,CRC开,16M晶振,外部时钟使能500KHZ输出
}; 


INT8U RFRxBuf[RFRxLen+2]; //射频接收缓冲区
INT8U RFTxBuf[RFTxLen+2]; //射频接收缓冲区

U32	CntTmp;

void PORT_Init(void)
{
	P2SEL &= ~(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0);
	P2DIR |= (BIT3|BIT2|BIT1); 
                //p2.1--PWR_UP,OUTPUT
                //p2.2--TRX_CE,OUTPUT
                //p2.3--TX_EN, OUTPUT
	P2DIR &= ~(BIT5|BIT4|BIT0);
	              //p2.0--uCLK, INPUT
                //p2.4--KEY1, INPUT
                //p2.5--KEY2, INPUT
                
	P1SEL &= ~(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1);
	P1DIR &= ~(BIT7|BIT6|BIT5);
                //p1.7--CD, INPUT
                //p1.6--AM, INPUT
                //p1.5--DR, INPUT
  P1DIR |= (BIT4|BIT3|BIT2|BIT1);//LED4--LED1, OUTPUT        
  P1OUT |= (BIT4|BIT3|BIT2|BIT1);       
}

void SPI_Init(void)
{
	P3SEL |= (BIT3|BIT2|BIT1);
	P3SEL &= ~BIT0;
	// P3.1 P3.2 P3.3作为SPI的管脚
	// p3.0--CE905,905片选, I/O
	// p3.1--MOSI,
	// p3.2--MISO,
	// P3.3--SCK905,

	P3DIR |= (BIT3|BIT1|BIT0);
	//P3.3作为输出
	//P3.1作为输出
	//P3.0作为输出

	P3OUT |= (BIT3|BIT1|BIT0); 
	//P3.0输出高电平
	//P3.1输出高电平
	//P3.3输出高电平

	// 以下设置SPI口的参数
	UCTL0 |= SWRST; //为设置串口作准备
	UCTL0 |= (CHAR + SYNC + MM);  //数据为8比特,选择SPI模式,单片机为主机模式
	UTCTL0 &= ~(CKPH|CKPL);	//SPI时钟设置
	UTCTL0 |= (SSEL1|STC); // 时钟源为SMCLK,选择3线模式

	UBR00 = 0x02; //波特率为ACLK/2
	UBR10 = 0x00; //波特率为ACLK/2
	UMCTL0 = 0x00; //调整寄存器
	ME1 |= USPIE0; //SPI0模块允许
	IE1 |= URXIE0; //接收中断允许
	IE1 |= UTXIE0; //发送中断允许
	UCTL0 &= ~SWRST; // Initalise USART state machine
}

void Init_CLK(void)
{
unsigned int i;
	BCSCTL1 = 0X00;//将寄存器的内容清零
	//XT2震荡器开启
	//LFTX1工作在低频模式
	//ACLK的分频因子为1
	do 
	{
		IFG1 &= ~OFIFG; // 清除OSCFault标志
		for (i = 0x20; i > 0; i--); 
	}
	while ((IFG1 & OFIFG) == OFIFG); // 如果 OSCFault == 1

	BCSCTL2 = 0x00; //将寄存器的内容清零
	BCSCTL2 |=SELM_2; //MCLK select lftx
	BCSCTL2 |= SELS; //SMCLK--DCOCLK
}

void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
unsigned long nCount;
int i;
unsigned long j;
	nCount = 2667;
	for(i = nValue;i > 0;i--)
	{
		for(j = nCount;j > 0;j--);
	}
	return;
}

void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
int nCount;
int i;
int j;
	nCount = 3;
	for(i = nValue;i > 0;i--)
	{
		for(j = nCount;j > 0;j--);
	}
	return;
}

void delay(INT16U s)
{
	INT16U i;
	for(i=0; i<s; i++);
}

void SpiWriteByte(INT8U dat)
{
//	while ((IFG1 & UTXIFG0)==0x0);
	U0TXBUF = dat;
	while ((U0TCTL & TXEPT) == 0x0); 
}

INT8U SpiReadByte(void)
{
//INT8U temp;
	U0TXBUF = 0;
	while ((U0TCTL & TXEPT) == 0x0); 
//	while((IFG1 & URXIFG0)==0);
//	temp=U0RXBUF;
//	return temp; 
	return U0RXBUF;
}

void INIT_905(void)
{ 
INT8U i;

	TRX_CE_0; //TRX_CE = 0;
	TX_EN_0; //TX_EN = 0;

	CE905_0; //ce905=0

	SpiWriteByte(WRC);
	for(i=0; i<10; i++)
	{
		SpiWriteByte(Nrf9e5Config[i]); 
	}
//	while ((IFG1 & UTXIFG0)==0x0);
	CE905_1;//CE_905 = 1
}

void TransmitBytes(void)
{
INT8U i; 
	TX_EN_1;	//TX_EN=1
	TRX_CE_0;	//TRX_CE = 0
	delay(1000);
	CE905_0; 		//ce905=0
	SpiWriteByte(WTA);
	SpiWriteByte(0xE7);
	SpiWriteByte(0xE7);
	SpiWriteByte(0xE7);
	SpiWriteByte(0xE7);
//	while ((IFG1 & UTXIFG0)==0x0);
	CE905_1;		//CE_905 = 1

	delay(1);

	CE905_0; 		//ce905=0
	SpiWriteByte(WTP);
	for(i=0; i<RFTxLen; i++)
	{
		SpiWriteByte(RFTxBuf[i]);
	}
//	while ((IFG1 & UTXIFG0)==0x0);
	CE905_1;		//CE_905 = 1

	delay(1);
	
	TRX_CE_1;	//TRX_CE=1
	CntTmp = 0;
	while(DR905 == 0)//; //DR=0
	{
		CntTmp ++;
	}
	
	TRX_CE_0;	//TRX_CE = 0
	TX_EN_0;	//TX_EN=0
}

INT8U Recepacket(void)
{
INT8U i;

	TX_EN_0; 	//TX_EN=0
	TRX_CE_1; //TRX_CE=1
	while(CD905 == 0);

	TRX_CE_0; //TRX_CE=0
	CE905_0; 		//ce905=0
	SpiWriteByte(RRP);
	for(i=0; i<RFRxLen; i++)
	{
		RFRxBuf[i] = SpiReadByte(); //接收数据
	} 
	while(DR905) //DR=1
	{
		SpiReadByte();
	}
	CE905_1; 		//ce905=1

	return 1;
}

void ChangeMode(U8 mode)
{
	switch(mode)
	{
		case PowerDown:
			PD905;		/* 配置为掉电模式 */
			TX_EN_0;
			TRX_CE_0;
			break;

		case Standby:
			TRX_CE_0;
			TX_EN_0;
			PU905;
			break;
			
		case RXMode:
			PU905;
//			delay(2);
			TX_EN_0;
			_NOP();
			_NOP();
			TRX_CE_1;
			break;

		case TXMode:
			TX_EN_1;
			PU905;
			TRX_CE_0;
			break;

		case TXData:
			TRX_CE_1;
			delay(2);	
			TRX_CE_0;		/* ??  Make a 20us Pulse as nRF905 Datasheet */
			break;
	}
}

void RF905_Read(U8 RFcmd,U8 *RFdata)
{
U8 i,len;
	switch(RFcmd)
	{
		case RTA:		len=4;        break;
		case RRC:		len=16;       break;
		case RTP:
		case RRP:		len=RFRxLen;  break;
		default:		len=0;
	}

	CE905_0;		/* Spi enable for write a spi command */
	SpiWriteByte(RFcmd);
	for(i=0;i<len;i++) RFdata[i]=SpiReadByte();
	CE905_1;
}

void RF905_Write(U8 RFcmd,U8 *RFdata)
{		
U8 i,len;
	switch(RFcmd)
	{
		case WTA:		len = 4;        break;
		case WRC:		len = 16;       break;
		case WTP:		len = RFRxLen;  break;
		default:		len = 0;
	}

	CE905_0;		/* Spi enable for write a spi command */
	SpiWriteByte(RFcmd);
	for(i=0;i<len;i++) SpiWriteByte(RFdata[i]);	/* len Bytes Data */
	CE905_1;                        // Disable Spi
}		

U32 msec_cont = 0;//10毫秒钟基数
U8  msec=0;//10毫秒钟
U8	sec=0;//秒钟
U8	min=0;//分钟
U8	old_min;

U8	K1DwCnt, K2DwCnt;
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  _BIC_SR_IRQ(LPM3_bits);							// Clear LPM3 bits from 0(SR)

	msec ++;
	msec_cont ++;

	if(KEY1)
	{
		if((++K1DwCnt) > KeyDwTimes){K1DwCnt = KeyDwTimes;}
	}
	else
	{
		if(K1DwCnt >= 3)
			K1DwCnt -= 3;
		else
			K1DwCnt = 0; 
	}
	
	if(KEY2)
	{
		if((++K2DwCnt) > KeyDwTimes){K2DwCnt = KeyDwTimes;}
	}
	else
	{
		if(K2DwCnt >= 3)
			K2DwCnt -= 3;
		else
			K2DwCnt = 0; 
	}
		
	if((msec == 100) | (msec == 50))
	{ //100分频,就是1秒一次
		if(msec == 100) msec = 0;
		sec ++;
/*
		if(Blink)
		{//需要闪烁
			BlkPtr = 1;
			for(LLi = 0; LLi < 4; LLi ++)
			{
				if((sec & 0x01) && (Blink & BlkPtr))
					LLTmp = 0xFF;
				else
					LLTmp = DisBuff[LLi];
				BlkPtr <<= 1;
				
				for(LLj = 0; LLj < 8; LLj ++)
				{
					if(LLTmp & 0x80)
					{
						LCD_DI_1;
					}
					else
					{
						LCD_DI_0;
					}
					LCD_CLK_1;
					LCD_CLK_0;
					LLTmp <<= 1;
				}
			}
		}
*/
		if(sec==60)
		{
			sec=0;//每分钟一次
			min++;
			if(min==60) min=0;
		}
	}
}

U8	K1Sta = WaitKeyDw;
U8	K2Sta = WaitKeyDw;

void main(void)
{
//INT8U i, tmp;

//	Init_CLK();
	WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
	_DINT();//关闭中断
	PORT_Init();
	PD905;
	SPI_Init();
	INIT_905();
	//P1OUT ^= 0x01; // 点亮LED
        RF905_Read(RRC,RFRxBuf);
	RFTxBuf[0] = 'a';
	RFTxBuf[1] = 'b';
	RFTxBuf[2] = 'c';
	RFTxBuf[3] = 'd';
	RFTxBuf[4] = 'e';
	RFTxBuf[5] = 'f'; 
	RFTxBuf[6] = 'g';
	RFTxBuf[7] = 'h';
	RFTxBuf[8] = 'i';
	RFTxBuf[9] = '\0';
	
  BCSCTL1 |= DIVA0 + DIVA1;							// ACLK = 32768/8
	//用Timer 定时5分钟
  TACTL &= ~(MC1 + MC0 + ID0 + ID1);  	//Stop TA, 不分频
  TACTL = TASSEL0 + TACLR;							// ACLK, clear TAR
  CCTL0 = CCIE;                         // CCR0 interrupt enabled
  CCR0 = 41;														// ≈10ms
  TACTL |= MC0;  // Start Timer_a in upmode to CCR0
  LED3_ON;	
	_EINT();//打开中断
		
/*	
	CE905_0; 		//ce905=0
	SpiWriteByte(RRC);
	for(i=0; i<RFRxLen; i++)
	{
		RFRxBuf[i] = SpiReadByte();
	}
	CE905_1;		//CE_905 = 1	
*/

	ChangeMode(RXMode);			/**/
	K1Sta = K2Sta = WaitKeyDw;
	
	while(1)
	{
		if(DR905)
		{
			RF905_Read(RRP, RFRxBuf);
			switch(RFRxBuf[0])
			{
				case 0x01:
					LED1_BLK;
					break;
				
				case 0x02:
					LED2_BLK;
					break;
			}
		}
		switch(K1Sta)
		{
			case WaitKeyDw:
				if(K1DwCnt > (KeyDwTimes -1))
				{
		 			ChangeMode(TXMode);	
					K1Sta = WaitKeyUp;
					delay(3100);
					RFTxBuf[0] = 0x01;
					RF905_Write(WTP, RFTxBuf);	/**/
				 	ChangeMode(TXData);	
					delay(650);			/* ensure nRF905 have began TX */
					ChangeMode(RXMode);			/**/
				}
				break;
		
			case WaitKeyUp:
				if(K1DwCnt == 0)
					K1Sta = WaitKeyDw;
				break;
		}

		switch(K2Sta)
		{
			case WaitKeyDw:
				if(K2DwCnt > (KeyDwTimes -1))
				{
		 			ChangeMode(TXMode);	
					K2Sta = WaitKeyUp;
					delay(3100);
					RFTxBuf[0] = 0x02;
					RF905_Write(WTP, RFTxBuf);	/**/
				 	ChangeMode(TXData);	
					delay(650);			/* ensure nRF905 have began TX */
					ChangeMode(RXMode);			/**/
				}
				break;
		
			case WaitKeyUp:
				if(K2DwCnt == 0)
					K2Sta = WaitKeyDw;
				break;
		}
	
//	TransmitBytes();	//发送缓冲区里的数据
//	LED1_ON;
//	delay(20000);
//	LED1_OFF;
//	delay(20000);
//	_NOP();
}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -