📄 main.c
字号:
#include <Nordic\reg24e1.h>
//include "ISD51.H"
sbit LEDR = P0^4;
sbit LEDG = P0^5;
sbit KEYR = P0^3;
sbit KEYT = P0^6;
#define int8u unsigned char
#define int16u unsigned int
#define FRESELE 0x28
#define ADDR_INDEX 8 // Index to default address bytes in RxTxConf.buf
#define ADDR_COUNT 4 // Number of address bytes
struct UARTBUF
{
int8u Buf[20];
int8u Counter;
int8u NewData;
}Rx;
int8u RFConfig[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
0x04 //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 rfAddress[4] = { 0xcd, 0xef, 0x12, 0xaa };
int8u timer[2]; // Two utility timers used in radio.c
int8u t0lrel, t0hrel;
int8u buf[8];
/*****************************************************************************************
//函数名:void Delay100us(int8u n)
//输入:时间
//输出:无
//功能描述:廷时100us
/*****************************************************************************************/
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++);
for(i=0; i<s; i++);
}
/*****************************************************************************************
//函数名:int8u SpiReadWrite(int8u b)
//输入:发送的数据
//输出:收到的数据
//功能描述:SPI发送接收一个字节
/*****************************************************************************************/
int8u SpiReadWrite(int8u b)
{
EXIF &= ~0x20; // Clear SPI interrupt
SPI_DATA = b; // Move byte to send to SPI data register
while((EXIF & 0x20) == 0x00); // Wait until SPI hs finished transmitting
return SPI_DATA;
}
/*****************************************************************************************
//函数名:TimerInit()
//输入:无
//输出:无
//功能描述:定时器0初始化
/*****************************************************************************************/
void TimerInit(void)
{
timer[0] = timer[1] = 0;
TR0 = 0;
TMOD &= ~0x03;
TMOD |= 0x01; // mode 1
CKCON |= 0x08; // T0M = 1 (/4 timer clock)
t0lrel = 0x60; // 1KHz tick...
t0hrel = 0xF0; // ... = 65536-16e6/(4*1e3) = F060h
TF0 = 0; // Clear any pending Timer0 interrupts
TR0 = 1; // Start Timer0
ET0 = 1; // Enable Timer0 interrupt
}
/*****************************************************************************************
//函数名:ResetTimer(int8u n)
//输入:要复位的计时器
//输出:无
//功能描述:复位计时器
/*****************************************************************************************/
void ResetTimer(int8u n)
{
ET0 = 0; // Disable Timer0 interrupt
timer[n & 0x01] = 0; // Clear timer[n]
ET0 = 1; // Enable Timer0 interrupt
}
/*****************************************************************************************
//函数名:ReadTimer()
//输入:要读的计时器
//输出:读出值
//功能描述:读计时器
/*****************************************************************************************/
unsigned ReadTimer(int8u n)
{
unsigned tmp;
ET0 = 0; // Disable Timer0 interrupt
tmp = timer[n]; // Clear timer[n]
ET0 = 1; // Enable Timer0 interrupt
return tmp;
}
/*****************************************************************************************
//函数名:SciInit()
//输入:无
//输出:无
//功能描述:串口初始化
/*****************************************************************************************/
void SciInit(void)
{
TH1 = 243; // 19200@16MHz (when T1M=1 and SMOD=1)
CKCON |= 0x10; // T1M=1 (/4 timer clock)
PCON = 0x80; // SMOD=1 (double baud rate)
SCON = 0x52; // Serial mode1, enable receiver
TMOD = 0x20; // Timer1 8bit auto reload
TR1 = 1; // Start timer1
P0_ALT |= 0x86; // Select alternate functions on pins P0.1 and P0.2 and P0.7(pwm)
P0_DIR &= 0x0F; //led p0.4 p0.5 output
P0_DIR |= 0x48; // P0.3 is input p0.6 input
ES = 1;
EA=1;
}
void PWMINIT(void)
{
PWMCON=0XC0;
PWMDUTY=0X55;
}
/*****************************************************************************************
//函数名:SetRxMode()
//输入:无
//输出:无
//功能描述:转为接收模式
/*****************************************************************************************/
void SetRxMode(void)
{
int8u ch;
CS = 1;
Delay100us(0);
ch = FRESELE << 1;
SpiReadWrite(ch | 0x01);
CS = 0;
}
/*****************************************************************************************
//函数名:SetTxMode()
//输入:无
//输出:无
//功能描述:转为发送模式
/*****************************************************************************************/
void SetTxMode(void)
{
int8u ch;
CS = 1;
Delay100us(0);
ch = FRESELE << 1;
SpiReadWrite(ch);
CS = 0;
}
/*****************************************************************************************
//函数名:SendC()
//输入:发送的数据
//输出:无
//功能描述:串口初始化
/*****************************************************************************************/
void SendCh(char c)
{
TI = 0;
SBUF = c;
while(!TI);
TI = 0;
}
/*****************************************************************************************
//函数名:Nrf24E1Init()
//输入:无
//输出:无
//功能描述:Nrf24E1Init初始化,这里我们配置成32位地址。
/*****************************************************************************************/
void Nrf24E1Init()
{
int8u i;
SPICLK = 0; // Max SPI clock
SPI_CTRL = 0x02; // Connect internal SPI controller to Radio
CE = 0;
CS = 1; // RF SPI CS = 1
Delay100us(0);
SpiReadWrite(0x00); // We are not using the DuoCeiver functionallity
for(i=1;i<15;i++)
{
SpiReadWrite(RFConfig[i]);
}
CS = 0;
Delay100us(30);
}
/*****************************************************************************************
//函数名:TransmitPacket(int8u *pBuf)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
/*****************************************************************************************/
TransmitPacket(int8u *pBuf)
{
int8u i;
SetTxMode();
CE = 1;
Delay100us(1);
for (i=0;i<ADDR_COUNT;i++)
{
SpiReadWrite(rfAddress[i]);
}
SpiReadWrite(1);
for (i=0;i<4;i++)
{
SpiReadWrite(pBuf[i]);
}
CE = 0;
Delay100us(13); // Wait until finished transmitting (200us + 256us)//delay(5)
}
/*****************************************************************************************
//函数名:void SendAck(unsigned char msgid)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
/*****************************************************************************************/
void SendAck(unsigned char msgid)
{
int8u i;
SetTxMode();
CE = 1;
Delay100us(2);
for (i=0;i<4;i++)
{
SpiReadWrite(rfAddress[i]);
}
SpiReadWrite(msgid);
CE = 0;
Delay100us(1);
}
/*****************************************************************************************
//函数名:int8u ReceivePacket(int8u *pBuf)
//输入:接收数据缓冲区
//输出:成功返回1,否则返回0
//功能描述:接收数据存在缓冲区内
/*****************************************************************************************/
int8u ReceivePacket(int8u *pBuf)
{
int8u i,cmd;
SetRxMode();
CE = 1;
ResetTimer(1);
while(DR1 == 0)
{
if (ReadTimer(1) > 1000)
{
CE = 0;
return 0;
}
}
cmd = SpiReadWrite(0);
i = 0;
while(DR1)
{
pBuf[i] = SpiReadWrite(0);
i++;
if (i == 5)
break;
}
while(DR1)
{
SpiReadWrite(0);
}
CE = 0;
return cmd;
}
/******************************************************************************************
*******************************************************************************************
************************************中断服务程序*******************************************
*******************************************************************************************
******************************************************************************************/
void Timer0ISR (void) interrupt 1 using 1 //定时器0中断
{
TF0 = 0; // Clear Timer0 interrupt
TH0 = t0hrel; // Reload Timer0 high byte
TL0 = t0lrel; // Reload Timer0 low byte
timer[0]++; // Increment timer[0]
timer[1]++; // Increment timer[1
}
void UartISR (void) interrupt 4 using 2 //串口中断
{
int8u temp;
EA = 0;
if(RI)
{
temp = SBUF;
if(temp == '@') //帧头
{
Rx.Buf[0] = '@';
Rx.Counter = 1;
}
else if(temp == '*') //帧尾
{
Rx.Buf[Rx.Counter] = temp;
Rx.Buf[Rx.Counter + 1] = '\0';
Rx.NewData = 1;
}
else if(Rx.Counter < 39){
Rx.Buf[Rx.Counter] = temp;
Rx.Counter += 1;
}
RI = 0;
}
if(TI)
{
TI = 0;
}
EA = 1;
}
/******************************************************************************************
*******************************************************************************************
******************************************主程序*******************************************
*******************************************************************************************
******************************************************************************************/
void main(void)
{
unsigned char temp;
unsigned char i;
SciInit();
TimerInit();
EA=1;
LEDR=0;
LEDG=0;
delay(10000);
LEDR=1;
LEDG=1;
Nrf24E1Init();
PWMINIT();
while(1)
{
for(i=0;i<256;i++)
{
//PWMDUTY=i;
delay(10);
}
}
while(1)
{
for(i=0;i<100;i++) SendCh(0xaa);
temp = ReceivePacket(buf);
if(temp != 0)
{
SendAck(temp);
LEDR=0;
LEDG=0;
delay(5000);
LEDR=1;
LEDG=1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -