51单片机与processing上位机小项目仿真控制

设计案例介绍

模拟水库自动保值一定蓄水量装置

1.利用单片机与上位机的互相串口通讯、

且拥有最高中断权限保证数据完整

2.设置阈值50%水量少电机抽水速度快正转,

剩余水量多则转速慢若超过50%电机反转泄流

超过80%蜂鸣器报警

3.数码管显示当前水量阈值

4.ON进水开关discharge泄流开关off急停

5.LCD显示状态

 

中断源及优先级

中断源符号

名称

中断标志

中断引起原因

中断号

/INT0

外部中断0

IE0

低电平或下降沿信号(IT)

0

T0

定时器中断0

TF0

定时/计数器0 计数回0溢出

1

/INT1

外部中断1

IE1

低电平或下降沿信号(IT)

2

T1

定时器中断1

TF1

定时/计数器1 计数回1溢出

3

TX/RX

串行口中断

TI/RI

通信完成一帧数据发送或接收

4

 案例硬件设计

 

案例软件设计

  1. 上位机

import processing.serial.*;
Serial port;
int speed=0;
int flag=0;//1开
int display=0;//1泄流
int data;//变量存储51传来数据
void setup(){
  port=new Serial(this,"COM1",9600); //Arduino板的端口号
  size(860,750);
  background(255,255,125);
}

void draw(){
  //text(50,750,325);
  //text(1,750,560);
  background(204);
     if(port.available()>0)
  {
    //把51传来的字节存入变量data
    data=port.read();     
    //println(data);
    
   }
   textSize(60);
   text(data, 0, 50);
  RGBDisplay(); 
  frame();
  if(flag==1){
    if(display==0){
      if(speed==-400){speed=-400;}
      else{speed=speed-data;}
    }

    if(display==1){
        int a=speed;
        if(speed>=-3){speed=speed-data;println(speed);}
        if(flag==0){speed=a;}
        else{speed=speed+data;}
      }
  }
  float x1=map(speed,0,-400,0,99);
  println("wai");
  println(speed);
//println(data);
  port.write(int(x1));
    
  textSize(50);
  fill(0,0,0,100);
  text(int(x1),750,100);
  text("%",800,100);
  
  fill(0,255,0);
  rect(50,600,100,100);
  fill(0);
  textSize(30);
  text("ON",70,660);
  
  fill(0,255,0);
  rect(250,600,100,100);
  
  fill(0,0,255);
  rect(450,600,100,100);  
  fill(0);
  textSize(25);
  text("discharge",450,660);
  
  fill(255,0,0);
  rect(650,600,100,100); 
  fill(0);
  textSize(30);
  text("OFF",670,660);
}
void frame()                                 //绘制进度条边框函数
{
  rectMode(CORNER);
  noFill();
  stroke(0,0,0);
  strokeWeight(2);
  rect(50,100,700,400);
}
void RGBDisplay()                            //绘制进度条函数
{
  rectMode(CORNER);
  noStroke();
  fill(255,0,0);
  rect(50,500,700,speed);

}
void mousePressed(){
  if((mouseX>=50)&(mouseX<=150)&(mouseY>=600)&(mouseY<=700))
  {
    flag=1;
    display=0;
    println("on");
  }
  else if((mouseX>=650)&(mouseX<=750)&(mouseY>=600)&(mouseY<=700))
  {
    flag=0;
    println("off");
  }
  else if((mouseX>=450)&(mouseX<=550)&(mouseY>=600)&(mouseY<=700))
  {
    display=1;
    println("discharge");
  }
    else if((mouseX>=250)&(mouseX<=350)&(mouseY>=600)&(mouseY<=700))
  {
    speed=0;
    println("22");
  }
}

单片机1

//接收
#include <reg51.h>//包含头文件reg51.h
sbit led_red=P2^0;
sbit led_green=P2^1;
sbit led_blue=P2^2;
sbit discharge=P2^3;
sbit FM=P2^7;
sbit ee=P2^6;
sbit button=P3^2;

int ount=0;
/*############################初始化############################*/

int val1;
void initinsterrupt0();
int speed=0;
int flag=0;
int count;
/*############################初始化############################*/

/*############################电机设置############################*/
#define uint unsigned int
#define uchar unsigned char
uchar code FFW[]=
	{0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};

uchar code REV[]=
	{0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};
int step=1;
/*############################电机设置############################*/
		uchar i,j;	
/*############################数码管定义############################*/
sbit high_bit=P3^6;  //定义数码管的高位位选通
sbit low_bit=P3^7;  //定义数码管的低位位选通
int num;//定义数码管要显示数字的暂存变量
//段码定义

unsigned char table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e};//0~F的段码表
void display(int);//显示函数声明
void delayms(unsigned int);//延时函数声明 
void LEFT(int speed);
void RIGHT(int speed);
/*############################数码管定义############################*/
int map(float val, float I_Min, float I_Max, float O_Min, float O_Max)
	{
		return(((val-I_Min)*((O_Max-O_Min)/(I_Max-I_Min)))+O_Min);
   }
  
void LEFT(int speed)
{
 	uchar i,j;
	for(i=0;i<10;i++)
	{
	 	for(j=0;j<8;j++)
		{
			RI=0;//接受完毕一个字符,清零接受中断标志位
			val1=SBUF;
			num=val1;
			if(val1>=80) {led_red=0;led_green=1;led_blue=1;speed=1;}
			if(val1>=40&&val1<80) {led_red=1;led_green=0;led_blue=1;speed=10;}
			if(val1>=0&&val1<40) {led_red=1;led_green=1;led_blue=0;speed=1;}
					SBUF=map(num,150,0,0,3)+0.5;
		TI=0;
			P1 = FFW[j];
			if (num>0&&num<50)break;
			display(num);//口相连的数码管显示数字
			delayms(speed);
		}
	}
}

void RIGHT(int speed)
{
 	uchar i,j;
	for(i=0;i<10;i++)
	{
	 	for(j=0;j<8;j++)
		{
			P1 = REV[j];
			RI=0;//接受完毕一个字符,清零接受中断标志位
			val1=SBUF;
			num=val1;
			if(val1>=80) {led_red=0;led_green=1;led_blue=1;speed=1;}
			if(val1>=40&&val1<80) {led_red=1;led_green=0;led_blue=1;speed=10;}
			if(val1>=0&&val1<40) {led_red=1;led_green=1;led_blue=0;speed=1;}
			SBUF=map(num,150,0,0,3)+0.5;
			TI=0;
			if (num>50)break;			
			display(num);//口相连的数码管显示数字
			delayms(speed);
		}
	}
}
void delay(unsigned int i)
{
	unsigned char k,j;
	for(j=i;j>0;j--)
		for(k=125;k>0;k--);
}
void main()
{
    initinsterrupt0(); //中断初始化设置
	while (1)
	{
		int i=0;
		while (!RI);
		RI=0;//接受完毕一个字符,清零接受中断标志位
		val1=SBUF;
		num=val1;
		while (num>80)
		{
			ee=0;
			FM=0;
			delay(10);
			FM=1;
			delay(5);
			display(num);//口相连的数码管显示数字
			if(i++>100){break;}
		}ee=1;
		if(val1>=80) {led_red=0;led_green=1;led_blue=1;speed=1;}
		if(val1>=40&&val1<80) {led_red=1;led_green=0;led_blue=1;speed=10;}
		if(val1>=0&&val1<40) {led_red=1;led_green=1;led_blue=0;speed=1;}
		speed=map(num,150,0,0,3)+0.5;
			if(step==1){
				num=val1;
				if ((num>=0&&num<50))
				{
					RIGHT(speed);
					discharge=1;
				}else{
					LEFT(speed);
					discharge=0;//开启泄流
				}

			}
		while (!TI);
		SBUF=map(num,150,0,0,2)+0.5;
		TI=0;
	}
	

	
}

