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

📄 89lv51.c

📁 NRF24L01 c51例程,已通过.C51
💻 C
字号:
#include <reg51.h>
#include <intrins.h>
#include "api.h"
/***************************************************/
#define uchar unsigned char
#define TX_ADR_WIDTH    5   // 地址字节数为5 BYTE
#define TX_PLOAD_WIDTH  20  // 数据量为20 BYTE
uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; // 接收发送数据的地址.
uchar rx_buf[TX_PLOAD_WIDTH];
uchar tx_buf[TX_PLOAD_WIDTH];
uchar flag;
/**************************************************/
sbit CE =  P2^5;
sbit CSN=  P2^0;
sbit SCK=  P2^1;
sbit MOSI= P2^2;
sbit MISO= P2^3;
sbit IRQ = P3^2;
/**************************************************/
uchar 	bdata sta;
sbit	RX_DR	=sta^6;
sbit	TX_DS	=sta^5;
sbit	MAX_RT	=sta^4;
/**************************************************/
void init_io(void)
{	P0=0x0f;		// led light
	CE=0;				// chip enable
	CSN=1;			// Spi disable	
	SCK=0;			// Spi clock line init high
	P0=0xff;		// led close
}
/**************************************************/
void init_int0(void)
{	EA=1;
	EX0=1;						
}
/**************************************************
void delay100(uchar )
{	uchar  x;
	uchar  y;
	for(x=0;x<100;x++)
	{	for(y=0;y<100;y++)
		_nop_();
	}
}
/**************************************************/
void delay_ms(unsigned int x)
{   unsigned int i,j;
    i=0;
    for(i=0;i<x;i++)
    {  j=108;           
       while(j--);
    }
}
/**************************************************/
uchar SPI_RW(uchar byte)									
{ 	uchar bit_ctr;
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // 输出 8 位
   	{	MOSI = (byte & 0x80);         // 从MOSI脚输出,从高位到低位.当BYTE 最高位为1时逻辑运算为1,输出1.运算为0时输出0
   		byte = (byte << 1);           // 左移1位.将低位向高位转移.
   		SCK = 1;                      // 将SCK脚拉高,
   		byte |= MISO;       		  		// 从MISO 中读出状态位存入BYTE中.
   		SCK = 0;            		  		// 将SCK脚拉低.发送一位完成.
   	}
    return(byte);           		  	// 返回状态位
}
/**************************************************/
uchar SPI_RW_Reg(BYTE reg, BYTE value)
{ 	uchar status;
  	CSN = 0;                   // CS为低,开始SPI传输
  	status = SPI_RW(reg);      // 传送命令与地址
  	SPI_RW(value);             // 写1 BYTE 值
  	CSN = 1;                   // 完成SPI传输
  	return(status);            // 返回 status
}
/**************************************************/
BYTE SPI_Read(BYTE reg)
{
	BYTE reg_val;
  	CSN = 0;                // CS为低,开始SPI传输
  	SPI_RW(reg);            // 设置读地址
  	reg_val = SPI_RW(0);    // 读数据
  	CSN = 1;                // 完成SPI传输
  	return(reg_val);        // 返回数据
}
/**************************************************/
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{ 	uchar status,byte_ctr;
  	CSN = 0;                    		// CS为低,开始SPI传输
  	status = SPI_RW(reg);       		// 传输读接收数据的命令.				61H
  	for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
   	pBuf[byte_ctr] = SPI_RW(0);    // 读 1 BYTE数据
  	CSN = 1;                           // 数据传送完成.
  	return(status);                    // return nRF24L01 status byte
}
/**************************************************/
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{ 	uchar status,byte_ctr;
  	CSN = 0;                   // CS为低,开始SPI传输
  	status = SPI_RW(reg);      // 传输写发送数据的命令.				A0H
  	for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // 传送发送数据
    SPI_RW(*pBuf++);
  	CSN = 1;                 // 数据传送完成.
  	return(status);          // return nRF24L01 status byte
}
/**************************************************/
void RX_Mode(void)
{		CE=0;
  	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); 	 // 设接收地址和地址宽度     20+0AH
  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      				 								 // 开放Pipe0 自动应答	20+01H
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); 					 								 // 开放Pipe0 接收数据	20+02H
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);        				 								 // 选择RF频率通道		20+05H
  	SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); 			 					 // 选择数据宽度		20+11H
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   				 								 // 设置TX_PWR,Datarate,LNA 20+06H
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     				                 // 设置PWR_UP,CRC,RX_DR 	20+00H
  	CE = 1; 									 																				 // Set CE pin high to enable RX device
  }
