下面给大家整理下315M无线模块的接收程序

315m无线模块怎么接收程序以及程序代码-LMLPHP

#include <AT89X52.H>



#include "string.h"



//液晶块



#define LCM_RW P3_6 //定义引脚



#define LCM_RSP3_5



#define LCM_E P3_7



#define LCM_Data P1



#define Busy 0x80 //用于检测LCM状态字中的Busy标识



typedef int byte;



typedef unsigned int word;



void Read_Temp(void);



void mychar(char,char);



void WriteDataLCM(unsigned char WDLCM);



void WriteCommandLCM(unsigned char WCLCM,BuysC);



unsigned char ReadDataLCM(void);



unsigned char ReadStatusLCM(void);



void LCMInit(void);



void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);



void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);



void Delay5Ms(void);



void Delay400Ms(void);



void delay(word useconds)



{



for(;useconds>0;useconds--);



}



void mychar(char xx,char yy)



{



DisplayOneChar(0,0,0x54);



DisplayOneChar(1,0,0x65);



DisplayOneChar(2,0,0x6D);



DisplayOneChar(3,0,0x70);



DisplayOneChar(4,0,0x65);



DisplayOneChar(5,0,0x72);



DisplayOneChar(6,0,0x61);



DisplayOneChar(7,0,0x74);



DisplayOneChar(8,0,0x75);



DisplayOneChar(9,0,0x72);



DisplayOneChar(10,0,0x65);



DisplayOneChar(11,0,0x3A);



///自定义字符



WriteCommandLCM(0x48, 0); //第一行



WriteDataLCM(0x06);



WriteCommandLCM(0x49, 0); //第2行



WriteDataLCM(0x09);



WriteCommandLCM(0x4a, 0); //第3



WriteDataLCM(0x09);



WriteCommandLCM(0x4b, 0); //第4



WriteDataLCM(0x06);



WriteCommandLCM(0x4c, 0); //第5



WriteDataLCM(0x00);



WriteCommandLCM(0x4d, 0); //第6



WriteDataLCM(0x00);



WriteCommandLCM(0x4e, 0); //第7



WriteDataLCM(0x00);



WriteCommandLCM(0x4f, 0); //第8



WriteDataLCM(0x00);



DisplayOneChar(xx,yy,0x01);



DisplayOneChar(xx+1,yy,0x43);



}



//写数据



void WriteDataLCM(unsigned char WDLCM)



{



ReadStatusLCM(); //检测忙



LCM_Data = WDLCM;



LCM_RS = 1;



LCM_RW = 0;



LCM_E = 0; //若晶振速度太高可以在这后加小的延时



LCM_E = 0; //延时



LCM_E = 1;



}



//写指令



void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测



{



if (BuysC) ReadStatusLCM(); //根据需要检测忙



LCM_Data = WCLCM;



LCM_RS = 0;



LCM_RW = 0;



LCM_E = 0;



LCM_E = 0;



LCM_E = 1;



}



//读状态



unsigned char ReadStatusLCM(void)



{



LCM_Data = 0xFF;



LCM_RS = 0;



LCM_RW = 1;



LCM_E = 0;



LCM_E = 0;



LCM_E = 1;



while (LCM_Data & Busy); //检测忙信号



return(LCM_Data);



}



void LCMInit(void) //LCM初始化



{



LCM_Data = 0;



WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号



Delay5Ms();



WriteCommandLCM(0x38,0);



Delay5Ms();



WriteCommandLCM(0x38,0);



Delay5Ms();



WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号



WriteCommandLCM(0x08,1); //关闭显示



WriteCommandLCM(0x01,1); //显示清屏



WriteCommandLCM(0x06,1); // 显示光标移动设置



WriteCommandLCM(0x0C,1); // 显示开及光标设置



}



//按指定位置显示一个字符



void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)



{



Y &= 0x1;



X &= 0xF; //限制X不能大于15,Y不能大于1



if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;



X |= 0x80; //算出指令码



WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码



WriteDataLCM(DData);



}



//按指定位置显示一串字符 ***原来的遇到空格0x20就不显示***



void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)



{



unsigned char ListLength,j;



ListLength = strlen(DData);



Y &= 0x1;



X &= 0xF; //限制X不能大于15,Y不能大于1



if (X <= 0xF) //X坐标应小于0xF



{



for(j=0;j<ListLength;j++)



{



DisplayOneChar(X, Y, DData[j]); //显示单个字符



X++;



}



}



}



//5ms延时



void Delay5Ms(void)



{



unsigned int TempCyc = 5552;



while(TempCyc--);



}



//400ms延时



void Delay400Ms(void)



{



unsigned char TempCycA = 5;



unsigned int TempCycB;



while(TempCycA--)



{



TempCycB=7269;



while(TempCycB--);



};



}



sbit W_IN = P2^1;



sbit W_OUT = P2^0;



unsigned char w_data; //接收时用于存储两次上升沿之间的时长,发送时存储前半周



unsigned char send_busy = 0;//存储发送时后半周



unsigned char recv_TImer = 0;



bit w_stat, last_w_stat;



unsigned char jiffies=0;



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++;



}



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 init_serialcomm(void)



{



SCON = 0x50; //SCON: serail mode 1, 8-bitUART, 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(unsigned char d){



while(!TI);



TI=0;



SBUF=(d);



}



void send_string_com(unsigned char *str,int strlen)//串口程序



{ unsigned char sum;



unsigned char k=0;



//serial_out(02);



do



{ //sum^=*(str+k);



serial_out(*(str + k));



//serial_out('a');



k++;



} while(k < strlen);



//serial_out(sum);



//serial_out('e');



}



//等待指定长度的串行数据到达,超时值为每两个字节之间的间隔时间而非等待整个串的时间.



//超时单位为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();



}



//=============================================================



//发送程序 开始



//=============================================================



#define PULS_0_WIDTH 8 //低电平脉宽



#define PULS_1_WIDTH 16 //高电平脉宽



#define PULS_HEAD_WIDTH 8 //前导信号脉宽



#define PULS_START_WIDTH 24 //引导信号脉宽



#define PULS_STOP_WIDTH 8 //结束码脉宽



#define PULS_HEAD_COUNTS 16 //前导信号长度



unsigned char send_buf[16];



#define send_byts send_buf[0] //剩余字节数,发送完后为0



unsigned char sending_byte; //当前正在发送的字节



unsigned char send_byte_p; //已发送字节数(含正在发送的字节)



unsigned char send_bit_p; //当前正在发送的字节已发送位数(含正在发送的位)



#define SEND_PROGRESSING 0x41



#define SEND_FAILED 0x21



#define SEND_SUCCESS 0x31



unsigned char send_stat = 0; //发送程序当前状态,为0时正常



unsigned char head_counts; //前导信号计数器(包括引导信号)



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()



//发送前应清除send_byte_p,send_bit_p,send_stat,并设置send_byts



//发送过程中可根据send_byts的值得到剩余字节数,根据send_byte_p的值得到已发送字节数.注意,将正在发送的字节当作已发送完毕.



//发送过程中可根据send_stat的值得到发送状态.



//发送完成后,send_byts和send_bit_p的值都为0.



#define SEND_PULS(x) w_data=send_busy=(x>>1)



void send(){



//下面两行在wirless()中已经执行过了,所以无需写上



// 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;



}



//=============================================================



//发送程序 结束



//=============================================================



//=============================================================



//接收程序 开始



//=============================================================



unsigned char recv_buf[16];



#define recv_byts recv_buf[0] //应收到字节数,由每个包的第一个字节指定



unsigned char recving_byte; //当前正在接收的字节



unsigned char recv_byte_p; //已收到字节数(不含正在接收的字节)



unsigned char recv_bit_p; //当前正在接收的字节等待接收位数(不含正在接收的位)



#define RECV_FAILED 0x31



#define RECV_SUCCESS 0x41



unsigned char recv_stat = 0; //接收程序当前状态,为0时正常



unsigned char recv_step = 0; //引导脉冲标志,为0时等待引导,为1时等待数据



#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){ //接收完一字节



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;



}



}



}



}



//=============================================================



//接收程序 结束



//=============================================================



#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;



//碰撞检测在该函数中实现.由于无线模块本身的限制,碰撞检测为非完全检测,只能在发送前



//检测是否有其它单元在使用信道,在发送过程中受到的碰撞干扰是无法检测到的.经测试,效果还行



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) //如果检测到当前有其它单元正在发送,继续等待



send_delay = SEND_DELAY_TIME;



else{



if(TEST_PULS(w_data, PULS_0_WIDTH) //如果检测到当前有其它单元正在发送,继续等待



|| 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;



}



}



}



}



void Display_T()



