基于processing的FPGA I/O调试界面笔记

基于processing的FPGA I/O调试界面笔记


笔记记录
运行软件:processing 4.1.3
功能1:自动模式,采集FPGA IO状态,展示FPGA IO的输入输出状态
功能2:手动模式,点击界面相应的引脚图标,可强制设置IO的输入输出电平

import processing.serial.*;
import controlP5.*;
ControlP5 cp5;
DropdownList serialPortsList;
//Serial serialPort;
String[] portNames;

//String portName = "COM20";
final int BAUD_RATE = 115200;

boolean send_flag=false;

Serial myPort;  // 声明Serial端口对象
PImage img;

int []x=new int[160];
int []do_index=new int[64];
int []mode_ctrl=new int[8];
void setup() {
  // 列出所有可用的串口
  size(1000, 1080);
  img = loadImage("emcc70.png");
  background(255);
  textSize(12); // 设置字体大小
  textAlign(CENTER);

  portNames = Serial.list();
  cp5 = new ControlP5(this);   // create a DropdownList
  
  serialPortsList = cp5.addDropdownList("serial ports").setPosition(900, 30).setWidth(80).setHeight(200);
  serialPortsList.clear();
  for (int i = 0; i < portNames.length; i++) serialPortsList.addItem(portNames[i], i);

  //myPort = new Serial(this, portName, BAUD_RATE);
  for (int i=0; i<64; i++) {
    x[i] = 0;
  }
}

int di_button_x = 700;
int di_button_y = 20;

int do_button_x = 150;
int do_button_y = 20;

int []rec_value=new int[21];
int []send_value=new int[12];
boolean dataVld=false;
int sendData1;
int sendData2;

int mouseReleased_x = 0;
int mouseReleased_y = 0;

boolean autoManual = true; // 按钮的状态,初始设置为未按下
//boolean diCtrlAuto=true;
//boolean doCtrlAuto=true;
String selectPortName=" ";
boolean portOpen_status = true;
void controlEvent(ControlEvent theEvent) {
  // DropdownList is of type ControlGroup.
  // A controlEvent will be triggered from inside the ControlGroup class.
  // therefore you need to check the originator of the Event with
  // if (theEvent.isGroup())
  // to avoid an error message thrown by controlP5.
  if (theEvent.isGroup()) {     // check if the Event was triggered from a ControlGroup
    //check if there's a serial port open already, if so, close it
    println("event from group : "+theEvent.getGroup().getValue()+" from "+theEvent.getGroup());
    if (myPort != null) {
      myPort.stop();
      myPort = null;
    }     //open the selected core
    selectPortName =portNames.toString();
    println("portName:"+selectPortName);
    try {
      myPort = new Serial(this, selectPortName, BAUD_RATE);
    }
    catch(Exception e) {
      System.err.println("Error opening serial port " + selectPortName);
      e.printStackTrace();
    }
  } else if (theEvent.isController()) {
    selectPortName = portNames[int(theEvent.getController().getValue())];
    println("event from controller : "+ selectPortName +" from "+theEvent.getController());

    try {
      myPort = new Serial(this, selectPortName, BAUD_RATE);
      portOpen_status = true;
    }
    catch(Exception e) {
      portOpen_status = false;
      System.err.println("Error opening serial port " + selectPortName);
      e.printStackTrace();
    }
  }
}