void int0() interrupt 0//开关
{
	int i=0;
	step=step+1;
	ee=0;

	if(step>=2)step=0;
		while (SBUF>50)
		{
			FM=0;
			delay(10);
			FM=1;
			delay(5);
			display(num);//口相连的数码管显示数字
			if(i++>100){break;}
		}
}
void initinsterrupt0()
{
	TMOD=0x21; //TMOD=0010 0001,定时器1工作为方式2
	SCON=0x50;//SCON=0101 0000B,串口工作方式为方式1,允许接受
	PCON=0x00;//PCON中的SMOD=0
	TH1=0xFD;TL1=0xFD;//波特率为9600b/s
	TR1=1;//启动T1,波特率发生器工作
	EA=1;
	ET0=1;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	TR0=1;

	EX0=1;
	IT0=0;


}

void time() interrupt 1
{
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	if(flag==1){
		if(--count==0){
			flag=0;
		}
	}
	EX0=0;

}
//显示子函数
void display(int num_display)
{
	int num_high,num_low;
	//把两位十六进制的模数转换结果拆分出低位
	num_low=num_display%10;
    //把低位数的段码通过P1口送到低位数码管
	P0=table[num_low];
	low_bit=1;//选通两位数码管的低位
	high_bit=0;
	delay(10);//延时10ms
	low_bit=0;
	//把两位十六进制的模数转换结果拆分出高位
	num_high=num_display/10;
	//把高位数的段码通过P1口送到高位数码管
	P0=table[num_high];
    high_bit=1;//选通两位数码管的高位
	low_bit=0;
	delay(10);//延时10ms
	high_bit=0;
}
//延时函数
void delayms(unsigned int xms)
{
	count=xms;
	flag=1;
	while (flag);
}

单片机2

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="   GOOD   ";
uchar code table1[]="      ON     ";
sbit lcden=P3^4;
sbit lcdrs=P3^5;
uchar num;


void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void write_com(uchar com)
{
	lcdrs=0;//写命令
	P2=com;
	delay(5);
	lcden=1;
	delay(5);
	lcden=0;
}

void write_data(uchar date)
{
	lcdrs=1;//写数据
	P2=date;
	delay(5);
	lcden=1;
	delay(5);
	lcden=0;
}
void init()
{
	lcden=0;
	write_com(0x38);//初始化
	write_com(0x0c);//光标打开
	write_com(0x06);
	write_com(0x01);
	write_com(0x80+0x1);
}
void main()
{
    int num;
	init();
    TMOD=0x21; //TMOD=0010 0001,定时器1工作为方式2
	SCON=0x50;//SCON=0101 0000B,串口工作方式为方式1,允许接受
	PCON=0x00;//PCON中的SMOD=0
	TH1=0xFD;TL1=0xFD;//波特率为9600b/s
	TR1=1;//启动T1,波特率发生器工作
	EA=1;
    while (!RI);
	RI=0;//接受完毕一个字符,清零接受中断标志位
	num=SBUF;
    delay(100);
    EA=1;EX0=1;EX1=1;
    if(num==1)
    {
        for(num=0;num<14;num++)//显示"Ying Ming Fei"
        {
            write_data(table[num]);
            delay(20);
        }
    }else{
        for(num=0;num<16;num++)//显示"5071418"
	{
		write_data(table1[num]);
		delay(20);
    }
    }


}

void int0() interrupt 0

{

for(num=0;num<14;num++)//显示"Ying Ming Fei"
	{
		write_data(table[num]);
		delay(20);
	}
	// write_com(2);//回车换行
	// write_com(0x80+0x40);
	// for(num=0;num<16;num++)//显示"5071418"
	// {
	// 	write_data(table1[num]);
	// 	delay(20);
	// }

}


void int1() interrupt 2

{


	write_com(1);//清屏

}

附上程序文件

链接:https://pan.baidu.com/s/1x7nagDCo3NQbTxFClEDvhQ 
提取码:md24 
--来自百度网盘超级会员V4的分享

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值