{



DisplayOneChar(9,1,recv_buf[5]);



DisplayOneChar(8,1,recv_buf[4]);



DisplayOneChar(7,1,recv_buf[3]);



DisplayOneChar(6,1,recv_buf[2]);



DisplayOneChar(5,1,recv_buf[1]);



DisplayOneChar(0,0,0x54);



}



#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 200 //心跳间隔 X / 1000 秒



unsigned int heart_beat_timer = HEART_BEAT_INTERVAL;



unsigned int last_jiffies=0;



void main(){



Delay400Ms(); //启动等待,等LCM讲入工作状态



LCMInit(); //LCM初始化



Delay5Ms(); //延时片刻(可不要)



mychar(10,1); //显示 自定义字符



init_serialcomm();



P0=0x0ff;



P2=0x00;



sys_init();



//send_string_com("ok",2);



//lcd_reset();



//lcd_power_on();



//lcd_self_test();



while(1){



if (jiffies - last_jiffies >= 20){//每次中断为50us,所以要20次才为1ms



last_jiffies = jiffies;



heart_beat_timer--;



if (send_delay)



send_delay--;



}



if (heart_beat_timer == 0){



heart_beat_timer = HEART_BEAT_INTERVAL;



while(1) {recv();if (recv_stat == RECV_SUCCESS)



{



P0_0=~P0_0;



send_string_com(recv_buf,strlen(recv_buf));



Display_T();



recv_stat = 0;break;}



recv_stat = 0;



}



}



/*#if 0



if (send_stat == 0){



//碰撞测试



START_SEND(8);



send_buf[1]='T';



send_buf[2]='e';



send_buf[3]='s';



send_buf[4]='t';



send_buf[5]='O';



send_buf[6]='k';



send_buf[7]='!';



lcd_out_string("sending:");



//send_string_com(send_buf,strlen(send_buf));



printhex(send_buf[0]);



printhex(send_buf[1]);



}



#endif



*/



wirless();



if (send_stat == SEND_FAILED){



send_stat = 0;



}else if (send_stat == SEND_SUCCESS){



send_stat = 0;



P2_3=~P2_3;



}



//recv();



//send_string_com("start",5);



/*while(1) {recv();if (recv_stat == RECV_SUCCESS)



{



P0_0=~P0_0;



send_string_com(recv_buf,strlen(recv_buf));} }*/



/* if (recv_stat == RECV_SUCCESS){



//send_string_com("test1",5);



#if 1



//unsigned int i;



//for(i=0; i<recv_byts; i++)



// serial_out(recv_buf[i]); //输出接收到的字符



P0_0=~P0_0;



send_string_com(recv_buf,strlen(recv_buf));



#else



//if (recv_buf[1]=='o')



//P0=0x00;



//lcd_out_string("data recived:");



//printhex(recv_buf[0]);



//printhex(recv_buf[1]);



//OutChar('\n');



//send_string_com("test3",5);



#endif



recv_stat = 0;



}



*/



#if 0



if (RI){



unsigned char scmd[17];



heart_beat_timer = HEART_BEAT_INTERVAL;



wait_serial(scmd, 1, 0);



switch(scmd[0]){



case SCMD_RESET:



((void (code *) (void))0x0000) ();//软件复位



case SCMD_SET_PORT:



if (wait_serial(scmd, 2, 200))



break;



switch(scmd[0]){



case 0:



P0 = scmd[1];



break;



case 1:



P1 = scmd[1];



break;



case 2:



P2 = scmd[1];



break;



case 3:



P3 = scmd[1];



break;



}



break;



case SCMD_GET_PORT:



if (wait_serial(scmd, 1, 200))



break;



switch(scmd[0]){



case 0:



serial_out(P0);



break;



case 1:



serial_out(P1);



break;



case 2:



serial_out(P2);



break;



case 3:



serial_out(P3);



break;



}



break;



case SCMD_LCD_OUTSTR:



if (wait_serial(scmd, 1, 200))



break;



scmd[scmd[0]] = 0;



if (wait_serial(scmd, scmd[0], 200))



break;



lcd_out_string(scmd);



break;



case SCMD_LCD_RESET:



lcd_reset();



break;



case SCMD_LCD_CLEAR:



lcd_clear();



break;



case SCMD_LCD_SETXY:



if (wait_serial(scmd, 2, 200))



break;



SetXY(scmd[0], scmd[1]);



break;



case SCMD_LCD_SETLINE:



if (wait_serial(scmd, 1, 200))



break;



SetLine(scmd[0]);



break;



default:



break;



}



}



#endif



}



}
12-22 19:00