📄 w78ie54无线接收端.c
字号:
//================================================================================
//编制:忻琦 2007.12.9 串口通讯速率:Baud:9600 fosc=11.0592MHz
//================================================================================
//1号装置 //接受端
//#pragma SRC
//#pragma SMALL
#include <REG51.H>
#define INBUF_LEN 32 //数据长度
//(以下操作全部从对应寄存器的字节0开始)
#define WC 0x00 // 写配置寄存器(RF-Configuration Register)
#define RC 0x10 // 读配置寄存器(RF-Configuration Register)
#define WTP 0x20 // 向TX-Payload寄存器写入发送有效数据
#define RTP 0x21 // 从TX-Payload寄存器读取发送有效数据
#define WTA 0x22 // 向TX-Address寄存器写入发送地址
#define RTA 0x23 // 从TX-Address寄存器读取发送地址
#define RRP 0x24 // 从RX-Payload寄存器读取接收到的有效数据
/*nRF905寄存器配置参数*/
struct RFConfig
{
unsigned char n;
unsigned char buf[10];
} RxTxConf;
char bdata char_buf;
unsigned char DATA_STR[16]; //放置接收的命令
unsigned char TxBuf[4];
unsigned char RxBuf[INBUF_LEN];
unsigned char CHARcount,RD_FLAG;
bit read_flag=0;
sbit AM=P0^4;
sbit DR=P3^2;
sbit TX_EN=P0^0;
sbit TRX_CE=P0^1;
sbit MOSI=P0^7;
sbit MISO=P0^6;
sbit SCK=P3^7;
sbit CSN=P3^3;
sbit PWR=P0^2; //芯片上电
sbit CD=P0^3;
sbit uCLK=P0^5;
sbit Led1=P2^0; //指示灯
sbit flag= char_buf^7;
sbit flag1= char_buf^0;
char uuch;
unsigned long t_num=0;
void Delay (unsigned char t) //t=1延迟650um
{
unsigned int i,j;
for (i=0;i<t;i++)
{
for(j=0;j<=650;j++);
}
}
//<SPI写操作 代码>
void SpiWrite(unsigned char ch_byte)
{
unsigned char i;
char_buf=ch_byte; // 将需要发送的数据写入缓存
for (i=0;i<8;i++) // 循环8次发送一个字节的数据
{
if (flag) // flag = char_buf^7;
MOSI=1;
else
MOSI=0;
SCK=1; // SCK 高电平
char_buf=char_buf<<1; // 左移一位,为下一位的发送做准备
SCK=0; // SCK 低电平
}
}
//<SPI读操作 代码>
unsigned char SpiRead(void)
{
unsigned char i;
for (i=0;i<8;i++) //循环8次发送一个字节的数据
{
char_buf=char_buf<<1; //左移一位,准备接收下一位数据
SCK=1; // SCK 高电平
if (MISO)
flag1=1; // flag1 = char_buf^0;
else
flag1=0;
SCK=0; // SCK低电平
}
return char_buf; // char_buf 为接收到的完整数据
}
//意:数据的传输时,高位在前,低位在后。
//<主机通过SPI接口向905配置寄存器写入信息>
void Config905(void)
{
unsigned char i;
CSN=0; // CSN片选信号,SPI使能
SpiWrite(WC); // 向905芯片写配置命令
for (i=0;i<RxTxConf.n;i++) // 循环写入配置信息
{
SpiWrite(RxTxConf.buf[i]); //RxTxConf保存预先设置好的配置信息
}
CSN=1; // 结束SPI数据传输
}
void Read905(void)
{
unsigned char i;
CSN=0; // CSN片选信号,SPI使能
SpiWrite(RC); // 向905芯片写配置命令
for (i=0;i<RxTxConf.n;i++) // 循环写入配置信息
{
DATA_STR[i]=SpiRead(); //RxTxConf保存预先设置好的配置信息
}
CSN=1; // 结束SPI数据传输
}
void TXready(char adr)
{
TxBuf[0]=adr;
TxBuf[1]=adr;
TxBuf[2]=adr;
TxBuf[3]=adr;
}
//使用nRF905发送数据
void TxPacket(void)
{
unsigned char i;
TX_EN=1;
TRX_CE=0;
Delay(1); // delay for mode change(>=650us)
CSN=0;
SpiWrite(WTP); // 先写数据,Write payload command
for (i=0;i<32;i++)
{
SpiWrite(RxBuf[i]); // 写入32直接发送数据
}
CSN=1; // 关闭SPI,保存写入的数据
Delay(1);
CSN=0; // SPI使能,准备写入地址信息
SpiWrite(WTA); // 再写地址,写数据至地址寄存器
for (i=0;i<4;i++) // 写入4字节地址
{
SpiWrite(TxBuf[i]);
}
CSN=1; // 关闭SPI
TRX_CE=1; // 进入发送模式,启动射频发送
Delay(1); // 进入ShockBurst发送模式后,芯片保证数据发送完成后返回STANDBY模式
TRX_CE=0;
}
void RxPacket(void)
{
unsigned char i;
TRX_CE=0; // 设置905进入待机模式
CSN=0; // 使能SPI
SpiWrite(RRP); // 准备读取接收到的数据
for (i=0;i<32;i++)
{
RxBuf[i]=SpiRead(); // 通过SPI接口从905芯片读取数据
}
CSN=1; // 禁用SPI
while(DR||AM);
}
//<设置器件为接收模式>
void SetRxMode(void)
{
TX_EN=0;
TRX_CE=1;
Delay(1); // delay for mode change(>=650us)
}
void init_serialcomm(void) //初始化串口
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
TH1 = 0xFD; //Baud:9600 fosc=11.0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; //timer 1 run
}
//向串口发送一个字符,非中断方式
void send_char_com(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com(unsigned char *str,unsigned int strlen)
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
CHARcount=0;
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
if(RI)
{
unsigned char ch;
RI = 0;
ch = SBUF;
DATA_STR[CHARcount]=ch;
if (CHARcount<INBUF_LEN)
CHARcount++;
if (ch==0xaa)
read_flag=1; //如果串口接收的数据
//就置位取数标志
}
}
void setConf(void)
{
RxTxConf.n = 10; //配置寄存器内容
RxTxConf.buf[0]=0x4c;
RxTxConf.buf[1]=0x0c; //RxTxConf={ 10,
// 0x4c,0x0c,0x44,0x20,0x20,0xcc,0xcc,0xcc,0xcc,0x58};
RxTxConf.buf[2]=0x44; //4字节的地址宽度
RxTxConf.buf[3]=0x20;
RxTxConf.buf[4]=0x20;
RxTxConf.buf[5]=0xcc; //接收地址为0x19
RxTxConf.buf[6]=0xcc;
RxTxConf.buf[7]=0xcc;
RxTxConf.buf[8]=0xcc;
RxTxConf.buf[9]=0x58;
Config905(); //写入配置
}
void ChComd(void) //解释命令
{
unsigned char ch;
ch=DATA_STR[0];
switch (ch)
{
case 'h':
DATA_STR[0]='H';
DATA_STR[1]='e';
DATA_STR[2]='l';
DATA_STR[3]='l';
DATA_STR[4]='o';
send_string_com(DATA_STR,5);
break;
case 'r':
Read905();
send_string_com(DATA_STR,10);
break;
case 'g':
while (DR==1);
PWR=0;
Delay(10);
PWR=1;
Delay(10);
setConf();
Delay(10);
SetRxMode(); //设置接收模式
DATA_STR[0]='S';
DATA_STR[1]='E';
DATA_STR[2]='T';
DATA_STR[3]='U';
DATA_STR[4]='P';
send_string_com(DATA_STR,5);
break;
case 'd':
uuch=0xcd;
RxBuf[0]=1;
RxBuf[1]=0xcc;
RxBuf[2]=uuch;
RxBuf[3]=0x00;
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
case 'b':
uuch=0xcb;
RxBuf[0]=1;
RxBuf[1]=0xcc;
RxBuf[2]=uuch;
RxBuf[3]=0x00;
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
case 'e':
uuch=0xce;
RxBuf[0]=1;
RxBuf[1]=0xcc;
RxBuf[2]=uuch;
RxBuf[3]=0x00;
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
case 'x':
uuch=0xcb;
RxBuf[0]=1;
RxBuf[1]=0xcc;
RxBuf[2]=uuch;
RxBuf[3]=0xcd;
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
case 'y':
uuch=0xcd;
RxBuf[0]=1;
RxBuf[1]=0xcc;
RxBuf[2]=uuch;
RxBuf[3]=0xcb;
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
case 'z':
RxBuf[0]=DATA_STR[1];
RxBuf[1]=DATA_STR[2];
RxBuf[2]=DATA_STR[3];
RxBuf[3]=DATA_STR[4];
uuch=RxBuf[2];
TXready(uuch);
TxPacket(); //发射
SetRxMode(); //设置为接收
break;
}
}
void PowUp(void)
{
PWR=0;
Delay(10);
PWR=1;
Delay(10);
setConf();
Delay(10);
SetRxMode(); //设置接收模式
Delay(2);
}
main() //程序入口
{
//配置寄存器内容
init_serialcomm(); //初始化串口
CHARcount=0;
Led1=0; //打开指示灯
PowUp();
PowUp();
while(1)
{
if (t_num<100000)
t_num++;
else
t_num=0;
if (t_num==40000||t_num==90000)
{
//DATA_STR[0]='s';
//read_flag=1;
if (Led1)
Led1=0;
else
Led1=1;
}
if ( DR )
{
RxPacket(); //接收
send_string_com(RxBuf,32);
SetRxMode(); //设置为接收
}
if(read_flag) //如果取数标志已置位,就将读到的数从串口发出
{
read_flag=0; //取数标志清0
ChComd(); //解释命令
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -