久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

51單片機+315M無線射頻模塊接受程序

作者:佚名   來源:本站原創   點擊數:  更新時間:2013年06月07日   【字體:
用的就是那種最普通的 最便宜的 大約幾塊錢 的315兆的無線模塊接受發射,不帶解碼的,433m的程序也是一樣的不用修改



壓縮包中的內容:


上位機以及完整程序在文件夾中,大家可自己下載
地址是:http://m.zg4o1577.cn/bbs/dpj-19033-1.html

下面是接受端的源代碼:
#include <AT89X52.H>
#include "string.h"

//液晶塊
#define LCM_RW P3_6 //定義引腳
#define LCM_RS P3_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-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(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
 }
}

 

關閉窗口

相關文章

主站蜘蛛池模板: 黄色一级电影免费观看 | 亚洲人在线| 人人九九精 | 国产一级视频在线观看 | 亚洲成人三级 | 欧美一区二区三区在线免费观看 | 国产精品久久国产精品 | av一级 | 51ⅴ精品国产91久久久久久 | 一区二区三区回区在观看免费视频 | 亚洲国产成人精品在线 | 日韩免费视频 | 999热在线视频 | 欧美色综合天天久久综合精品 | 中文字幕不卡在线观看 | 中文字幕亚洲视频 | 午夜成人在线视频 | 欧美在线一区二区三区 | 精品久久久999| 午夜国产 | 激情网站 | 精品欧美一区免费观看α√ | 国产欧美精品一区二区 | 日韩成人免费 | 乱一性一乱一交一视频a∨ 色爱av | 精品三级在线观看 | 精品国产一区二区三区性色 | 国产资源在线观看 | 在线观看亚洲一区二区 | 午夜精品福利视频 | 国产欧美一区二区三区在线看 | 影音先锋中文字幕在线观看 | 国产一区二区三区在线 | 色小姐综合网 | 精品一区二区观看 | 亚洲精选一区 | 亚洲精品乱码久久久久久蜜桃91 | 日韩成人在线视频 | 在线观看国产精品视频 | 成人国产精品视频 | 成人免费看黄网站在线观看 |