当前位置:文档之家› 简易风洞设计(带有程序)

简易风洞设计(带有程序)

简易风洞设计需要的材料风机,小球,51单片机,风机驱动模块,液晶1602,超声波,电源设计任务设计制作一简易风洞及其控制系统。

风洞由圆管、连接部与直流风机构成。

圆管竖直放置,长度约40cm,内径大于4cm且内壁平滑,小球(直径4cm黄色乒乓球)可在其中上下运动;管体外壁应有A、B、C、D等长标志线,BC段有1cm间隔的短标志线;可从圆管外部观察管内小球的位置;连接部实现风机与圆管的气密性连接,圆管底部应有防止小球落入连接部的格栅。

控制系统通过调节风机的转速,实现小球在风洞中的位置控制。

设计要求(1)小球置于圆管底部,启动后5秒内控制小球向上到达BC段,并维持5秒以上。

(20分)(2)当小球维持在BC段时,用长形纸板(宽度为风机直径的三分之一)遮挡风机的进风口,小球继续维持在BC段。

(10分)(3)以C点的坐标为0cm、B点的坐标为10cm;用键盘设定小球的高度位置(单位:cm),启动后使小球稳定地处于指定的高度3秒以上,上下波动不超过±1cm。

(10分)(4)以适当的方式实时显示小球的高度位置及小球维持状态的计时。

(10分)小球置于圆管底部,启动后5秒内控制小球向上到达圆管顶部处A端,且不跳离,维持5秒以上。

(10分)(5)小球置于圆管底部,启动后30秒内控制小球完成如下运动:向上到达AB段并维持3~5秒,再向下到达CD段并维持3~5;再向上到达AB段并维持3~5,再向下到达CD段并维持3~5;再向上冲出圆管(可以落到管外)。

(20分)(6)风机停止时用手将小球从A端放入风洞,小球进入风洞后系统自动启动,控制小球的下落不超过D点,然后维持在BC段5秒以上。

(10分)(7)其他自主发挥设计。

(10分)说明(1)题中“到达XX段”是指,小球的整体全部进入该段内;(2)题中“维持”是指,在维持过程中小球整体全部不越过该段的端线;(3)小球的位置以其中心点为准(即小球的上沿切线向下移2cm,或下沿切线向上移2cm);(4)直流风机的供电电压不得超过24V,注意防止风机叶片旋转可能造成的伤害;可在圆管及其周围设置传感器检测管内小球的位置;可将圆管、连接部与直流风机安装在硬质板或支架上,以便于使圆管保持竖直状态,并保持风洞气流通畅。

设计论证该装置通过利用单片机输出pwm波控制风机转速,从而达到控制小球位置的目的。

利用超声波检测小球离检测装置的距离通过单片机发送至外设lcd1602显示模块,并通过显示模块显示的数据利用键盘模块进行任务的设定。

