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

📄 plc.c

📁 单片PLC,AT2581实现梯形图功能,可作为参考
💻 C
📖 第 1 页 / 共 5 页
字号:
      show_ladder();
      return;
      }
   if (mouse_object == DELROW_OBJ)
      {
      null_mouse_object();
      for (r = 0; r < ladder_size; r++)
         if (rung_list[r] == rung)
            break;
      if (r != ladder_size)  /* if a "root" rung */
         delrow(r);  /* delete current rung */
      show_ladder();
      return;
      }
#endif
   null_mouse_object();
   if (rungs[rung].node[index].objindex == NULL_OBJ)
      return;
   (*objs[rungs[rung].node[index].objindex].delfn)(rungs[rung].info.u_row-scroll_baserow,rungs[rung].info.l_col+index*LADDER_ELEMENT_WIDTH,&rungs[rung].node[index]);
   rungs[rung].node[index].objindex = NULL_OBJ;
   dirty = TRUE;
   show_ladder();
   }

void clear_elements(rung)
   WORD rung;
   {
   WORD index, i;

   for (index = 0; index < ELEMENTS_PER_RUNG; index++)
      {
      rungs[rung].node[index].objindex = NULL_OBJ;
      rungs[rung].node[index].or_branch = OR_NULL;
      rungs[rung].node[index].or_parent = OR_NULL;
      rungs[rung].node[index].or_parentnode = OR_NULL;
      rungs[rung].node[index].linkstatus = AVAILABLE;
      for (i = 0; i < OPCODE_MAX; i++)
         rungs[rung].node[index].opflags[i] = UNUSED_TYPE;
      }
   rungs[rung].info.left_action = ladder_node_add;
   rungs[rung].info.right_action = ladder_node_del;
   rungs[rung].info.objindex = LADDER_OBJ;
   dirty = TRUE;
   }

void new_rung(rung,screenrow)
   WORD rung,screenrow;
   {
   WORD index;

   if (screen_index == SCREEN_MAX)
      return;
   screen_list[screen_index++] = (struct element_info *)&rungs[rung];
   rungs[rung].info.u_row = screenrow;
   rungs[rung].info.l_row = screenrow + LADDER_ROW_HEIGHT;
   rungs[rung].info.l_col = LADDER_LEFT_COL;
   rungs[rung].info.r_col = LADDER_RIGHT_COL;
   rungs[rung].num_elements = ELEMENTS_PER_RUNG;
   rungs[rung].max_elements = ELEMENTS_PER_RUNG;
   clear_elements(rung);
   used_rungs[rung] = TRUE;
   }

WORD get_rung_maxrow(rung)  /* recursive! */
   WORD rung;
   {
   WORD j, r, maxrow;

   maxrow = rungs[rung].info.l_row;
   for (j = 0; j < rungs[rung].num_elements; j++)
      {
      if (rungs[rung].node[j].or_branch != OR_NULL)
         if ((r = get_rung_maxrow(rungs[rung].node[j].or_branch)) > maxrow)
            maxrow = r;
      }
   return(maxrow);
   }

WORD get_ladder_maxrow()
   {
   return(get_rung_maxrow(rung_list[ladder_size-1]));
   }

WORD find_root_rung(root,rung)  /* recursive! */
   WORD root, rung;
   {
   WORD i;

   if (root == rung)
      return(TRUE);
   for (i = 0; i < rungs[root].num_elements; i++)
      {
      if (rungs[root].node[i].or_branch != OR_NULL)
         if (find_root_rung(rungs[root].node[i].or_branch,rung))
            return(TRUE);
      }
   return(FALSE);
   }

#ifdef BROKEN_ADD_OR_BRANCH
move_rungs_down(rung,row)  /* recursive! */
   {
   WORD i;

   for (i = 0; i < rungs[rung].num_elements; i++)
      if (rungs[rung].node[i].or_branch != OR_NULL)
         move_rungs_down(rungs[rung].node[i].or_branch,row);
   if (rungs[rung].info.l_row >= row)
      {
      rungs[rung].info.u_row += LADDER_ROW_INCREMENT;
      rungs[rung].info.l_row += LADDER_ROW_INCREMENT;
      }
   }

WORD encloses(rung,br,row,lcol,rcol)
   WORD rung, *br, row, lcol, rcol;
   {
   WORD i, branch;

   for (i = 0; i < rungs[rung].num_elements; i++)
      if ((branch = rungs[rung].node[i].or_branch) != OR_NULL)
         if ((rungs[branch].info.l_row >= row)
                   && (rungs[branch].info.l_col < lcol)
                   && (rungs[branch].info.r_col > rcol))
            {
            *br = branch;
            return(rungs[branch].info.l_row);
            }
   return(0);
   }

update_branch_spacing(rung,row,lcol,rcol)  /* recursive! */  /* update branch spacing, if needed */
   WORD rung, row, lcol, rcol;  /* rung is an index into rungs[] */
   {
   WORD i, nextr, parent, branch;

   if (rungs[rung].node[0].or_parent != OR_NULL)
      {
      if (nextr = encloses(rung,&branch,row,lcol,rcol))
         {
         if (nextr <= row)
               /* max current row on parent is too small */
            {
            move_rungs_down(branch,row);
            }
         }
      if ((parent = rungs[rung].node[0].or_parent) != OR_NULL)
         update_branch_spacing(parent,row,lcol,rcol);
      }
   else
      {
      nextr = get_rung_maxrow(rung);
      if (nextr < row)
         nextr = row;
      for (i = 0; i < ladder_size; i++)
         if (rung_list[i] == rung)
            break;
      for (i++; i < ladder_size; i++)
         {
         if (rungs[rung_list[i]].info.l_row <= nextr + LADDER_ROW_INCREMENT)
            break;
         }
      for ( ; i < ladder_size; i++)
         {
         move_rungs_down(rung_list[i],0);
         }
      }
   }

add_or_branch(rung,index)
   WORD rung, index;
   {
   WORD i, j;
   WORD root, maxr;
   WORD nextrung;

   if (rungs[rung].node[index].linkstatus != AVAILABLE)
      return;  /* already connected to an OR branch */
   if (rungs[rung].node[index].or_branch != OR_NULL)
      return;
   for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
      if (!used_rungs[nextrung])
         break;
   if (nextrung == MAX_RUNGS)  /* full, can't do anything */
      return;
   if (screen_index == SCREEN_MAX)
      return;
#ifdef NEVERDEF
   if (get_ladder_maxrow() - scroll_baserow > MAX_GRAPHICS_ROW - LADDER_ROW_INCREMENT)
      return;
#endif
   for (j = 0; j < ladder_size; j++)
      {
      root = rung_list[j];
      if (find_root_rung(root,rung))
         break;
      }
   rungs[nextrung].info.u_row = rungs[rung].info.u_row + LADDER_ROW_INCREMENT;
   rungs[nextrung].info.l_row = rungs[rung].info.l_row + LADDER_ROW_INCREMENT;
   rungs[nextrung].info.l_col = rungs[rung].info.l_col + index * LADDER_ELEMENT_WIDTH;
   rungs[nextrung].info.r_col = rungs[nextrung].info.l_col + LADDER_ELEMENT_WIDTH;
   rungs[nextrung].num_elements = 1;
   rungs[nextrung].max_elements = ELEMENTS_PER_RUNG - index;
   clear_elements(nextrung);  /* setup new rung */
   rungs[nextrung].node[0].or_parent = rung;  /* set parent */
   rungs[nextrung].node[0].or_parentnode = index;
   update_branch_spacing(rung,
                         rungs[nextrung].info.l_row,
                         rungs[nextrung].info.l_col,
                         rungs[nextrung].info.r_col);  /* update branch spacing, if needed */
   rungs[rung].node[index].or_branch = nextrung;  /* set rung link */
   rungs[rung].node[index].linkstatus = ENDLINK;  /* default: only 1 element, this must be the end */
      /* DO NOT link rung into ladder until AFTER
       * we scan rung/OR branches for position updates!
       */
#ifdef NEVERDEF
   maxr = get_rung_maxrow(root);  /* get max current row on root */
   if (maxr < rungs[nextrung].info.l_row)  /* if we need more space */
      move_rungs_down(rungs[rung].info.l_row);  /* make space for new branch */
#endif
   screen_list[screen_index++] = (struct element_info *)&rungs[nextrung];
   used_rungs[nextrung] = TRUE;
   }

#else  /* BROKEN_ADD_OR_BRANCH */

move_rungs_down(row)  /* recursive! */
   WORD row;
   {
   WORD rung;

   for (rung = 0; rung < MAX_RUNGS; rung++)
      {
      if ((used_rungs[rung]) && (rungs[rung].info.u_row > row))
          {
          rungs[rung].info.u_row += LADDER_ROW_INCREMENT;
          rungs[rung].info.l_row += LADDER_ROW_INCREMENT;
          }
      }
   }

