简易风洞设计(带有程序)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简易风洞设计
需要的材料
风机,小球,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>
#defineucharunsignedchar
#defineuintunsignedint
sbitled1=P1A3;
sbitled2=P1A4;
sbitRX=P3A2;
sbitTX=P1A5;
sbitLCM_RW=P»1;〃定义LCD弓|脚
sbitLCM_RS=P1A0;
sbitLCM_E=P2A5;
#defineLCM_DataP0
〃#defineKey_DataP3_4〃定义Keyboard引脚
//#defineKey_CLKP3_5
#defineBusy0x80〃用于检测LCM状态字中的Busy标识
sbitin0=P1A0;
sbitin1=P1A1;
sbitena=P3A0;
sbitk1=P3A6;
sbitk2=P3A7;
sbitk3=P3A5;
floata;
floatzkb=10;
charval=2;
voiddelay(intz)
{intx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//1602
voidDelay12us();
voidConut(void);
voidLCMInit(void);
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);
voidDelay5Ms(void);
voidDecode(unsignedcharScanCode);
voidWriteDataLCM(unsignedcharWDLCM); voidWriteCommandLCM(unsignedcharWCLCM,BuysC);
unsignedcharReadDataLCM(void); unsignedcharReadStatusLCM(void); unsignedcharcodeASCII[15]={'0','1','2','3','4','5','6','7','8','9','.','-','M'};
staticunsignedcharDisNum=0;//显示用指针
unsignedinttime=0;
unsignedlongS=0;
bitflag=0;
unsignedchardisbuff[4]={0,0,0,0,};
voiddelayms(unsignedintms)
{
unsignedchari=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;//若晶振速度太高可以在这后加小的延时
LCM_E=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测{ if(BuysC)ReadStatusLCM();//根据需要检测忙LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=0;
LCM_E=1;
}
//读数据
unsignedcharReadDataLCM(void){
LCM_RS=1;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
return(LCM_Data);
}
//读状态
unsignedcharReadStatusLCM(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);
}
voidLCMInit(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);//显示开及光标设置}
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData){
Y&=0x1;
X&=0xF;〃限制X不能大于15,Y不能大于1
if(Y)X1=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
WriteCommandLCM(X,1);//发命令字
WriteDataLCM(DData);//发数据}
//按指定位置显示一串字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData){
unsignedcharListLength;
ListLength=0;
Y&=0x1;
X&=0xF;〃限制X不能大于15,Y不能大于1
while(DData[ListLength]>0x19)//若到达字串尾则退出
{
if(X<=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符ListLength++;
X++;
}
}}
voidStartModule()//启动模块
{
TX=1;//启动一次模块
Delay12us();
TX=0;
while(!RX);〃当RX为零时等待
TR1=1;//开启计数
while(RX);〃当RX为1计数并等待
TR1=0;Conut();
}
//5ms延时
voidDelay5Ms(void){
unsignedintTempCyc=5552;while(TempCyc--);
}
unsignedcharleddata[]={
0x3F,//"0"0x06,//"1"0x5B,//"2"0x4F,//"3"0x66,//"4"0x6D,//"5"0x7D,//"6"0x07,//"7
"
0x7F,//"8"
0x6F,//"9"
0x77,//"A"};
floatt;
//uintbai,shi,ge;
uintdistance;
voidinit();
//voiddisplay(uint,uint,uint);
voidDelay12us()//@11.0592MHz{
unsignedchari;
;;;;;
i=30;
while(--i);
}
//voidleddisplay()//数码管显示程序
//{
//duan=1;
//P0=leddata[zkb];
//duan=0;
//wei=1;
//P0=0xfe;
//wei=0;
//delay(10);
//}
/*pwm调速设置*/
voidpwm()
{
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); } 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);
}
*程序初始化*
voidinit()
{
TMOD=0x10;
TH0=0xFC;
TL0=0x66;
ET0=1;
TR0=1;占空比
TX=0;
RX=0;
TH1=0;
TL1=0;
//
//
//
//
//
// } if(!k2)减速调节{
EA=1;〃D"”
}
voidmain()
{
LCMInit();
init();
in0=1;
in1=0;
while(1)
{
pwm();
//led1=0;
//delayms(5);
led1=!led1;
StartModule();
led2=!led2;
// switch(val)
// {
// case0:if(S<27)zkb=13;
// if(S>30)zkb=12;break; //
// case1:if(S<17)zkb=10.6;
// if(S>22)zkb=10;break; //
// case2:if(S<14)zkb=11.3;
// if(S>16)zkb=9.4;break; // }
}
}
voidConut(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}//}
/*占空比调节中断*/
voidooo()interrupt1//ET0
{
a++;
if(a==50)
a=0;
if(distance<7)zkb=13;//预防死机(不知何种原因,到底时准会”卡住“)TH0=0xFC;
TL0=0x66;
if(a<zkb){
ena=1;
}else{
ena=0;
}
}
voidzd1()interrupt1 //T1中断用来计数器溢出,超过测距范
围
flag=l;
Ied2=!led2;
〃中断溢出标志}
设计流程图
A。