部分程序代码#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit led1=P1^3;sbit led2=P1^4;sbit RX=P3^2;sbit TX=P1^5;sbit LCM_RW=P1^1; //定义LCD引脚sbit LCM_RS=P1^0;sbit LCM_E=P2^5;#define LCM_Data P0//#define Key_Data P3_4 //定义Keyboard引脚//#define Key_CLK P3_5#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit in0=P1^0;sbit in1=P1^1;sbit ena=P3^0;sbit k1=P3^6;sbit k2=P3^7;sbit k3=P3^5;float a;float zkb=10;char val=2;void delay(int z){ int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//1602void Delay12us();void Conut(void);void LCMInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);void Delay5Ms(void);void Decode(unsigned char ScanCode);void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);unsigned char ReadDataLCM(void);unsigned char ReadStatusLCM(void);unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};static unsigned char DisNum = 0; //显示用指针unsigned int time=0;unsigned long S=0;bit flag =0;unsigned char disbuff[4] ={ 0,0,0,0,};void delayms(unsigned int ms){unsigned char i=100,j;for(;ms;ms--){while(--i){j=10;while(--j);}}}//写数据void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}//写指令void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}//读数据unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}//读状态unsigned char ReadStatusLCM(void){LCM_Data = 0xFF;LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;while (LCM_Data & Busy); //检测忙信号return(LCM_Data);}void LCMInit(void) //LCM初始化{LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0F,1); // 显示开及光标设置}//按指定位置显示一个字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCM(X, 1); //发命令字WriteDataLCM(DData); //发数据}//按指定位置显示一串字符void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>0x19) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void StartModule() //启动模块{TX=1; //启动一次模块Delay12us();TX=0;while(!RX); //当RX为零时等待TR1=1; //开启计数while(RX); //当RX为1计数并等待TR1=0;Conut();}//5ms延时void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}unsigned char leddata[]={0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x77, //"A"};float t;//uint bai,shi,ge;uint distance;void init();//void display(uint,uint,uint);void Delay12us() //@11.0592MHz {unsigned char i;;;;;;i = 30;while (--i);}//void leddisplay()//数码管显示程序//{// duan=1;// P0=leddata[zkb];// duan=0;// wei=1;// P0=0xfe;// wei=0;// delay(10);//}/*pwm调速设置*/void pwm(){for(a=0;a<50;a++){if(a==50)a=0;if(!k1)//加速调节{delay(5);if(!k1){zkb=zkb+5;if(zkb>50)zkb=0;while(!k1);}}if(a<zkb){ena=1;}else{ena=0;}}// if(!k1)//加速调节// {// delay(5);// if(!k1)// {// zkb=zkb+0.3; // if(zkb>50)// zkb=0;// while(!k1); // }// }if(!k2)//减速调节{delay(5);if(!k2){zkb=zkb-0.3;if(zkb<0)zkb=0;while(!k2);}}if(!k3)//减速调节{delay(5);if(!k3){val++;if(val==3)val=0;while(!k3);}}}/*程序初始化*/void init(){TMOD = 0x10;TH0 = 0xFC;TL0 = 0x66;// ET0 = 1;TR0 = 1;//占空比RX=0;TH1=0;TL1=0;ET1=1;EA = 1;//超声波测距}void main(){LCMInit();init();in0=1;in1=0;while(1){pwm();// led1=0;// delayms(5);led1=!led1;StartModule();led2=!led2;// switch (val)// {// case 0: if(S<27)zkb=13;// if(S>30)zkb=12;break; //// case 1: if(S<17)zkb=10.6;// if(S>22)zkb=10;break; //// case 2: if(S<14)zkb=11.3;// if(S>16)zkb=9.4; break; // }}}void Conut(void){time=TH1*256+TL1;TH1=0;S=(time*1.7)/100; //算出来是CM// if(S>=700||flag==1) //超出测量范围显示“-”// {// flag=0;//// DisplayOneChar(0, 1, ASCII[11]);// DisplayOneChar(1, 1, ASCII[10]); //显示点// DisplayOneChar(2, 1, ASCII[11]);// DisplayOneChar(3, 1, ASCII[11]);// DisplayOneChar(4, 1, ASCII[12]); //显示M// }// else// {disbuff[0]=S%1000/100;disbuff[1]=S%1000%100/10;disbuff[2]=S%1000%10 %10;DisplayOneChar(0, 1, ASCII[disbuff[0]]);DisplayOneChar(1, 1, ASCII[10]); //显示点DisplayOneChar(2, 1, ASCII[disbuff[1]]);DisplayOneChar(3, 1, ASCII[disbuff[2]]);DisplayOneChar(4, 1, ASCII[12]); //显示M}// }/*占空比调节中断*/void ooo() interrupt 1 //ET0{a++;if(a==50)a=0;if(distance<7)zkb=13; //预防死机(不知何种原因,到底时准会”卡住“)TH0=0xFC;TL0=0x66;if(a<zkb){ena=1;}else{ena=0;}}void zd1() interrupt 1 //T1中断用来计数器溢出,超过测距范围{flag=1;led2=!led2; //中断溢出标志}设计流程图。

相关主题