add_or_branch(rung,index)
   WORD rung, index;
   {
   WORD i, j;
   WORD root, maxr;
   WORD nextrung;

   if (rungs[rung].node[index].linkstatus != AVAILABLE)
      return;  /* already connected to an OR branch */
   if (rungs[rung].node[index].or_branch != OR_NULL)
      return;
   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;
   if (screen_index == SCREEN_MAX)
      return;
   if (get_ladder_maxrow() - scroll_baserow > MAX_GRAPHICS_ROW - LADDER_ROW_INCREMENT)
      return;
   for (j = 0; j < ladder_size; j++)
      {
      root = rung_list[j];
      if (find_root_rung(root,rung))
         break;
      }
   maxr = get_rung_maxrow(root);  /* get max current row on root */
   rungs[rung].node[index].or_branch = nextrung;  /* set rung link */
   rungs[rung].node[index].linkstatus = ENDLINK;  /* default: only 1 element, this must be the end */
   rungs[nextrung].info.u_row = rungs[rung].info.u_row + LADDER_ROW_INCREMENT;
   rungs[nextrung].info.l_row = rungs[rung].info.l_row + LADDER_ROW_INCREMENT;
   rungs[nextrung].info.l_col = rungs[rung].info.l_col + index * LADDER_ELEMENT_WIDTH;
   rungs[nextrung].info.r_col = rungs[nextrung].info.l_col + LADDER_ELEMENT_WIDTH;
   rungs[nextrung].num_elements = 1;
   rungs[nextrung].max_elements = ELEMENTS_PER_RUNG - index;
   clear_elements(nextrung);  /* setup new rung */
   rungs[nextrung].node[0].or_parent = rung;  /* set parent */
   rungs[nextrung].node[0].or_parentnode = index;
   if (maxr < rungs[nextrung].info.l_row)  /* if we need more space */
      move_rungs_down(rungs[rung].info.l_row);  /* make space for new branch */
   screen_list[screen_index++] = (struct element_info *)&rungs[nextrung];
   used_rungs[nextrung] = TRUE;
   }
#endif  /* BROKEN_ADD_OR_BRANCH */

void expand_or_branch(rung,index)
   WORD rung, index;
   {
   WORD parent, parentnode;
   WORD expandnode;

   if (rungs[rung].num_elements == rungs[rung].max_elements)  /* full, we can't expand */
      return;
   if ((parent = rungs[rung].node[0].or_parent) == OR_NULL)
      return;  /* root rung, can't expand that! */
   parentnode = rungs[rung].node[0].or_parentnode;
   if (parentnode == rungs[parent].max_elements - 1)
      return;  /* at EOL, can't expand */
   expandnode = rungs[rung].node[0].or_parentnode + rungs[rung].num_elements - 1;
   if (expandnode == rungs[parent].num_elements-1)  /* branch runs to end of parent branch */
      return;
   if (rungs[parent].node[expandnode+1].linkstatus != AVAILABLE)
      return;
#ifdef BROKEN_ADD_OR_BRANCH
   rungs[parent].node[expandnode].linkstatus = AVAILABLE;
#else
   rungs[parent].node[expandnode].linkstatus = TAKEN;
#endif
   rungs[parent].node[expandnode+1].linkstatus = ENDLINK;
   rungs[rung].num_elements++;
   rungs[rung].info.r_col += LADDER_ELEMENT_WIDTH;
   }

void newladder(menuindex)
   WORD menuindex;
   {
   WORD rung;

   cleanup_dirty();
   erase_ladder();
   for (screen_index = 0; screen_index < NUM_MENU_ELEMENTS; screen_index++)
      screen_list[screen_index] = &menu[screen_index];
   null_mouse_object();
   ladder_size = 1;
   for (rung = 1; rung < MAX_RUNGS; rung++)
      used_rungs[rung] = FALSE;
   show_menu();
   new_rung(0,FIRST_LADDER_ROW);
   rung_list[0] = 0;   /* new rung list */
   dirty = FALSE;
   scroll_baserow = 0;
   show_ladder();
   }

void xmit_buf(buf,len)
   BYTE *buf;
   WORD len;
   {
   WORD tickcount, t, next;

   tickcount = 0;
   t = get_timer();
   while (len)
      {
      if (ok_to_send())
         {
         send_byte(*buf++);
         len--;
         }
      if (t != (next = get_timer()))
         {
         t = next;
         if (++tickcount == 36)  /* two seconds */
            break;
         }
      }
   }

void get_ack(msg)
   BYTE *msg;
   {
   BYTE answer[8];
   BYTE answerptr;
   WORD tickcount, t, next;

   answerptr = 0;
   tickcount = 0;
   t = get_timer();
   while (tickcount < 9)  /* 1/2 second */
      {
      while (in_queue_head != in_queue_tail)
         {
         if (answerptr < 8)
            answer[answerptr++] = in_queue[in_queue_tail];

⌨️ 快捷键说明

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