📄 main.c
字号:
#include <string.h>
#include <reg52.h>
#include <intrins.h>
#define INT8U unsigned char
#define INT16U unsigned int
#define FOSC 11059200
#define BAUD 9600
#define TIMER1 0XFD //256-(110592/(12*32*96))
#define TIMER0H (65535-3*FOSC/12/1000)/256
#define TIMER0L (65535-3*FOSC/12/1000)%256 //定时3MSVR
//----------------------------------------------------------------------------------------------------------
//内部寄存器定义
//----------------------------------------------------------------------------------------------------------
//sfr P4 = 0xc0;
//sfr ADC_CONTR = 0xC5;
//sfr AUXR = 0x8E;
//sfr ADC_DATA = 0xC6;
//sfr P1_ADC_EN = 0x97;
//定义I/O口
sbit POW_UP = P1^0;
sbit CE = P1^1;
//sbit DR2 = P3^3;
//sbit SCK2 = P3^2;
sbit MOSI = P1^2; //DATA1
sbit MISO = P1^3; //DR1
sbit SCK = P1^5; //clk1
//sbit DOUT2 = P1^5;
sbit CS = P1^4;
sbit DR1 = P1^2;
sbit LED1 = P3^4;
sbit LED2 = P3^5;
/********************* I/O define end*****************************************************/
#define FRESELE 0x28 //频道选择
#define DATANUM 4 //有效数据位数
#define time0h (65535-3000)/256
#define time0l (65535-3000)%256 //定时3MS
INT8U CofigBuf[15]=
{
0x00, //接收频道二有效数据长度
40, //接收频道一有效数据长度
0x00,0x00,0x00,0x00,0x00, //接收频道二地址
0x00,0xcd,0xef,0x12,0xaa, //接收频道一地址
0x83, //32位地址,16位CRC,使能CRC
//bit7~2:ADDR_W,最大40位
//bit1:CRC_L
//Logic 0: 8 bit CRC
//Logic 1: 16 bit CRC
//BIT0:CRC_EN
//Logic 0: On-chip CRC generation/checking disabled
//Logic 1: On-chip CRC generation/checking enabled
0x4f, //ShockBurst模式,250 kbps,16M晶振,0dBm最大功率
//Bit 15:RX2_EN
//Logic 0: One channel receive
//Logic 1: Two channels receive
//Bit 14:
//Communication Mode:
//Logic 0: nRF2401 operates in direct mode.
//Logic 1: nRF2401 operates in ShockBurst. mode
//Bit 13:
//RF Data Rate:
//Logic 0: 250 kbps
//Logic 1: 1 Mbps
//Bit 12-10:Selects the nRF2401 crystal frequency to be used:
// D12 D11 D10 Crystal Frequency [MHz]
// 0 0 0 4
// 0 0 1 8
// 0 1 0 12
// 0 1 1 16
// 1 0 0 20
//Bit 9-8:RF_PWR: Sets nRF2401 RF output power in transmit mode:
// D9 D8 P [dBm]
// 0 0 -20
// 0 1 -10
// 1 0 -5
// 1 1 0
0x50 //2400+4*1=2404MHZ=2.404G,发送模式
//Bit 7 – 1:RF_CH#: Sets the frequency channel the nRF2401 operates on.
//Channelrf = 2400MHZ + RF_CH# * 1.0MHZ
//Bit 0:Set active mode:
//Logic 0: transmit mode
//Logic 1: receive mode
};
INT8U AddrCofig[4]={0xcd, 0xef, 0x12, 0xaa}; //地址
INT8U TxBuf[8]={0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}; //发送绶冲区
INT8U RxBuf[8]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //接收绶冲区
INT16U timer[2]; //超时计数器
/*****************************************************************************************
//函数名:void Delay100us(INT8U s)
//输入:时间
//输出:无
//功能描述:廷时
/*****************************************************************************************/
void Delay100us(INT8U n)
{
INT8U i;
while(n--)
{
for(i=0; i<35; i++);
}
}
/*****************************************************************************************
//函数名:delay(unsigned int s)
//输入:时间
//输出:无
//功能描述:普通廷时
/*****************************************************************************************/
delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
/*****************************************************************************************
//函数名:CpuInit()
//输入:无
//输出:无
//功能描述:SPI初始化程序
/*****************************************************************************************/
CpuInit(void)
{
POW_UP = 1;
Delay100us(40);
CE = 0;
CS = 0;
// SCK = 0;
}
/*****************************************************************************************
//函数名:void TimerInit(void)
//输入:无
//输出:无
//功能描述:定时器0初始化程序
/*****************************************************************************************/
void TimerInit(void)
{
TH0 = TIMER0H;
TL0 = TIMER0L;
ET0 = 1; //定时器0中断允许
TF0 = 0;
TR0 = 1; //启动定时器0
EA = 1; //开全局中断
}
/*****************************************************************************************
//函数名:ResetTimer(INT8U n)
//输入:要复位的计时器
//输出:无
//功能描述:复位计时器
/*****************************************************************************************/
void ResetTimer(INT8U n)
{
ET0 = 0; // Disable Timer0 interrupt
timer[n & 0x01] = 0; // Clear timer[n]
ET0 = 1; // Enable Timer0 interrupt
}
/*****************************************************************************************
//函数名:INT16U ReadTimer(INT8U n)
//输入:要读的计时器
//输出:读出值
//功能描述:读计时器
/*****************************************************************************************/
INT16U ReadTimer(INT8U n)
{
INT16U tmp;
ET0 = 0; // Disable Timer0 interrupt
tmp = timer[n]; // Clear timer[n]
ET0 = 1; // Enable Timer0 interrupt
return tmp;
}
/*****************************************************************************************
//函数名:UartInit()
//输入:无
//输出:无
//功能描述:串口初始化程序
/*****************************************************************************************/
void UartInit(void)
{
SCON = 0x50; //串口方式1,允许接收
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1
TH1 = TIMER1;
TL1 = TIMER1;
TR1 = 1; //启动定时器1
}
/*****************************************************************************************
//函数名:SendCh(ch)
//输入:无
//输出:无
//功能描述:串口发送一个字符
/*****************************************************************************************/
void SendCh(INT8U ch)
{
SBUF = ch;
while(!TI);
TI = 0;
}
/*****************************************************************************************
//函数名:void SpiWriteByte(INT8U dat)
//输入:发送的数据
//输出:无
//功能描述:SPI发送一个字节
/*****************************************************************************************/
void SpiWriteByte(INT8U dat)
{
INT8U i;
SCK = 0;
_nop_();
_nop_();
for(i=0; i<8; i++)
{
if((dat & 0x80) == 0x80)
{
MOSI = 1;
MISO = 1;
}
else
{
MOSI = 0;
MISO = 0;
}
dat <<= 1;
SCK = 1;
_nop_();
_nop_();
SCK = 0;
_nop_();
_nop_();
}
}
/*****************************************************************************************
//函数名:INT8U SpiReadByte(void)
//输入:无
//输出:读出的数据
//功能描述:SPI读出一个字节
/*****************************************************************************************/
INT8U SpiReadByte(void)
{
INT8U i,temp;
temp = 0;
MISO = 1;
MOSI = 1;
SCK = 0;
_nop_();
_nop_();
for(i=0; i<8; i++)
{
temp <<= 1;
SCK = 1;
_nop_();
_nop_();
if(MISO)temp++;
SCK = 0;
_nop_();
_nop_();
}
return temp;
}
/*****************************************************************************************
//函数名:SetTxMode()
//输入:无
//输出:无
//功能描述:转为发送模式
/*****************************************************************************************/
void SetTxMode(void)
{
unsigned char ch;
CS = 1;
Delay100us(0);
ch = FRESELE<<1;
SpiWriteByte(ch);
CS = 0;
Delay100us(2);
}
/*****************************************************************************************
//函数名:SetRxMode()
//输入:无
//输出:无
//功能描述:转为接收模式
/*****************************************************************************************/
void SetRxMode(void)
{
unsigned char ch;
CS = 1;
Delay100us(0);
ch = FRESELE<<1;
SpiWriteByte(ch | 0x01);
CS = 0;
Delay100us(2); //200us
}
/*****************************************************************************************
//函数名:Nrf2401Init()
//输入:地址,发送数据位数
//输出:无
//功能描述:Nrf2401Init初始化,这里我们配置成32位地址。
/*****************************************************************************************/
void Nrf2401Init(void)
{
INT8U i;
CE = 0;
CS = 1;
Delay100us(0);
for(i=0; i<15; i++)
{
SpiWriteByte(CofigBuf[i]);
}
CS = 0;
Delay100us(30);
}
/*****************************************************************************************
//函数名:TranData()
//输入:无
//输出:无
//功能描述:发送发送缓冲区的数据。
/*****************************************************************************************/
void TranData(void)
{
INT8U i;
SetTxMode();
CE = 1;
Delay100us(1);
for(i=0; i<4; i++)
{
SpiWriteByte(AddrCofig[i]); //发送地址
}
for(i=0; i<5; i++)
{
SpiWriteByte(TxBuf[i]); //发送五位
}
CE = 0;
Delay100us(13);
}
/*****************************************************************************************
//函数名:void ReceiveBytes(void)
//输入:无
//输出:无
//功能描述:接收数据存在接收缓冲区内
/*****************************************************************************************/
INT8U ReceivePacket(void)
{
INT8U i;
SetRxMode();
CE = 1;
ResetTimer(1);
while(DR1 == 0)
{
if(ReadTimer(1) > 1000)
{
CE = 0;
return 0;
}
}
i = 0;
while(DR1)
{
RxBuf[i] = SpiReadByte();
i++;
if (i == 5)
break;
}
while(DR1)
{
SpiReadByte();
}
CE = 0;
return 1;
}
/******************************************************************************************
*******************************************************************************************
************************************中断服务程序*******************************************
*******************************************************************************************
******************************************************************************************/
void Timer0ISR(void) interrupt 1
{
EA = 0;
TH0+=TIMER0H;
TL0+=TIMER0L;
timer[0]++;
timer[1]++;
EA = 1;
}
/******************************************************************************************
*******************************************************************************************
******************************************主程序*******************************************
*******************************************************************************************
******************************************************************************************/
main()
{
INT8U temp, i;
CpuInit();
TimerInit();
UartInit();
LED1=0;
LED2=0;
delay(20000);
LED1=1;
LED2=1;
Nrf2401Init();
delay(500);
while(1)
{
temp = ReceivePacket();
if(temp == 1)
{
LED1=0;
delay(5000);
LED1=1;
for(i=0; i<5; i++)
{
SendCh(RxBuf[i]);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -