⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.lst

📁 51单片机315模块双向通信代码,可直接使用.用于完成家电控制之类的小应用.
💻 LST
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V7.20   TEST                                                                  11/06/2004 03:55:45 PAGE 1   


C51 COMPILER V7.20, COMPILATION OF MODULE TEST
OBJECT MODULE PLACED IN test.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE test.c ROM(COMPACT) BROWSE DEBUG OBJECTEXTEND

line level    source

   1          #include <reg51.h>
   2          #include "string.h"
   3          
   4          
   5          sbit LED1 = P1^2;
   6          sbit LED2 = P1^4;
   7          sbit LED3 = P1^3;
   8          //sbit LED1 = P3^6;
   9          //sbit LED2 = P3^7;
  10          sbit W_IN = P3^2;
  11          sbit W_OUT = P3^4;
  12          
  13          unsigned char w_timer=0;
  14          unsigned int jiffies=0,x=0;
  15          void clock_timer(void) interrupt 1 using 1{
  16   1              jiffies++;
  17   1              //if(x++==500){x=0;
  18   1              w_timer++;//};
  19   1      }
  20          
  21          void clock_init(void){
  22   1              jiffies = 0;
  23   1              TMOD=0x02;
  24   1      //      TH0=TL0=0x9b;//12M
  25   1      //      TH0=TL0=0x7a;//16M
  26   1      //      TH0=TL0=0x75;//16.59M
  27   1      //      TH0=TL0=0x72;//17M
  28   1      //      TH0=TL0=0x37;//24M
  29   1              TH0=TL0=0x40;//22M
  30   1              EA=1;
  31   1              ET0=1;
  32   1      
  33   1              TR0=1;
  34   1      }
  35          void init_serialcomm(void)
  36          {
  37   1          SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr 
  38   1          TMOD |= 0x20;       //TMOD: timer 1, mode 2, 8-bit reload 
  39   1          PCON |= 0x80;       //SMOD=1; 
  40   1          TH1   = 0xFF;       //Baud:4800  fosc=11.0592MHz  :f4
  41   1          //IE   |= 0x90;       //Enable Serial Interrupt 
  42   1          TR1   = 1;          // timer 1 run
  43   1              RI=0;
  44   1              TI=1; 
  45   1      }
  46          
  47          void serial_out(unsigned char d){
  48   1              while(!TI);
  49   1              TI=0;
  50   1              SBUF=(d);
  51   1      }
  52          
  53          //等待指定长度的串行数据到达,超时值为每两个字节之间的间隔时间而非等待整个串的时间.
  54          //超时单位为time_out * 100uS
  55          bit wait_serial(unsigned char *p, unsigned char len, unsigned char time_out){
C51 COMPILER V7.20   TEST                                                                  11/06/2004 03:55:45 PAGE 2   

  56   1              unsigned int time=jiffies;
  57   1              unsigned char n=0;
  58   1              do{
  59   2                      if (RI){
  60   3                              p[n++]=SBUF;
  61   3                              RI=0;
  62   3                              if(n==len)
  63   3                                      return 0;
  64   3                              time=jiffies;
  65   3                      }
  66   2              }while(jiffies-time < time_out);
  67   1              return 1;
  68   1      }
  69          
  70          #define W_LP 6  //低电平/前引导
  71          #define W_HP 12 //高电平
  72          #define W_FS 18 //引导/结束
  73          #define HEAD_CODE 100   //前导码个数
  74          
  75          #define DEBUG 0
  76          
  77          #define W_BUF_LEN 24
  78          unsigned char w_buf[W_BUF_LEN];
  79          
  80          unsigned char w_recv_step=0;
  81          unsigned char w_recv_data;
  82          unsigned char w_recv_last_time; //上一次翻转的时间
  83          unsigned char w_recv_width;     //脉冲宽度
  84          bit w_recv_status,w_recv_last_status;
  85          bit recv_over = 0;
  86          #define START_RECV() {w_recv_step=0; recv_over=0;}
  87          #define STOP_RECV() {recv_over=1;}
  88          void w_recv(void){
  89   1              //正式写程序时,应在调用该函数前就做检测,以节省时间.以下检测应删去.
  90   1              if(recv_over)
  91   1                      return;
  92   1      
  93   1              w_recv_status=W_IN;
  94   1              LED1=!w_recv_status;
  95   1      
  96   1              if (w_recv_last_status == w_recv_status){//信号脚无变化,无信号到达,直接返回,返回前仅处理超时.
  97   2                      if (w_recv_step == 0)//w_recv_step==0时无需处理超时
  98   2                              return;
  99   2                      w_recv_width = w_timer - w_recv_last_time;
 100   2                      if (w_recv_width > W_FS + W_LP/2){//超时处理
 101   3                              w_recv_step = 0;
 102   3      #if DEBUG
                                      //serial_out(0x53);
                                      //serial_out(w_recv_width);
              #endif
 106   3                      }
 107   2                      return;
 108   2              }
 109   1              w_recv_last_status = w_recv_status;//记下本次电平值
 110   1              w_recv_width = w_timer - w_recv_last_time;//如果上一个信号已完成,记录信号宽度,如果当前为第一个信号,该计算
             -结果不使用
 111   1              w_recv_last_time = w_timer;//新的信号到达,更新计时器
 112   1      
 113   1              if (w_recv_step == 0){//目前所处理的信号为第一个信号,不需作后续处理,因为无上一个信号信息.
 114   2                      w_recv_step = 1;
 115   2                      return;
 116   2              }
C51 COMPILER V7.20   TEST                                                                  11/06/2004 03:55:45 PAGE 3   

 117   1      
 118   1              //step 1: 等待前引导信号到来
 119   1              if(w_recv_step == 1){
 120   2                      if(w_recv_width > W_LP - W_LP/2 && w_recv_width < W_LP + W_LP/2)//前引导脉冲到来,宽度约为8,重复发送,直到
             -发送引导脉冲
 121   2                              w_recv_step = 2;
 122   2                      return;
 123   2              }
 124   1      
 125   1              //等待前引导信号结束及等待引导信号到来
 126   1              if(w_recv_step == 2){
 127   2                      if(w_recv_width > W_LP - W_LP/2 && w_recv_width < W_LP + W_LP/2)//前引导脉冲还未结束,等待
 128   2                              return;
 129   2                      if(w_recv_width > W_FS - W_LP/2 && w_recv_width < W_FS + W_LP/2)//引导脉冲到来,宽度约为16
 130   2                              w_recv_step = 3;
 131   2                      else{
 132   3                              w_recv_step = 0;
 133   3      #if DEBUG
                                      serial_out(0x54);
                                      serial_out(w_recv_width);
              #endif
 137   3                      }
 138   2                      return;
 139   2              }
 140   1      
 141   1              //读取一字节
 142   1              if(w_recv_step > 2 && w_recv_step < 3 + W_BUF_LEN * 8){//step 3 --- step 10: 取回8位数据
 143   2                      w_recv_data >>= 1;
 144   2              
 145   2                      if(w_recv_width > W_LP - W_LP/2 && w_recv_width < W_LP + W_LP/2)
 146   2                              w_recv_data &= 0x7f;
 147   2                      else
 148   2                      if(w_recv_width > W_HP - W_LP/2 && w_recv_width < W_HP + W_LP/2)
 149   2                              w_recv_data |= 0x80;
 150   2                      else{
 151   3                              w_recv_step = 0;
 152   3      #if DEBUG
                                      serial_out(0x56);
                                      serial_out(w_recv_width);
              #endif
 156   3                      }
 157   2                      if(((w_recv_step - 3) & 7) == 7)
 158   2                              w_buf[(w_recv_step - 3) >> 3] = w_recv_data;
 159   2              }
 160   1      
 161   1              if(w_recv_step == 3 + W_BUF_LEN * 8){//step 11 : 结束
 162   2                      if(w_recv_width > W_FS - W_LP/2 && w_recv_width < W_FS + W_LP/2)//等待结束脉冲,宽度约为20,未收到该信号则
             -为出错
 163   2                              recv_over = 1;//serial_out(0xaa);
 164   2                      else
 165   2                              serial_out(0x55);
 166   2              }
 167   1      
 168   1              w_recv_step++;
 169   1      }
 170          
 171          unsigned int w_send_step=0;
 172          unsigned char w_send_data;
 173          unsigned char w_send_last_time; //上一次翻转的时间
 174          unsigned char w_send_width;     //脉冲宽度
 175          bit send_over=1;
 176          #define START_SEND() {w_send_step=0; send_over=0;}
C51 COMPILER V7.20   TEST                                                                  11/06/2004 03:55:45 PAGE 4   

 177          #define STOP_SEND() {send_over=1;}
 178          void w_send(){
 179   1              //正式写程序时,应在调用该函数前就做检测,以节省时间.以下检测应删去.
 180   1              if(send_over)
 181   1                      return;
 182   1      
 183   1              if(w_send_step == HEAD_CODE + 2 + W_BUF_LEN * 8)//数据发送完毕
 184   1                      send_over = 1;
 185   1      
 186   1              if (w_send_step == 0){
 187   2                      w_send_step = 1;
 188   2                      w_send_width = W_LP;
 189   2                      W_OUT = 0;
 190   2                      LED2 = 0;
 191   2                      return;
 192   2              }
 193   1      
 194   1              if(w_timer - w_send_last_time < w_send_width)
 195   1                      return;
 196   1      
 197   1              w_send_step++;
 198   1              w_send_last_time = w_timer;
 199   1              W_OUT = !W_OUT;
 200   1              LED2 = !LED2;
 201   1      
 202   1              if(w_send_step == HEAD_CODE)
 203   1                      w_send_width = W_FS;
 204   1      
 205   1              if(w_send_step > HEAD_CODE && w_send_step < HEAD_CODE + 1 + W_BUF_LEN * 8){
 206   2                      if(((w_send_step - (HEAD_CODE + 1)) & 7) == 0)
 207   2                              w_send_data = w_buf[(w_send_step - (HEAD_CODE + 1)) >> 3];
 208   2                      if(w_send_data & 1)
 209   2                              w_send_width = W_HP;
 210   2                      else
 211   2                              w_send_width = W_LP;
 212   2                      w_send_data >>= 1;
 213   2              }
 214   1      
 215   1              if(w_send_step == HEAD_CODE + 1 + W_BUF_LEN * 8)
 216   1                      w_send_width = W_FS;
 217   1      
 218   1      }
 219          
 220          sys_init(){
 221   1              clock_init();
 222   1              init_serialcomm();
 223   1      }
 224          
 225          //pdata unsigned char this_node_id = 0x11;
 226          unsigned char this_node_id = 0x11;
 227          
 228          typedef struct pack_head_s{
 229                  unsigned char source_id;
 230                  unsigned char target_id;
 231                  unsigned char package_len;
 232                  unsigned char check_sum;
 233          }package_head_t;
 234          typedef struct package_s{
 235                  package_head_t head;
 236                  unsigned char package_data[1];
 237          }package_t;
 238          
C51 COMPILER V7.20   TEST                                                                  11/06/2004 03:55:45 PAGE 5   

 239          //发送函数返回值
 240          #define ERROR_SEND_BUSY 0x10    //前一次发送未完成
 241          #define ERROR_SEND_NULL 0x23            //发送包长为0,错误包
 242          
 243          //接收函数返回值
 244          #define ERROR_RECV_EMPTY 0x20   //当前未收到数据
 245          #define ERROR_RECV_CHECKSUM 0x21        //校验和错误
 246          #define ERROR_RECV_NULL 0x22            //收到包长为0,错误包
 247          
 248          
 249          //由于计算校验合会占用大量时间,因此在调用该函数时接收程序后台部分会受影响,可能造成正在接收的数据报文丢失.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -