双路7512b+at89c2051无线通信slave端源码
文章来源:http://gliethttp.cublog.cn
//-------------------------- //gliethttp_20071211 //注意:外振6M,timer0中断的代码如果比较长,需要考虑到,所执行代码可能耗费很多处理器时间 #include <reg51.h> #define uint8 unsigned char #define uint16 unsigned short
#define ___LED_MOD 2
#define DBGU_WATCH_PULS 0 #if DBGU_WATCH_PULS sbit puls_pin =P1^6; #endif struct _sr { #define _sr_max 4 #define PRE_CMD0 0x75 #define PRE_CMD1 0xa5 #define PRE_CMD2 0x55 #define PRE_CMD3 0x55 /* #define PRE_CMD0 0xff #define PRE_CMD1 0xff #define PRE_CMD2 0xff #define PRE_CMD3 0xff*/ char buf[_sr_max+4]; char *cur; uint8 len; char rcve_buf[_sr_max]; uint8 rcve_len; }; //-------------------------- sbit _S_CTRL =P3^5; sbit _LED_RUN =P1^7; sbit _LED_W =P3^7; sbit _LED_G =P1^0; sbit _G7512b_RS_pin =P1^3; sbit _G7512b_MOD1_pin =P1^2; sbit _G7512b_RD_pin =P3^2; sbit _G7512b_XD_pin =P1^4; #define _G7512b_send1() _G7512b_XD_pin = 1 #define _G7512b_send0() _G7512b_XD_pin = 0 #define _G7512b_getdata() _G7512b_RD_pin #define _G7512b_setrs(x) _G7512b_RS_pin = x
#define led_run_off() _LED_RUN = 1 #define led_run_on() _LED_RUN = 0 #define led_w_off() _LED_W = 1 #define led_w_on() _LED_W = 0 #define led_g_off() _LED_G = 1 #define led_g_on() _LED_G = 0
sbit _W7512b_RS_pin =P1^5; sbit _W7512b_MOD1_pin =P1^1; sbit _W7512b_RD_pin =P3^3; sbit _W7512b_XD_pin =P3^4; #define _W7512b_send1() _W7512b_XD_pin = 1 #define _W7512b_send0() _W7512b_XD_pin = 0 #define _W7512b_getdata() _W7512b_RD_pin #define _W7512b_setrs(x) _W7512b_RS_pin = x
#define _S_CTRL2G() _S_CTRL = 0 #define _S_CTRL2W() _S_CTRL = 1 #define _C_CTRLisG() (_S_CTRL == 0)
#define _GEnable_send() \ _G7512b_setrs(0);\ _G7512b_MOD1_pin = 0
#define _GEnable_rcve() \ _G7512b_setrs(1);\ _G7512b_MOD1_pin = 1
#define _GHalt_7512b() \ _G7512b_setrs(1);\ _G7512b_MOD1_pin = 0
#define _WEnable_send() \ _W7512b_setrs(0);\ _W7512b_MOD1_pin = 0
#define _WEnable_rcve() \ _W7512b_setrs(1);\ _W7512b_MOD1_pin = 1
#define _WHalt_7512b() \ _W7512b_setrs(1);\ _W7512b_MOD1_pin = 0
//-------------------------- #define __step_waiting 1 #define __step_receiving_precode0 2 #define __step_receiving 3 #define __step_precoding 4 #define __step_sending 5 #define __step_receiving_precode1 6 #define __step_receiving_precode2 7 #define __step_receiving_precode3 8 #define __step_over 9 #define __step_erro 10 static uint8 __step = __step_waiting; static uint8 __step_pre = 0xff; bit send_rdy; bit rcve_rdy; struct _sr sr; uint16 time_ticks,hold_ticks,hold_continue_ticks; static uint8 tmp_data,rcve_data; static uint16 led_count; static uint16 chanel_line1_time_out,chanel_line2_time_out; //线路切换函数 #define chanel_line_1 1 #define chanel_line_2 2 #define chanel_line_max 2 static char chanel_line; static char chanel_line_pre; static char chanel_line_status[chanel_line_max+1]; static char chanel_line_status_pre1,chanel_line_status_pre2; //-------------------------- void env_ini(void); void var_ini(void); /*inline*/void timer0_restart(void); void recvieving_var_reset(void); //void __enable_rcve(void); void com_send_char( char cd); void com_ini(void); void com_send_string( char *string); char *__get_cur_chanel(void); void set_led_g(void); void set_led_w(void); //-------------------------- int main(void) { var_ini(); env_ini(); TR0 = 1; EX0 = 1;EX1 = 1;
com_send_string("\r\n上电启动!\r\n");
for(;;) {uint8 tmp; const char convert_table[]={'0','1','2','3','4','5','6','7','8','9','a','b'};
if(led_count < 600*4)led_run_on(); else if(led_count < 1200*4)led_run_off(); else { EA = 0; led_count = 0; EA = 1; }; tmp = chanel_line_status[chanel_line_1]; if(tmp != chanel_line_status_pre1) { chanel_line_status_pre1 = tmp; set_led_g(); } tmp = chanel_line_status[chanel_line_2]; if(tmp != chanel_line_status_pre2) { chanel_line_status_pre2 = tmp; set_led_w(); } tmp = __step; if(__step_pre != tmp) { __step_pre = tmp; tmp = chanel_line; if(tmp != chanel_line_pre) { chanel_line_pre = tmp; if(tmp == chanel_line_1)com_send_string("\r\nA "); if(tmp == chanel_line_2)com_send_string("\r\nB "); com_send_string(__get_cur_chanel()); //com_send_string("\r\n"); } com_send_char(','); com_send_char(convert_table[__step_pre]); } } }
void env_ini(void) { EA = 0; PCON = 0x00; TMOD = 0x12; timer0_restart(); recvieving_var_reset(); _S_CTRL2G();//默认光线链路
//slave添加 chanel_line = chanel_line_1; __step = __step_receiving_precode0; rcve_rdy = 1; //__enable_rcve(); _GEnable_rcve(); _WEnable_rcve();
TF1 = 0; TF0 = 0; IE1 = 0; IE0 = 0; //IT1 = 1;//下降边沿触发,具有记忆功能,导致不稳定 //IT0 = 1;//下降边沿触发,具有记忆功能,导致不稳定 IT1 = 0;//低电平中断触发,不具备记忆能力,每个clock采样 IT0 = 0;//低电平中断触发,不具备记忆能力,每个clock采样
ET0 = 1;//允许timer0进行向量中断 EX0 = 0;//禁用外部中断0进行向量中断 EX1 = 0;
IP = 0; PT0 = 1;//提高定时器0的中断优先级
com_ini(); set_led_g();//安装指示灯 set_led_w();
EA = 1; } void var_ini(void) { chanel_line1_time_out = 0; chanel_line2_time_out = 0; } void set_led_g(void) { /* if(chanel_line_status_pre1)led_g_on(); else led_g_off(); */ if(chanel_line_status_pre1)led_w_on(); else led_w_off(); } void set_led_w(void) { /* if(chanel_line_status_pre2)led_w_on(); else led_w_off(); */ if(chanel_line_status_pre2)led_g_on(); else led_g_off(); } /*inline*/ void timer0_restart(void) { //TH0=0x98;TL0=0x98; //timer0,mode2,6M晶振 TH0=0x00;TL0=0x00; } void recvieving_var_reset(void) { send_rdy = 0; rcve_rdy = 0; sr.cur = sr.buf; sr.len = 0; sr.rcve_len = 0; time_ticks = 0; hold_ticks = 0; tmp_data = 0; rcve_data= 0; /* _GHalt_7512b(); _WHalt_7512b(); */ _GEnable_rcve(); _WEnable_rcve(); } void rcve2default(void) { time_ticks = 0; rcve_data = 0; tmp_data = 0; EX0 = 0;EX1 = 0; } void send2_7512b(char *buf,uint8 len,bit ea) {uint8 i; char *to; EA = 0; recvieving_var_reset(); if(len > _sr_max)len = _sr_max; to = sr.buf; *to++ = PRE_CMD0; *to++ = PRE_CMD1; *to++ = PRE_CMD2; *to++ = PRE_CMD3; for(i = 0;i < len;i++) { *to++ = *buf++; } sr.len = len + 4; EX0 = 0;EX1 = 0;//禁止接收 send_rdy = 1; __step = __step_precoding; if(ea)EA = 1; } void __set_out_data(uint8 dat) { if(chanel_line == chanel_line_1){if(dat)_G7512b_send1();else _G7512b_send0();} else if(chanel_line == chanel_line_2){if(dat)_W7512b_send1();else _W7512b_send0();} // if(dat)_G7512b_send1(); // else _G7512b_send0(); } bit __get_in_data(void) { if(chanel_line == chanel_line_1)return _G7512b_getdata(); else if(chanel_line == chanel_line_2)return _W7512b_getdata(); } void __enable_send(void) { if(chanel_line == chanel_line_1){_GEnable_send();} else if(chanel_line == chanel_line_2){_WEnable_send();} } /* void __enable_rcve(void) { if(chanel_line == chanel_line_1){_GEnable_rcve();} else if(chanel_line == chanel_line_2){_WEnable_rcve();} } */ /* void __enable_cur_irq(void) { if(chanel_line == chanel_line_1)EX0 = 1; else if(chanel_line == chanel_line_2)EX1 = 1; } */ char *__get_cur_chanel(void) { if(_C_CTRLisG())return "g"; else return "w"; } /* void __disable_cur_irq(void) { EX0 = 0; } */ void com_ini(void) { /* SCON 7 6 5 4 3 2 1 0 SM0 SM1 SM2 REN TB8 RB8 TI RI SM0 SM1 REN TB8 0 0 方式0 1 允许接收 发送数据的第9位 0 1 方式1 0 不允许接收 RB8 1 0 方式2 RI 为1 表示接收到数据 1 1 方式3 TI 为1 表示发送数据成功 RI TI必须由软件清0 */ /* PCON 7 6 5 4 3 2 1 SMOD - - - GF1 GF0 IDL */ SCON = 0X50; TMOD &= 0x0f; TMOD |= 0X20;//定时器 选用方式2 自动重装 //串口采用方式1或3 PCON = 0x00;//SMOD=1;恢复默认值 //6M,1200 TH1 = 0xF3;TL1 = 0xF3; TR1 = 1;TI = 1; } void com_send_char( char cd) { while(!TI);TI = 0; SBUF = cd; }
void com_send_string( char *string) { while(*string != 0)com_send_char(*string++); }
#define PRE_CODING_TIME_SEND (160 ) #define PRE_CODING_TIME_RCVE (1600)//对端peer用来__switch2next_line()和send2_7512b()函数执行所花费的时间 #define RESEND_TRY_MAX_COUNT (10 ) void timer0_interrupt(void) interrupt 1 { EA = 0; //原子操作,保护共享数据区,禁止中断嵌套 if(send_rdy) { switch(__step) { case __step_precoding: {//发送导频码,信道静默 //实测:一个bit即8个ticks占用1.68ms if(time_ticks < 2) { __step = __step_precoding; //出现一个翻转,标示至少有一个电平变化,以使PRE_CODING_TIME_SEND时间内,有一个变化,以使时间记录正常 __set_out_data(sr.buf[0] & 0x80); __enable_send(); } if(time_ticks == 8) { //发送第一个数据的反位,实现翻转ext0或ext1修正 __set_out_data(!(sr.buf[0] & 0x80)); } if(time_ticks > PRE_CODING_TIME_SEND) { __step = __step_sending; time_ticks = 64; } } break; case __step_sending: {//发送数据 if(time_ticks >= 64) { if(sr.len-- == 0) { //数据发送完毕 __step = __step_receiving_precode0; send_rdy = 0; rcve_rdy = 1; sr.rcve_len = 0; tmp_data = 0; time_ticks = -1; rcve_data = 0; hold_ticks = 0; hold_continue_ticks = 0; //__enable_rcve(); //切到另一个信道检测 #if ___LED_MOD == 1 //设置建议信道,和irq结合使用 chanel_line = ( (chanel_line == chanel_line_1) ? chanel_line_2:chanel_line_1 ); #endif _GEnable_rcve(); _WEnable_rcve(); break; } time_ticks = 0; tmp_data = *sr.cur++; } if((time_ticks & 0x7) == 0) { __set_out_data(tmp_data & 0x80); tmp_data <<= 1; } } break; default: { __step = __step_erro; rcve_rdy = 0; send_rdy = 0; } break; } }else if(rcve_rdy) { if((time_ticks & 0x7) == 0x00) {//time_ticks=0时无伤大雅, rcve_data <<= 1; if(tmp_data > 4)rcve_data |= 0x01; tmp_data = 0;
#if DBGU_WATCH_PULS puls_pin = rcve_data & 0x01; #endif /* //gliethttp_20071217 修正接收不稳定bug if(__step == __step_receiving_precode0) {static uint8 gliethttp_match_array[]={0, (PRE_CMD0 >> 7)&0x01, (PRE_CMD0 >> 6)&0x01, (PRE_CMD0 >> 5)&0x01, (PRE_CMD0 >> 4)&0x01, (PRE_CMD0 >> 3)&0x01, (PRE_CMD0 >> 2)&0x01, (PRE_CMD0 >> 1)&0x01, (PRE_CMD0 >> 0)&0x01}; //assert //if(time_ticks > 64)time_ticks = 64; if((rcve_data & 0x01) != gliethttp_match_array[time_ticks >> 3]) { EX0 = 1;EX1 = 1; } } */ } if(time_ticks >= 64) { switch( __step) { case __step_receiving_precode0: {//bit do_switch = 0; #if ___LED_MOD == 1 hold_continue_ticks++; #endif
if(rcve_data == PRE_CMD0) { __step = __step_receiving_precode1; }else { EX0 = 1;EX1 = 1;
#if ___LED_MOD == 1 if( hold_continue_ticks > (PRE_CODING_TIME_RCVE / 16/*64*/) ) { //设置建议信道,和irq结合使用 hold_continue_ticks = 0; chanel_line_status[chanel_line] = 0; chanel_line = ( (chanel_line == chanel_line_1) ? chanel_line_2:chanel_line_1 ); } #endif } /* else if(rcve_data == ((PRE_CMD0 & 0x80)? 0x00:0xff)) { if(hold_continue_ticks > (((PRE_CODING_TIME_SEND / 64 )* 2) / 3)) { __enable_cur_irq(); //有可能中断一直未发生,直到hold_ticks超时 } if( hold_continue_ticks > (PRE_CODING_TIME_SEND / 64) ) do_switch = 1; }//else_disable_cur_irq();//到这,说明已经中断修正过了 else { do_switch = 1; } //gliethttp_20071212 //因为发送做了工作,所以,导频的固定电平持续时间不会大于PRE_CODING_TIME_SEND,如果是真正数据一定不会超过 if(do_switch) { //因为信号不好,导致的检测信道切换 hold_continue_ticks = 0; //chanel_line = ( (chanel_line == chanel_line_1) ? chanel_line_2:chanel_line_1 ); chanel_line = chanel_line_1; } */ } break; case __step_receiving_precode1: { if(rcve_data == PRE_CMD1) { __step = __step_receiving_precode2; }else __step = __step_receiving_precode0; } break; case __step_receiving_precode2: { if(rcve_data == PRE_CMD2) { __step = __step_receiving_precode3; }else __step = __step_receiving_precode0; } break; case __step_receiving_precode3: { if(rcve_data == PRE_CMD3) { __step = __step_receiving; }else __step = __step_receiving_precode0; } break; case __step_receiving: { #define mmmmmm_max _sr_max if(sr.rcve_len < mmmmmm_max) sr.rcve_buf[sr.rcve_len++] = rcve_data; else { __step = __step_over; rcve_rdy = 0; send_rdy = 0; } hold_ticks = 0; } break; } time_ticks = 0; tmp_data = 0; rcve_data = 0; /* if(hold_ticks++ > (PRE_CODING_TIME_RCVE / 64)) { hold_ticks = 0; chanel_line_status[chanel_line] = 0; //设置建议信道,和irq结合使用 chanel_line = ( (chanel_line == chanel_line_1) ? chanel_line_2:chanel_line_1 ); } */ #if ___LED_MOD == 2 if(chanel_line1_time_out++ > RESEND_TRY_MAX_COUNT*((PRE_CODING_TIME_SEND+PRE_CODING_TIME_RCVE) / 64)) { chanel_line1_time_out = 0; chanel_line_status[chanel_line_1] = 0; } if(chanel_line2_time_out++ > RESEND_TRY_MAX_COUNT*((PRE_CODING_TIME_SEND+PRE_CODING_TIME_RCVE) / 64)) { chanel_line2_time_out = 0; chanel_line_status[chanel_line_2] = 0; } #endif } if(__get_in_data())tmp_data++; }else { if(__step == __step_over) { send2_7512b("bj",2,0); chanel_line_status[chanel_line] = 1; if(chanel_line == chanel_line_1)chanel_line1_time_out = 0; if(chanel_line == chanel_line_2)chanel_line2_time_out = 0; if(sr.rcve_buf[0] == 'g') { _S_CTRL2G(); chanel_line_status[chanel_line_1] = 1; chanel_line1_time_out = 0; } if(sr.rcve_buf[0] == 'w') { _S_CTRL2W(); chanel_line_status[chanel_line_2] = 1; chanel_line2_time_out = 0; } }else {//异常 recvieving_var_reset(); //slave添加 __step = __step_receiving_precode0; rcve_rdy = 1; //__enable_rcve(); _GEnable_rcve(); _WEnable_rcve(); } } time_ticks++; led_count++; EA = 1; } void ext0_interrupt(void) interrupt 0 { EA = 0; //原子操作,保护共享数据区,禁止中断嵌套 if(rcve_rdy) { timer0_restart(); rcve2default(); #if ___LED_MOD == 1 hold_continue_ticks = 0; #endif chanel_line = chanel_line_1; PX0 = 0;PX1 = 1; } EA = 1; } void ext1_interrupt(void) interrupt 2 { EA = 0; //原子操作,保护共享数据区,禁止中断嵌套 if(rcve_rdy) { timer0_restart(); rcve2default(); #if ___LED_MOD == 1 hold_continue_ticks = 0; #endif chanel_line = chanel_line_2; PX0 = 1;PX1 = 0; } EA = 1; }
|