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

📄 plc.c

📁 单片PLC,AT2581实现梯形图功能,可作为参考
💻 C
📖 第 1 页 / 共 5 页
字号:
         in_queue_tail = (in_queue_tail + 1) & (QUEUE_SIZE-1);  /* it's a power of 2 */
         }
      if (answerptr == 5)  /* size of ACK */
         break;
      if (t != (next = get_timer()))
         {
         t = next;
         tickcount++;
         }
      }
   if ((answerptr != 5)
          || (answer[0] != MSG_BYTE0)
          || (answer[1] != MSG_BYTE1)
          || (answer[2] != MSG_ACK)
          || (answer[3] != 0)
          || (answer[4] != 0))
      {
      draw_popbox(NULL);
      cstrout(POPBOX_ROW + 2 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,msg,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
      cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Press <enter> to continue",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
      getstr(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + (3 + 25) * TEXTWIDTH, answer, 1,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
      show_ladder();
      }
   }

WORD compile_rung(rung,level,find_label_addresses)  /* recursive function! */
   WORD rung, level, find_label_addresses;
   {
   WORD i, error, len, index, branch;
   BYTE objbuf[8];  /* should only need 4 bytes */

   if (level == 0)
      {
      if (program_len < MAX_PROGRAM)
         program[program_len++] = SETLINETRUE;
      else
        return(COMPILE_PROG_TOO_BIG);
      }
   error = COMPILE_OK;
   for (index = 0; (error == COMPILE_OK) && (index < rungs[rung].num_elements); index++)
      {
      if (rungs[rung].node[index].or_branch != OR_NULL)
         {
         branch = rungs[rung].node[index].or_branch;
         if (program_len < MAX_PROGRAM)
            program[program_len++] = PUSHLINETRUE;
         else
            return(COMPILE_PROG_TOO_BIG);
         }
      if (rungs[rung].node[index].objindex == NULL_OBJ)
         {
         error = COMPILE_OK;
         len = 0;  /* blank node, ignore it */
         }
      else
         {
         if ((error = (*objs[rungs[rung].node[index].objindex].compilefn)(&rungs[rung].node[index],&len,objbuf)) != COMPILE_OK)
            {
            if ((error == COMPILE_UNKNOWN_ADDR) && (find_label_addresses))
               error = COMPILE_OK;  /* ignore this error first pass */
            else
               {
               (*objs[rungs[rung].node[index].objindex].drawfn)(rungs[rung].info.u_row-scroll_baserow,rungs[rung].info.l_col+TEXTWIDTH+index*LADDER_ELEMENT_WIDTH,&rungs[rung].node[index],BLACK,RED);
               return(error);
               }
            }
         }
      if ((program_len + len) >= MAX_PROGRAM)
         return(COMPILE_PROG_TOO_BIG);
      for (i = 0; i < len; i++, program_len++)
         {
         program[program_len] = objbuf[i];
         }
      if (rungs[rung].node[index].linkstatus == ENDLINK)
         {
         if (program_len < MAX_PROGRAM)
            program[program_len++] = ORBRANCH;
         else
            return(COMPILE_PROG_TOO_BIG);
         if ((error = compile_rung(branch,level+1,find_label_addresses)) != COMPILE_OK)
            {
            if ((error == COMPILE_UNKNOWN_ADDR) && (find_label_addresses))
               error = COMPILE_OK;  /* ignore this error first pass */
            else
               return(error);
            }
         }  /* if (... == ENDLINK) */
      }  /* for (index = 0; ...) */
   if (level)
      {
      if (program_len < MAX_PROGRAM)
         program[program_len++] = ORPOPLINETRUE;
      else
         return(COMPILE_PROG_TOO_BIG);
      }
   return(COMPILE_OK);
   }

void compile_error(error)
   WORD error;
   {
   BYTE answer[8];

   draw_popbox("Ladder program error:");
   switch (error)
      {
      case COMPILE_UNKNOWN_PARAMS:
         cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Node parameters not set",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
         break;
      case COMPILE_DUP_ADDR:
         cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Duplicate label",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
         break;
      case COMPILE_PROG_TOO_BIG:
         sprintf(tempstr,"Program too big %d ",program_len);
         cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,tempstr,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
         break;
      }
   cstrout(POPBOX_ROW + 6 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Press <enter> to continue",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
   getstr(POPBOX_ROW + 6 * TEXTHEIGHT, POPBOX_COL + (3 + 25) * TEXTWIDTH, answer, 1,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
   show_ladder();
   }

void download(menuindex)
   WORD menuindex;
   {
   WORD i;
   WORD chksum;
   WORD root;
   WORD error;
   BYTE answer[8];

   null_mouse_object();
   for (i = 0; i < NUM_LABELS; i++)
      label_addresses[i] = NULL_LABEL;
      /* Pass 1:  find label addresses */
   program_len = 0;
   error = COMPILE_OK;
   for (root = 0; (error == COMPILE_OK) && (root < ladder_size); root++)
      {
      error = compile_rung(rung_list[root],0,TRUE);  /* TRUE = find label addreses */
      }
   if (error != COMPILE_OK)
      return(compile_error(error));
      /* Pass 2:  generate final code */
   program_len = 0;
   error = COMPILE_OK;
   for (root = 0; (error == COMPILE_OK) && (root < ladder_size); root++)
      {
      error = compile_rung(rung_list[root],0,FALSE);  /* FALSE = label addreses should be known */
      }
   if (error != COMPILE_OK)
      return(compile_error(error));
   for (chksum = 0, i = 0; i < program_len; i++)
      chksum += program[i];
   tempstr[0] = MSG_BYTE0;
   tempstr[1] = MSG_BYTE1;
   tempstr[2] = MSG_PROGRAM;
   tempstr[3] = (program_len + 2) & 0xff;
   tempstr[4] = (program_len + 2) >> 8;
   xmit_buf(tempstr,5);
   xmit_buf(program,program_len);
   tempstr[0] = chksum & 0xff;
   tempstr[1] = chksum >> 8;
   xmit_buf(tempstr,2);
   get_ack("Download failure (comm error?)");
   }

void onestep(menuindex)
   WORD menuindex;
   {
   null_mouse_object();
   beep();
   }

void linestep(menuindex)
   WORD menuindex;
   {
   null_mouse_object();
   beep();
   }

void run(menuindex)
   WORD menuindex;
   {
   BYTE answer[8];

   null_mouse_object();
   tempstr[0] = MSG_BYTE0;
   tempstr[1] = MSG_BYTE1;
   tempstr[2] = MSG_RUN;
   tempstr[3] = 0;
   tempstr[4] = 0;
   xmit_buf(tempstr,5);
   get_ack("RUN failure (comm error?)");
   }

void stop(menuindex)
   WORD menuindex;
   {
   BYTE answer[8];

   null_mouse_object();
   tempstr[0] = MSG_BYTE0;
   tempstr[1] = MSG_BYTE1;
   tempstr[2] = MSG_STOP;
   tempstr[3] = 0;
   tempstr[4] = 0;
   xmit_buf(tempstr,5);
   get_ack("STOP failure (comm error?)");
   }

#ifdef SIMPLE_ADDROW
void addrow(menuindex)
   WORD menuindex;
   {
   WORD maxr;
   WORD nextrung;

   null_mouse_object();
   for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
      if (!used_rungs[nextrung])
         break;
   if ((nextrung == MAX_RUNGS)  /* full, can't do anything */
              || (ladder_size == MAX_LADDER))
      return;
   new_rung(nextrung,maxr + LADDER_ROW_INCREMENT);
   rung_list[ladder_size++] = nextrung;
   show_ladder();
   }

void delrow(menuindex)
   WORD menuindex;
   {
   null_mouse_object();
   beep();
   }

#else  /* SIMPLE_ADDROW */

void appendrow(menuindex)
   WORD menuindex;
   {
   WORD maxr;
   WORD nextrung;

   null_mouse_object();
   for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
      if (!used_rungs[nextrung])
         break;
   if ((nextrung == MAX_RUNGS)  /* full, can't do anything */
              || (ladder_size == MAX_LADDER))
      return;
   maxr = get_ladder_maxrow();
   new_rung(nextrung,maxr + LADDER_ROW_INCREMENT);
   rung_list[ladder_size++] = nextrung;
   show_ladder();
   }

void addrow_spacing(rung,size)  /* recursive! */
   {
   WORD i;

   for (i = 0; i < rungs[rung].num_elements; i++)
      if (rungs[rung].node[i].or_branch != OR_NULL)
         addrow_spacing(rungs[rung].node[i].or_branch,size);
   rungs[rung].info.u_row += size;
   rungs[rung].info.l_row += size;
   }

void addrow(index)  /* index into rung_list[] */
   WORD index;
   {
   WORD maxr, nextrung, i;

   for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
      if (!used_rungs[nextrung])
         break;
   if ((nextrung == MAX_RUNGS)  /* full, can't do anything */
              || (ladder_size == MAX_LADDER))
      return;
   maxr = get_ladder_maxrow() + LADDER_ROW_INCREMENT;
   if (index != ladder_size)  /* if not end-of-list */
      maxr = rungs[rung_list[index]].info.u_row;  /* get row we're going to replace */
   for (i = index; i < ladder_size; i++)
      addrow_spacing(rung_list[i],LADDER_ROW_INCREMENT+LADDER_ROW_HEIGHT);
   for (i = ladder_size; i > index; i--)
      rung_list[i] = rung_list[i-1];  /* move rungs logically "down" to make space */
   rung_list[i] = nextrung;
   new_rung(nextrung,maxr);
   ladder_size++;
   }

void delrow_spacing(rung,size)  /* recursive! */
   {
   WORD i;

   for (i = 0; i < rungs[rung].num_elements; i++)
      if (rungs[rung].node[i].or_branch != OR_NULL)
         delrow_spacing(rungs[rung].node[i].or_branch,size);
   rungs[rung].info.u_row -= size;
   rungs[rung].info.l_row -= size;
   }

void delrow_rungs(rung)  /* recursive! */
   {
   WORD i;

   for (i = 0; i < rungs[rung].num_elements; i++)
      if (rungs[rung].node[i].or_branch != OR_NULL)
         delrow_rungs(rungs[rung].node[i].or_branch);
   used_rungs[rung] = FALSE;
   }

void delrow(index)
   WORD index;
   {
   WORD spacing, i;

   if (ladder_size == 1)
      return;  /* can't completely empty the ladder! */
   spacing = 0;
   if (index < ladder_size - 1)
      {
      spacing = rungs[rung_list[index+1]].info.l_row - rungs[rung_list[index]].info.l_row;
           /* get "moveup" size */
      }
   delrow_rungs(rung_list[index]);
   for (i = index; i < ladder_size - 1; i++)
      {
      rung_list[i] = rung_list[i+1];
      delrow_spacing(rung_list[i],spacing);
      }
   ladder_size--;
   }
#endif  /* SIMPLE_ADDROW */

void pickup(menuindex)
   WORD menuindex;
   {
   null_mouse_object();
   mouse_object = screen_list[menuindex].objindex;
   strcat(mouse_cursor,objs[mouse_object].label);
   strcpy(mouse_overlay," ");
   strcat(mouse_overlay,objs[mouse_object].overlay);
   }

void quit(menuindex)
   WORD menuindex;
   {
   BYTE answer[8];

   if (!quickexit)
      cleanup_dirty();
   exitflag = TRUE;
   }

show_menu()
   {
   WORD i;

   for (i = 0; i < NUM_MENU_ELEMENTS; i++)
      {
      strout(screen_list[i].u_row,screen_list[i].l_col,objs[screen_list[i].objindex].label);
      overlay(screen_list[i].u_row,screen_list[i].l_col,objs[screen_list[i].objindex].overlay);
      }
   }

void show_rung(rung,level)  /* RECURSIVE! */
   WORD rung, level;
   {
   WORD j, r, c;
   WORD i;

   r = rungs[rung].info.u_row;
   if (r < (scroll_baserow + LADDER_ROW_HEIGHT))
      return;

⌨️ 快捷键说明

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