?? 無線發射端.c
字號:
//================================================================================
//編制:忻琦 2007.12.9 串口通訊速率:Baud:9600 fosc=11.0592MHz
//================================================================================
//1號裝置 //發射端端 at89c2051
//#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寄存器讀取接收到的有效數據
#define adss 0xcb //本機地址
/*nRF905寄存器配置參數*/
struct RFConfig
{
unsigned char n;
unsigned char buf[10];
} RxTxConf;
char temp_buff[9]; //存儲讀取的字節,read scratchpad為9字節
char *p;
char bdata char_buf;
unsigned char TxBuf[4];
unsigned char RxBuf[INBUF_LEN];
unsigned char CHARcount,RD_FLAG;
unsigned char DATA_STR[16]; //放置接收的命令
bit read_flag=0;
sbit AM=P1^3;
sbit DR=P3^2;
sbit TX_EN=P1^7;
sbit TRX_CE=P1^6;
sbit MOSI=P1^0;
sbit MISO=P1^1;
sbit SCK=P3^7;
sbit CSN=P3^3;
sbit PWR=P1^5; //芯片上電
sbit CD=P1^4;
sbit uCLK=P1^2;
sbit Led1=P3^4; //指示燈
sbit Led2=P3^5;
sbit flag= char_buf^7;
sbit flag1= char_buf^0;
sbit DQ = P3^1; //溫度讀口
char uuch;
unsigned long t_num=0;
//=============================================================================
void qdelay(unsigned int i)
{
while(i--);
}
//初始化函數
char Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
qdelay(8); //稍做延時
DQ = 0; //單片機將DQ拉低
qdelay(80); //精確延時 大于 480us
DQ = 1; //拉高總線
qdelay(14);
x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
//if (x==0)
//ledb=0; //成功初始化
//else
//ledb=1;
qdelay(20);
return (x);
}
//讀一個字節
char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat=0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
qdelay(4);
}
return(dat);
}
//寫一個字節
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
qdelay(5);
DQ = 1;
dat>>=1;
}
qdelay(4);
}
//讀取溫度
int ReadTemperature(void)
{
unsigned char i;
unsigned int t=0;
float tt=0;
p=temp_buff;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉換
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
for(i=0;i<9;i++)
{
*p = ReadOneChar();
p++;
}
t=temp_buff[1];
t=t*0x100+temp_buff[0];
t /=16;
//tt=t*0.0625;
//t= tt*10+0.5; //放大10倍輸出并四舍五入---此行沒用
return(t);
}
//============================================================
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 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);
TRX_CE=1;
}
//<設置器件為接收模式>
void SetRxMode(void)
{
TX_EN=0;
TRX_CE=1;
Delay(1); // delay for mode change(>=650us)
}
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]=adss; //接收地址為0x19
RxTxConf.buf[6]=adss;
RxTxConf.buf[7]=adss;
RxTxConf.buf[8]=adss;
RxTxConf.buf[9]=0x58;
Config905(); //寫入配置
}
void ChComd(void) //解釋命令
{
unsigned char ch;
ch=DATA_STR[0];
switch (ch)
{
case 'g':
while (DR==1);
PWR=0;
Delay(10);
PWR=1;
Delay(10);
setConf();
Delay(10);
SetRxMode(); //設置接收模式
break;
}
}
void PowUp(void)
{
PWR=0;
Delay(10);
PWR=1;
Delay(10);
setConf();
Delay(10);
SetRxMode(); //設置接收模式
Delay(2);
}
main() //程序入口
{
CHARcount=0;
Led1=0; //打開指示燈
PowUp();
PowUp();
while(1)
{
if (t_num<50000)
{
t_num++;
if ( DR )
{
RxPacket(); //接收并存在RxBuf中
while (DR || AM );
if (RxBuf[2]==adss && RxBuf[3]!=0 && RxBuf[0]==1) //如果是中繼就繼續發射
{
uuch=RxBuf[3];
}
if (RxBuf[2]==adss && RxBuf[3]==0 && RxBuf[0]==1) //如果不是就測溫返回
{
RxBuf[0]=2; //返回信息
RxBuf[10]=ReadTemperature(); //檢測溫度并返回
RxBuf[11]=temp_buff[0];
RxBuf[12]=temp_buff[1];
RxBuf[13]=temp_buff[2];
RxBuf[14]=temp_buff[3];
RxBuf[15]=temp_buff[4];
RxBuf[16]=temp_buff[5];
RxBuf[17]=temp_buff[6];
RxBuf[18]=temp_buff[7];
RxBuf[19]=temp_buff[8];
uuch=RxBuf[1];
}
if (RxBuf[2]==adss && RxBuf[3]!=0 && RxBuf[0]==2) //如果中繼是就測溫返回
{
uuch=RxBuf[1];
}
if (RxBuf[3]==adss && RxBuf[0]==1) //如果不是中繼就測溫返回
{
RxBuf[0]=2; //返回信息
RxBuf[10]=ReadTemperature(); //檢測溫度并返回
RxBuf[11]=temp_buff[0];
RxBuf[12]=temp_buff[1];
RxBuf[13]=temp_buff[2];
RxBuf[14]=temp_buff[3];
RxBuf[15]=temp_buff[4];
RxBuf[16]=temp_buff[5];
RxBuf[17]=temp_buff[6];
RxBuf[18]=temp_buff[7];
RxBuf[19]=temp_buff[8];
uuch=RxBuf[2];
}
TXready(uuch); //發射地址
TxPacket(); //發射
SetRxMode(); //設置為接收
if(Led2)
Led2=0;
else
Led2=1;
}
}
else
{
t_num=0;
}
if(read_flag) //如果取數標志已置位,就將讀到的數從串口發出
{
read_flag=0; //取數標志清0
ChComd(); //解釋命令
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -