📄 89lv51.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 + -