void draw() {
  background(#D4FCF9);
  image(img, 128, -20, 700, height);
  if (portOpen_status==false) {
    textSize(24); // 设置字体大小
    fill(255, 0, 0);
    text("Error:", 920, 310);
    text(selectPortName, 920, 340);
    text("Open Failed!", 920, 370);
    textSize(12); // 设置字体大小
  }

  text("BAUD_RATE:"+BAUD_RATE, 940, 20);
  // ----------------- UART I/O status process -----------------
  if (dataVld) {
    dataVld = false;

    for (int p=0; p<rec_value.length; p++) {
      String t = binary(rec_value[p], 8);
      if (p==20) {
        for (int q=0; q<8; q++) {
          mode_ctrl[q] = t.charAt(7-q)-'0';
        }
      } else if (p<12) {
        for (int q=0; q<8; q++) {
          x[q+p*8] = t.charAt(7-q)-'0';
        }
      } else {
        for (int q=0; q<8; q++) {
          do_index[q+(p-12)*8] = t.charAt(7-q)-'0';
        }
      }
    }
    if (send_flag) {
      send_flag = false;
      byte [] dataSend = {byte(sendData1), byte(sendData2)};
      myPort.write(dataSend);
      println("sendData1 is:"+sendData1+";"+"sendData1 is:"+sendData2);
    }
  }


  // --------------------- DI I/O process -------------------

  di_dis_rect_16(820, 230, 0);
  di_dis_rect_16(820, 390, 1);
  di_dis_rect_16(820, 550, 2);
  di_dis_rect_16(820, 710, 3);
  di_dis_rect_16(820, 860, 4);
  di_dis_rect_16(820, 1010, 5);

  //di_dis_16(830, 250, 0);
  //di_dis_16(900, 400, 1);
  //di_dis_16(830, 550, 2);
  //di_dis_16(900, 700, 3);
  //di_dis_16(830, 850, 4);
  //di_dis_16(900, 1000, 5);

  // --------------------- DO I/O process -------------------
  do_dis_rect_16(110, 110, 0);
  do_dis_rect_16(110, 270, 1);
  do_dis_rect_16(110, 430, 2);
  do_dis_rect_16(110, 590, 3);

  //do_dis_16(105, 60, 0);
  //do_dis_16(40, 200, 1);
  //do_dis_16(105, 360, 2);
  //do_dis_16(40, 500, 3);
  led_blink(10, 50);

  diModeChange(di_button_x, di_button_y);
  doModeChange(do_button_x, do_button_y);
  fill(0);
  text("Mouse X: " + mouseX, 40, 20);
  text("Mouse Y: " + mouseY, 40, 40);
  //do_dis_rect_16(mouseX, mouseY, 0);
  //rect(mouseX, mouseY, 20, 40);
}

void di_dis_rect_16(int l_x, int l_y, int group) {
  for (int i=0; i<16; i++) {
    int index = group*16+i;
    if (x[index]==1) {
      fill(8, 255, 253);
    } else {
      fill(255);
    }
    int dis_x = l_x-25*(i%2)-10;
    int dis_y = l_y-18*(i/2)-8;
    rect(dis_x, dis_y, 20, 15);
    if (mode_ctrl[0]==1) {
      if ((mouseReleased_x > dis_x && mouseReleased_x < (dis_x+20) && mouseReleased_y > dis_y && mouseReleased_y < (dis_y+15))) {
        send_flag = true;
        sendData1 = index;
        sendData2 = (x[index]==0) ? 192 : 193;  // Select di [7:6] = 2'b11
        //println("sendData1:"+sendData1+"sendData2:"+sendData2);
        mouseReleased_x = 0;
        mouseReleased_y = 0;
      }
    }

    fill(0); // 设置颜色为黑色
    text(group*16+i, l_x-25*(i%2), l_y-18*(i/2)+4); // 显示文本
  }
}


void do_dis_rect_16(int l_x, int l_y, int group) {
  for (int i=0; i<16; i++) {
    int index = group*16+i;
    if (do_index[index]==1) {
      fill(8, 255, 253);
    } else {
      fill(255);
    }

    //rect(l_x+25*(i%2)-10, l_y+18*(i/2)-8, 20, 15);
    int dis_x = l_x+25*(i%2)-10;
    int dis_y = l_y+18*(i/2)-8;
    rect(dis_x, dis_y, 20, 15);
    if (mode_ctrl[1]==1) {
      if ((mouseReleased_x > dis_x && mouseReleased_x < (dis_x+20) && mouseReleased_y > dis_y && mouseReleased_y < (dis_y+15))) {
        send_flag = true;
        sendData1 = index;
        sendData2 = (do_index[index]==0) ? 128 : 129;// Select do [7:6] = 2'b10
        //println("sendData1:"+sendData1+"sendData2:"+sendData2);
        mouseReleased_x = 0;
        mouseReleased_y = 0;
      }
    }
    fill(0); // 设置颜色为黑色
    text(group*16+i, l_x+25*(i%2), l_y+18*(i/2)+4); // 显示文本
  }
}

int MAX_CNT = 10;
int rec_cnt;
void led_blink(int l_x, int l_y) {
  if (rec_cnt>MAX_CNT/2)
    fill(#2DFF00);
  else
    fill(255, 255, 255);
  rect(l_x, l_y, 40, 20);
}

void mouseReleased() {
  //buttonState = ((mouseX > (button_x) && mouseX < (button_x+40) && mouseY > button_y && mouseY < (button_y+20)));// 当鼠标在按钮上并且按下时,切换状态
  if ((mouseX > (di_button_x) && mouseX < (di_button_x+40) && mouseY > di_button_y && mouseY < (di_button_y+20))) {
    send_flag = true;
    sendData1 = 170; // 0xAA
    sendData2 = 64+((mode_ctrl[0]==1) ? 0 : 1); // 0xFF // di mode select  [7:6] = 2'b01
    //println("sendData1:"+sendData1+"sendData2:"+sendData2);
  } else if ((mouseX > (do_button_x) && mouseX < (do_button_x+40) && mouseY > do_button_y && mouseY < (do_button_y+20))) {
    send_flag = true;
    sendData1 = 234; // 0xEA
    sendData2 = 64+((mode_ctrl[1]==1) ? 0 : 1); // 0xFA // do mode select  [7:6] = 2'b01
    //println("sendData1:"+sendData1+"sendData2:"+sendData2);
  }
  mouseReleased_x = mouseX;
  mouseReleased_y = mouseY;
  //println(mouseReleased_x, mouseReleased_y);
}
void diModeChange(int l_x, int l_y) {
  if (mode_ctrl[0]==0) {
    fill(#2DFF00);
    rect(l_x, l_y, 40, 20);
    fill(0);
    text("auto", l_x+20, l_y+15 ); // 显示文本
  } else {
    fill(255, 255, 255);
    rect(l_x, l_y, 40, 20);
    fill(0);
    text("manual", l_x+20, l_y+15 ); // 显示文本
  }
  text("DI", l_x+20, l_y-5); // 显示文本
}
void doModeChange(int l_x, int l_y) {
  if (mode_ctrl[1]==0) {
    fill(#2DFF00);
    rect(l_x, l_y, 40, 20);
    fill(0);
    text("auto", l_x+20, l_y+15 ); // 显示文本
  } else {
    fill(255, 255, 255);
    rect(l_x, l_y, 40, 20);
    fill(0);
    text("manual", l_x+20, l_y+15 ); // 显示文本
  }
  text("DO", l_x+20, l_y-5); // 显示文本
}
int state=0;
void serialEvent(Serial myPort) {
  int readTemp = myPort.read(); //读一个字符串赋值给temp

  switch(state) {
  case 0:
    {
      if (readTemp==100) // "d"
        state = 1;
      else
        state = 0;
    };
    break;
  case 1:
    {
      if (readTemp==105) // "i"
        state = 2;
      else
        state = 0;
    };
    break;
  case 2:
    {
      if (readTemp==100) // "d"
        state = 3;
      else
        state = 0;
    };
    break;
  case 3:
    {
      if (readTemp==111) // "o"
        state = 4;
      else
        state = 0;
    };
    break;
  case 4:
    {
      if (readTemp==61) // "="
        state = 5;
      else
        state = 0;
    };
    break;

  case 5:
  case 6:
  case 7:
  case 8:
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
  case 25:
    {

      //println("rec:"+(state-5)+":"+readTemp);
      rec_value[state-5] = readTemp;
      state += 1;
    };
    break;
  case 26:
    {
      //println("case 25 data:"+readTemp);
      state += 1;
    };
    break;
  case 27:
    {
      state = 0;
      dataVld = true;
      rec_cnt ++;
      if (rec_cnt>MAX_CNT)rec_cnt=0;
    };
    break;

  default:
    {
      state = 0;
    };
    break;
  }
}

界面展示
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值