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

📄 nrf905.c

📁 ARM程序
💻 C
字号:
/*******************************************************************************************************
* 文件名:main.c
* 功  能:开发板main()函数例子
* 作  者:POWER
* 日  期:2006年9月28号
* 斯凯科技主页:www.armsky.net
* 斯凯科技论坛:www.armsky.net/bbs
********************************************************************************************************/
#include "config.h"


//nRF905配置测试程序主程序

/* LPC2131控制nRF905无线芯片程序,使用SPI配置并通信
 版本:1.0*/
//#include "config.h"
#include "nrf905.h"
#include <stdio.h>

#define  MASTER  //编译控制是主机还是从机
#define  UART_BPS0  9600 // 通讯波特率2400
#define  BufferSize  32
uint8  Buffer1[BufferSize];  //U0Rx,U1Tx
uint8  Buffer2[BufferSize];  //U0Tx,U1Rx
 
const uint32 LED6 = (1 << 23); // P1.18控制LED1,低电平点亮 
const uint32 LED7 = (1 << 3); // P1.18控制LED1,低电平点亮 
const uint32 LED8 = (1 << 2);  // P1.18控制LED1,低电平点亮 
volatile uint8 rcv_new; 
uint8 buffer1Start, buffer1End; 
uint8 *buffer1head, *buffer1tail;
uint8 *buffer2Start, *buffer2End;
uint8 *buffer2head, *buffer2tail;
uint8 OverFlowFlag1;
uint8 OverFlowFlag2;
uint16  uart0lock,spi0lock;
uint8  bufferlock;
uint32 stanum,endnum ;
uint32 loopcount,endtimeout;
uint8  ch,ch1;
uint8 text[]="STW";
uint8 textend[]="QUI";
uint8 flagtext[]="send data123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF...";
uint8 uart0txstatus,uart0rxstatus;
uint8 spi0txstatus,spi0rxstatus;
uint8 rfstatus,rftxstatus;
uint8 buf[3],bufcount;
void WDT_INIT(void); 
void WDT_CLEAR(void);
void __irq IRQ_UART0(void);
void UART_Init (void);
void UART0_SendByte (uint8 data);
void UART0_SendBuf ( char *str);
void UART0_SendStr ( char *str); 
void MSPI_Init(void);
uint8 nrf905_SpiRW(uint8 data);
void nrf905_SPISendStr (uint8 *str);  
void nrf905_SpiTest(void);
void Config905(void);
void nrf905_ReadData(void);
void nrf905_SendData(void);
void Receiver(void);
void Transmitter(void);
void nrf905_Off(void);
void nrf905_StandBy(void);
void nrf905_TxOn(void);
void nrf905_RxOn(void);

void WDT_INIT(void)
{
 	while(( WDMOD & 0x04 ) == 0x04)             // 判断看门狗超时标志 
    WDMOD = 0x00; 
 
 	/* 初始化看门狗 */
 	WDTC  = 0xffffff;            // 设置看门狗定时器参数
 	WDMOD = 0x01;              // 看门狗中断使能
 	WDFEED = 0xAA;            // 第一次喂狗启动WDT
 	WDFEED = 0x55; 
}
void WDT_CLEAR(void)
{
 	IRQDisable();     //喂狗之前关中断
 	WDFEED = 0xAA;    //第一次喂狗启动WDT
 	WDFEED = 0x55; 
 	IRQEnable();     //喂狗之后IRQ中断使能
}
void __irq IRQ_UART0(void)                    //串口0接收中断
{  
   	//uint8 i;
   	if((U0IIR&0x0f)==0x04)
    	rcv_new = 1;
 	//for(i=0;i<BufferSize;i++)
 	//{
    //	Buffer1[i]=U0RBR;
   	//}
   	
   	Buffer1[buffer1Start++]=U0RBR;
   	if(buffer1Start==BufferSize)
   	  buffer1Start=0;
    VICVectAddr = 0x00;    
}
void UART_Init (void)
{
 	uint16 Fdiv;
 
 	PINSEL0 = (PINSEL0 & 0xFFFfFFF0) | 0x05; // 设置I/O连接到UART
 
 	U0LCR = 0x83;      // DLAB=1,允许设置波特率
 
 	Fdiv  = (Fpclk / 16) / UART_BPS0; // 设置U0波特率
 	U0DLM = Fdiv / 256;
 	U0DLL = Fdiv % 256;
 	U0LCR = 0x03;
   
 	/* 使能UART0中断 */
 	VICIntSelect = 0x00000000;   // 设置所有的通道为IRQ中断
 	VICVectCntl0 = 0x20 | 0x06;      // UART0分配到IRQ slot0,即最高优先级
 	VICVectAddr0 = (uint32)IRQ_UART0; // 设置UART0向量地址
 	VICIntEnable = 1 << 0x06;   // 使能UART0中断
}
void UART0_SendByte (uint8 data)          //串口0发送数据
{
 	U0THR = data;
 
 	while ((U0LSR & 0x40) == 0); // 等待数据发送完毕
}
void UART0_SendBuf ( char *str)          //串口0发送字符串
{
 	uint8 i;
 	for(i=0;i<BufferSize;i++)
      UART0_SendByte(Buffer1[i]);   // 发送数据
 	while((U0LSR&0x20) == 0);
}

void UART0_SendStr ( char *str)          //串口0发送字符串
{
 	uint8 i;
 	//for(i=0;i<BufferSize;i++)
 	while(str[i]!=0){
 	   UART0_SendByte(str[i]);   // 发送数据
 	   i++;
 	 }
 	while((U0LSR&0x20) == 0);
}
//SPI中断服务函数
void __irq SPI_IRQ(void)
{
 	uint32 tmp;
 
 	volatile uint8  RcvData;    // 接收到的数据
 	volatile uint8  RcvFlag;    // 接收到新数据标志
   	tmp = S0PSR;       		 // SPI读取数据寄存器之前,必须先读SPSR寄存器,清零SPIF位。
   	RcvData = S0PDR;          // 接收数据
   	RcvFlag = 0x01;      	 // 接收到新数据
   	S0PINT  = 0x01;           // 清除标志位
   
/* if(spi0txstatus==0)   	 //没有收到有效帧头
 {
     if(RcvData==text[stanum])
         stanum++;
     else 
         stanum = 0;
   
     if(stanum>=3)
     {
      stanum=0;
       spi0txstatus = 0;   //清除有效帧尾,
      spi0txstatus = 1;    //收到了有效帧头
      spi0lock = 0;
     }
    }
    else        		  //拥有有效帧头标志
    {
     spi0lock++;
     if(spi0lock>=1000)
     {
      spi0txstatus =0;
      spi0txstatus =1;
      uart0lock = 0;
     }
     else
     {
      AddByteToBuffer2(&ch);   //加入FIFO
      if(OverFlowFlag2)    		//如果FIFO溢出
      {
       Buffer2Init();
      } 
     
    if(ch==textend[endnum])    //判断接收完成
       endnum++;
    else 
         endnum = 0;
     if(endnum >= 3)
      {
        endnum=0;
        spi0txstatus = 1;   //收到有效帧尾,
        spi0txstatus =0;   	//清除有效帧头
        spi0lock =0;
       }
      }
    }
    */ 
    VICVectAddr = 0x00;
} 
void  MSPI_Init(void)
{  
 	PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ;// 设置管脚连接SPI
 	//IO0DIR |= 0xd0;
  	S0PCCR  = 0x52;           // 设置SPI时钟分频
  	S0PCR   = (0 << 3) |    	// CPHA = 0, 数据在SCK 的第一个时钟沿采样
      (0 << 4) |    		// CPOL = 0, SCK 为高有效
      (1 << 5) |    		// MSTR = 1, SPI 处于主模式
      (0 << 6) |    		// LSBF = 0, SPI 数据传输MSB (位7)在先
      (0 << 7);     		// SPIE = 1, SPI 中断使能
  
  	VICIntSelect = 0x00000000;            // 设置所有中断为IRQ
    VICVectCntl0 = (0x20 | 10);           // SPI中断为最高优先级
    VICVectAddr0 = (int32)SPI_IRQ;          // 设置中断向量地址
    VICIntEnable = (1 << 10);             // 允许SPI中断
    delay(10);
}

 //SPI读写一体化函数
uint8 nrf905_SpiRW(uint8 data) 
{
    uint32 temp=0;
 	S0PINT = 0x01; // Clear SPI interrupt
   	S0PDR = data;
   	while( 0 == (S0PSR & 0x80)){
   	//   if(++temp==256)
   	//       break;
   	}
   	temp=S0PDR;
  	return S0PDR;
}
void nrf905_SPISendStr (uint8 *str)          //SPI0发送字符串
{
	while (1)
 	{
  	if (*str == '\0') 
  		break;  // 遇到结束符,退出
  	nrf905_SpiRW(*str++) ;   	// 发送数据
 	}
}
//测试:通过读配置,判断SPI操作是否正确
void nrf905_SpiTest(void)
{
 	uint8 i;
   	IO0CLR |= nRF905_CSN;                  
   	nrf905_SpiRW(RC);  //读配置
   	for (i=0;i<10;i++)
  	{ 
     Buffer2[i]= nrf905_SpiRW(0);//read from nrf905
     UART0_SendByte(Buffer2[i]);
   }
   IO0SET |= nRF905_CSN;  
}  
//配置nRF905
void Config905(void) 
{
 	nrf905_StandBy();
    IO0CLR |= nRF905_CSN;        // Spi enable for write a spi command
    delay(1); 
	nrf905_SpiRW(WC);                     // Write config command
 	nrf905_SpiRW(CH_NO_BYTE);                       //中心频率低8位
 	nrf905_SpiRW(PA_PWR_10dBm | HFREQ_PLL_433MHz);  //发射+10dBm,发射频率433MHz,中心频率第9位=0
 	nrf905_SpiRW(TX_AFW_4BYTE | RX_AFW_4BYTE);      //接收地址宽度4字节,发送地址宽度4字节
 	nrf905_SpiRW(RX_PW_32BYTE);                     //接收数据宽度32字节
 	nrf905_SpiRW(TX_PW_32BYTE);                     //发送数据宽度32字节
 	nrf905_SpiRW(RX_ADDRESS_0);                     //接收有效地址第1字节
 	nrf905_SpiRW(RX_ADDRESS_1);                     //接收有效地址第2字节
 	nrf905_SpiRW(RX_ADDRESS_2);                     //接收有效地址第3字节
 	nrf905_SpiRW(RX_ADDRESS_3);
 	//nrf905_SpiRW(0x09);                      //接收有效地址第4字节
 	nrf905_SpiRW(CRC16_EN | XOF_16MHz|UP_CLK_EN_4MHz);             //CRC16模式使能,晶体振荡器频率12MHz
 
 	delay(1);
 	IO0SET |= nRF905_CSN;                           // Disable Spi
 
 	nrf905_SpiTest();
 	nrf905_RxOn();
  
 	IO0CLR |= LED7;
 	delay(40);
 	IO0SET |= LED7;
 	delay(40);
  	UART0_SendStr("Config905 OK");
}
 

//读出接收到的数据
void nrf905_ReadData(void)
{
 	uint8 i;
 	IO0CLR |= nRF905_CSN;                    
 	nrf905_SpiRW(RRP);  //读RxPayload 
   	for (i=0;i<BufferSize;i++)
  	{ 
     Buffer2[i]=nrf905_SpiRW(0);//read...
   	}
   	IO0SET |= nRF905_CSN;   
}
void nrf905_SendData(void)
{  
 	uint8 i;
 	nrf905_TxOn();
    IO0CLR |= nRF905_CSN;               
   	nrf905_SpiRW(WTA);  //写Tx地址  
  	nrf905_SpiRW(TX_ADDRESS_0);
  	nrf905_SpiRW(TX_ADDRESS_1);
   	nrf905_SpiRW(TX_ADDRESS_2);
   	nrf905_SpiRW(TX_ADDRESS_3);   
   	IO0SET |= nRF905_CSN;
   	delay(1);
   
   	IO0CLR |= nRF905_CSN;                  
   	nrf905_SpiRW(WTP);  //写TxPayload 
   	nrf905_SPISendStr(flagtext);
   	for (i=0;i<BufferSize;i++)
   	{ 
     nrf905_SpiRW(Buffer1[i]);
   	}  
   	IO0SET |= nRF905_CSN; 
}
void Receiver(void)
{
 	uint8 i;
 	//if ((IO0PIN&nRF905_AM))==0) return;//一般先AM=1指示地址匹配对
   
 	if ((IO0PIN&nRF905_DR)==0) return;//DR=1时表示数据接收对而且Crc正确
   
    //已经接收到数据
    nrf905_ReadData();//读出...
   
    for (i=0;i<32;i++)
    {
     if (Buffer2[i]!=(i+i)) 
        return;
    }
   
    //数据接收正确...灯指示
    IO0CLR = LED8;
    delay(50);
    IO0SET = LED8;
   
    //从机回送数据包,这样双方都能指示是否收到有效数据包
    #ifndef MASTER
      Transmitter();
    #endif
}
void Transmitter(void)
{
 	uint8 i;
    for (i=0;i<32;i++) 
    Buffer2[i]=i+i;
    nrf905_SendData();//发送数据
    i=0;
    while((IO0PIN&nRF905_DR)== 0){
    	//if(++i==0)
     	//	break;
    }
    delay(1);
    nrf905_RxOn();//重新回到接收状态
}
 
int main(void)
{
 	//WDT_INIT();                   //看门狗初始化
 	//PINSEL2 = PINSEL2&(~0x08);    // P1[25:16]连接GPIO
 	//IO0DIR |= 0x397<<16;		   //p1.16 p1.17 p1.18 p1.20 p1.23 p1.24 p1.25为输出
 	uint8 tmp=0;
 	

 	PINSEL0=0;
 	IO0DIR=~(nRF905_CD| nRF905_AM| nRF905_DR |nRF905_MISO) ;
 	while(tmp++<3){
 		IOCLR |= LED8;
 		delay(50);
 		IOSET |= LED8;
		delay(50);
	}
 
  	IRQEnable();            //使能IRQ中断
 	MSPI_Init();
 	UART_Init ();           //系统初始化
 	U0IER = 0x01;           //允许串口0接收中断
 	Config905();
  	while(1){
  		IO0CLR |= LED8;
 		delay(40);
 		IO0SET |= LED8;
  		//WDT_CLEAR();    //看门狗清零
  		delay(40);
  		#ifdef MASTER
  			Transmitter();
  		#endif
		//Receiver();
   }
   return 0;
}













⌨️ 快捷键说明

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