/**************************************************
void TX_Mode(void)
{		CE=0;	
  	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 设发送地址和地址宽度     	20+10H
  	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 设接收地址和地址宽度     	20+0AH
  	SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); 		   			 // 写发送数据		      	A0H
  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      			   // 开放Pipe0 自动应答		20+01H
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  			   // 开放Pipe0 接收数据		20+02H
  	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); 			   // 500us + 86us, 10 retrans... 20+04H
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);        			   // 选择RF频率通道			20+05H
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);  	 			   // 设置TX_PWR,Datarate,LNA 	20+06H
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     			   // 设置PWR_UP,CRC,TX_DR 		20+00H
		CE=1;
}
/**************************************************
void check_ACK()
{
	uchar test;
	test=SPI_Read(READ_REG+STATUS);											// 读STATUS 的值
	test=test&0x20;																			// 测试 TX_DS=1
	if(test==0x20)																			// TX_DS =1
	{	P0=0x00;																					// turn on all led
	  delay100();																			// delay 100ms
		P0=0xff;
	}
}
/**************************************************
Function: CheckButtons();
Description:
  check buttons ,if have press,read the key values,
  turn on led and transmit it;  after transmition,
  if received ACK, clear TX_DS interrupt and enter RX Mode;
  turn off the led
/**************************************************/
void CheckButtons()
{
	uchar Temp,xx,Tempi;

	P0=0xff;
	Temp=P0&0x0f;			         //read key value from port P0
	if (Temp!=0x0f)
	{	
		delay_ms(10);
		Temp=P0&0x0f;				// read key value from port P0
		if (Temp!=0x0f)
		{
				xx=Temp;
				Tempi=Temp<<4;		// Left shift 4 bits
				P0=Tempi;		    // Turn On the led
				tx_buf[0]=Tempi;	// Save to tx_buf[0]
				TX_Mode();			// set TX Mode and transmitting				
				check_ACK();		// if have acknowledgment from RX device,turn on all led
				SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS));	// clear interrupt flag(TX_DS)
				delay_ms(200);
				P0=0xff;			// Turn off the led				
				RX_Mode();			// set receive mode
				while((P0&0x0f)!=0x0f);
		}
	}
}
/**************************************************/
void main(void)
{
	uchar xx;
	init_io();		// Initialize IO port
	init_int0();		// enable int0 interrupt
	RX_Mode();		// set RX mode
	while(1)
	{
		CheckButtons(); // scan key value and transmit 
		if(flag)		// finish received
		{
			flag=0;		//	set flag=0
			P0=rx_buf[0];	// turn on led
			delay_ms(200);
  			P0=0xff;		// turn off led
			xx=rx_buf[0]>>4;// right shift 4 bits			
		}
	}
}
/**************************************************
Function: ISR_int0() interrupt 0;
Description:
  if RX_DR=1 or TX_DS or MAX_RT=1,enter this subprogram;
  if RX_DR=1,read the payload from RX_FIFO and set flag;
/**************************************************/
void ISR_int0(void) interrupt 0
{
	sta=SPI_Read(STATUS);															// read register STATUS's value
	if(RX_DR)																				  // 判断是否是接收中断
	{
		SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// 读取收到的数据
		flag=1;
	}
	if(MAX_RT)
	{
		SPI_RW_Reg(FLUSH_TX,0);
	}
		SPI_RW_Reg(WRITE_REG+STATUS,sta);									// clear RX_DR or TX_DS or MAX_RT interrupt flag
}
/**************************************************/

⌨️ 快捷键说明

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