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

📄 main.c

📁 nrf24e1 PWM输出程序,可以调节占空比,可用做音频信号输出.
💻 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 + -