📄 nrf905.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 + -