壓縮包中的內(nèi)容:
下面是發(fā)射端的源代碼:
#include <AT89X52.H>
#include "string.h"
sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit W_IN = P2^2; //電路是用11.0592MHz晶振
sbit W_OUT = P2^0;
sbit DQ =P2^1; //DS18B20數(shù)據(jù)口
unsigned char Te=0;//溫度整數(shù)部分
unsigned char Te_D=0;//溫度小數(shù)部分
unsigned char T0_last;
unsigned char w_data; //接收時(shí)用于存儲(chǔ)兩次上升沿之間的時(shí)長(zhǎng),發(fā)送時(shí)存儲(chǔ)前半周
unsigned char send_busy = 0;//存儲(chǔ)發(fā)送時(shí)后半周
unsigned char recv_timer = 0;
bit w_stat, last_w_stat;
unsigned char jiffies=0;
//定義通信端口
//延時(shí)函數(shù)
void delay(unsigned int i)
{
while(i--);
}
//初始化函數(shù)
Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復(fù)位
delay(8); //稍做延時(shí)
DQ = 0; //單片機(jī)將DQ拉低
delay(50); //精確延時(shí) 大于 480us
DQ = 1; //拉高總線
delay(14);
x=DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
delay(20);
}
//讀一個(gè)字節(jié)
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號(hào)
dat>>=1;
DQ = 1; // 給脈沖信號(hào)
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
//寫(xiě)一個(gè)字節(jié)
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(4);
}
//讀取溫度
void ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char e=0;
//unsigned char t;
unsigned char c,d;
//unsigned char t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
Init_DS18B20();
WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
a=ReadOneChar(); //讀取溫度值低位
b=ReadOneChar(); //讀取溫度值高位
e=a&0x0f;//小數(shù)部分
c=(e*10)/16;
d=((e*10)%16)*10/16;
Te_D=c*10+d;
a=a>>4;
Te=b<<4;
Te=Te|a;
}
void clock_timer(void) interrupt 1 using 1{
if (send_busy){
if(w_data){
w_data--;
w_stat = 0;
}else{
send_busy--;
w_stat = 1;
}
W_OUT = w_stat;
}else{
w_stat = W_IN;
if (w_stat != last_w_stat){
last_w_stat = w_stat;
if (w_stat){
w_data = recv_timer;
recv_timer = 0;
}
}
if (~recv_timer)//if(recv_busy != 0xff)
recv_timer++;
}
jiffies++;
T0_last=TL0;
}
void clock_init(void){
jiffies = 0;
TMOD=0x02;
TH0=TL0=0x0ce;//12M,50us
// TH0=TL0=0x7a;//16M
// TH0=TL0=0x75;//16.59M
// TH0=TL0=0x72;//17M
// TH0=TL0=0x37;//24M
// TH0=TL0=0x47;//22.1844M, 100us
// TH0=TL0=0xa3;//22.1844M, 50us
EA=1;
ET0=1;
TR0=1;
}
void clock_init_again(void){
TMOD=0x02;
TH0=0x0ce;//12M,50us
TL0=T0_last;
// TH0=TL0=0x7a;//16M
// TH0=TL0=0x75;//16.59M
// TH0=TL0=0x72;//17M
// TH0=TL0=0x37;//24M
// TH0=TL0=0x47;//22.1844M, 100us
// TH0=TL0=0xa3;//22.1844M, 50us
EA=1;
ET0=1;
jiffies=0;
TR0=1;
}
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
PCON |= 0x80; //SMOD=1;
TH1 = 0x0e6; //Baud:2400 fosc=11.0592MHz :f4
TL1 = 0x0e6;
//IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
RI=0;
TI=1;
}
void serial_out(char d){
while(!TI);
TI=0;
SBUF=(d);
}
void send_string_com(char *str,int strlen)//串口程序
{ char sum;
int k=0;
serial_out(02);
do
{ sum^=*(str+k);
serial_out(*(str + k));
k++;
} while(k < strlen);
serial_out(sum);
serial_out(03);
}
//等待指定長(zhǎng)度的串行數(shù)據(jù)到達(dá),超時(shí)值為每?jī)蓚(gè)字節(jié)之間的間隔時(shí)間而非等待整個(gè)串的時(shí)間.
//超時(shí)單位為time_out * 100uS
bit wait_serial(unsigned char *p, unsigned char len, unsigned char time_out){
unsigned int time=jiffies;
unsigned char n=0;
do{
if (RI){
p[n++]=SBUF;
RI=0;
if(n==len)
return 0;
time=jiffies;
}
}while(jiffies-time < time_out);
return 1;
}
sys_init(){
clock_init();
init_serialcomm();
}
//=============================================================
//發(fā)送程序 開(kāi)始
//=============================================================
#define PULS_0_WIDTH 8 //低電平脈寬
#define PULS_1_WIDTH 16 //高電平脈寬
#define PULS_HEAD_WIDTH 8 //前導(dǎo)信號(hào)脈寬
#define PULS_START_WIDTH 24 //引導(dǎo)信號(hào)脈寬
#define PULS_STOP_WIDTH 8 //結(jié)束碼脈寬
#define PULS_HEAD_COUNTS 16 //前導(dǎo)信號(hào)長(zhǎng)度
unsigned char send_buf[16];
#define send_byts send_buf[0] //剩余字節(jié)數(shù),發(fā)送完后為0
unsigned char sending_byte; //當(dāng)前正在發(fā)送的字節(jié)
unsigned char send_byte_p; //已發(fā)送字節(jié)數(shù)(含正在發(fā)送的字節(jié))
unsigned char send_bit_p; //當(dāng)前正在發(fā)送的字節(jié)已發(fā)送位數(shù)(含正在發(fā)送的位)
#define SEND_PROGRESSING 0x41
#define SEND_FAILED 0x21
#define SEND_SUCCESS 0x31
unsigned char send_stat = 0; //發(fā)送程序當(dāng)前狀態(tài),為0時(shí)正常
unsigned char head_counts; //前導(dǎo)信號(hào)計(jì)數(shù)器(包括引導(dǎo)信號(hào))
void start_send(){
send_byte_p = 0;
send_bit_p = 0;
send_stat = SEND_PROGRESSING;
head_counts = 16;
}
#define START_SEND(byts) send_buf[0]=byts;send_byts=byts;start_send()
//發(fā)送前應(yīng)清除send_byte_p,send_bit_p,send_stat,并設(shè)置send_byts
//發(fā)送過(guò)程中可根據(jù)send_byts的值得到剩余字節(jié)數(shù),根據(jù)send_byte_p的值得到已發(fā)送字節(jié)數(shù).注意,將正在發(fā)送的字節(jié)當(dāng)作已發(fā)送完畢.
//發(fā)送過(guò)程中可根據(jù)send_stat的值得到發(fā)送狀態(tài).
//發(fā)送完成后,send_byts和send_bit_p的值都為0.
#define SEND_PULS(x) w_data=send_busy=(x>>1)
void send(){
//下面兩行在wirless()中已經(jīng)執(zhí)行過(guò)了,所以無(wú)需寫(xiě)上
// if (send_stat != SEND_PROGRESSING)
// return;
if (!send_busy){
if(send_byts || send_bit_p){
if (head_counts){
head_counts--;
if(head_counts)
SEND_PULS(PULS_HEAD_WIDTH);
else
SEND_PULS(PULS_START_WIDTH);
}else{
if (send_bit_p == 0){
sending_byte = send_buf[send_byte_p];
send_byte_p++;
send_byts--;
send_bit_p = 8;
}
if(sending_byte & 0x80){
SEND_PULS(PULS_1_WIDTH);
}else{
SEND_PULS(PULS_0_WIDTH);
}
sending_byte <<= 1;
send_bit_p--;
}
}else{
SEND_PULS(PULS_STOP_WIDTH);
send_stat = SEND_SUCCESS;
}
}
return;
}
//=============================================================
//發(fā)送程序 結(jié)束
//=============================================================
//=============================================================
//接收程序 開(kāi)始
//=============================================================
unsigned char recv_buf[16];
#define recv_byts recv_buf[0] //應(yīng)收到字節(jié)數(shù),由每個(gè)包的第一個(gè)字節(jié)指定
unsigned char recving_byte; //當(dāng)前正在接收的字節(jié)
unsigned char recv_byte_p; //已收到字節(jié)數(shù)(不含正在接收的字節(jié))
unsigned char recv_bit_p; //當(dāng)前正在接收的字節(jié)等待接收位數(shù)(不含正在接收的位)
#define RECV_FAILED 0x31
#define RECV_SUCCESS 0x41
unsigned char recv_stat = 0; //接收程序當(dāng)前狀態(tài),為0時(shí)正常
unsigned char recv_step = 0; //引導(dǎo)脈沖標(biāo)志,為0時(shí)等待引導(dǎo),為1時(shí)等待數(shù)據(jù)
#define TEST_PULS(puls_in, puls_type) (puls_in > puls_type - PULS_0_WIDTH / 2 && puls_in < puls_type + PULS_0_WIDTH / 2)
#define HEAD_NEED_RECIVED 8
void recv(){
unsigned puls_width;
if ((recv_stat == RECV_SUCCESS) || !w_data)
return;
puls_width = w_data;
w_data = 0;
#if 0 //輸出脈寬
serial_out(puls_width);
// printhex(puls_width);
#endif
if (recv_step < HEAD_NEED_RECIVED){
if(TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
recv_step++;
}else{
recv_step = 0;
}
}else if (recv_step == HEAD_NEED_RECIVED){
if(TEST_PULS(puls_width, PULS_START_WIDTH)){
serial_out(0xbb);
recv_byte_p = 0;
recv_bit_p = 8;
recv_stat = 0;
recv_step++;
}else{
if(!TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
recv_step = 0;
}
}
}else{
//serial_out(puls_width);
recving_byte <<= 1;
if(TEST_PULS(puls_width, PULS_0_WIDTH)){
recving_byte &= 0xfe;
}else if(TEST_PULS(puls_width, PULS_1_WIDTH)){
recving_byte |= 1;
}else{
serial_out(puls_width);
recv_step = 0;
serial_out(0xaa);
return;
}
recv_bit_p--;
if(recv_bit_p == 0){ //接收完一字節(jié)
recv_bit_p = 8;
// serial_out(recving_byte); //輸出接收到的字符
recv_buf[recv_byte_p] = recving_byte;
recv_byte_p++;
if(recv_byte_p == recv_byts){
recv_step = 0;
recv_stat = RECV_SUCCESS;
}
}
}
}
//=============================================================
//接收程序 結(jié)束
//=============================================================
#define SEND_DELAY_TIME 20 //防碰撞延遲(單位:毫秒)
unsigned char send_delay = SEND_DELAY_TIME;
#define VALID_PULS_COUNT 10
unsigned char valid_puls_counts = VALID_PULS_COUNT;
//碰撞檢測(cè)在該函數(shù)中實(shí)現(xiàn).由于無(wú)線模塊本身的限制,碰撞檢測(cè)為非完全檢測(cè),只能在發(fā)送前
//檢測(cè)是否有其它單元在使用信道,在發(fā)送過(guò)程中受到的碰撞干擾是無(wú)法檢測(cè)到的.經(jīng)測(cè)試,效果還行
void wirless(){
if (send_stat == SEND_PROGRESSING && send_delay == 0){
send();
if (send_stat == SEND_SUCCESS)
send_delay = SEND_DELAY_TIME;
}else{
recv();
if (recv_step > HEAD_NEED_RECIVED) //如果檢測(cè)到當(dāng)前有其它單元正在發(fā)送,繼續(xù)等待
send_delay = SEND_DELAY_TIME;
else{
if(TEST_PULS(w_data, PULS_0_WIDTH) //如果檢測(cè)到當(dāng)前有其它單元正在發(fā)送,繼續(xù)等待
|| TEST_PULS(w_data, PULS_1_WIDTH)
//|| TEST_PULS(w_data, PULS_HEAD_WIDTH)
|| TEST_PULS(w_data, PULS_START_WIDTH)
//|| TEST_PULS(w_data, PULS_STOP_WIDTH)
){
if (valid_puls_counts)
valid_puls_counts--;
else
send_delay = SEND_DELAY_TIME;
}else{
valid_puls_counts = VALID_PULS_COUNT;
}
}
}
}
#define SCMD_SET_PORT 0x51
#define SCMD_GET_PORT 0x52
#define SCMD_RESET 0x61
#define SCMD_LCD_OUTSTR 0x71
#define SCMD_LCD_RESET 0x72
#define SCMD_LCD_SETXY 0x73
#define SCMD_LCD_SETLINE 0x74
#define SCMD_LCD_CLEAR 0x75
#define SRESP_GET_PORT_ERROR 0x41
#define SRESP_SET_PORT_ERROR 0x42
#define HEART_BEAT_INTERVAL 100 //心跳間隔 X / 1000 秒
unsigned int heart_beat_timer = HEART_BEAT_INTERVAL;
unsigned int last_jiffies=0;
void main(){
init_serialcomm();
//P0=0xff;
//P2=0x00; ;
sys_init();
LED1 = 0;
LED2 = 1;
//send_string_com("ok",2);
//lcd_reset();
//lcd_power_on();
//lcd_self_test();
while(1){
if (jiffies - last_jiffies >= 50){//每次中斷為50us,所以要20次才為1ms
last_jiffies = jiffies;
heart_beat_timer--;
if (send_stat == 0 ){// 碰撞測(cè)試
ET0=0;
ReadTemperature();
clock_init_again();
START_SEND(8);
send_buf[1]=Te/10+0x30;
send_buf[2]=Te%10+0x30;
send_buf[3]='.';
send_buf[4]=Te_D/10+0x30;
send_buf[5]=(Te_D%10)+0x30;
send_buf[6]='D';
send_buf[7]='\0';
//wirless();
//send_string_com(send_buf,strlen(send_buf));
}
if (send_delay)
send_delay--;
}
if (heart_beat_timer == 0){
heart_beat_timer = HEART_BEAT_INTERVAL;
LED1 = ~LED1;
LED2 = ~LED2;
}
wirless();
if (send_stat == SEND_FAILED){
send_stat = 0;break;
}else if (send_stat == SEND_SUCCESS){
send_stat = 0;
P2_3=~P2_3;break;
}
}
}