标题:
stm32单片机控制水位源程序
[打印本页]
作者:
声几又香
时间:
2018-4-17 14:34
标题:
stm32单片机控制水位源程序
这是一个利用stm32单片机控制水位的程序
0.jpg
(33.01 KB, 下载次数: 62)
下载附件
2018-4-17 16:40 上传
单片机源程序如下:
/********************************* 深圳市航太电子 *******************************
* 实 验 名 :小车超声波+红外跟踪实验
* 实验说明 :使用超声波判断前方引导物的距离,使用红外来判断引导物的移动方向
* 实验平台 :航太ARM单片机开发板
* 连接方式 :请参考interface.h文件
* 注 意 :1.因地面和轮子的差异,左右转向时需要根据实际需要调节差速的差值
* 2.需要耐心调节红外避障的感应距离以及超声波控制距离
* 3.建议使用不反光的书本作为引导物
* 作 者 :航太电子产品研发部
****************************************************************************************/
#include "stm32f10x.h"
#include "interface.h"
#include "LCD1602.h"
#include "IRCtrol.h"
#include "motor.h"
#include "UltrasonicCtrol.h"
//全局变量定义
volatile unsigned int speed_count=0;//占空比计数器 50次一周期
char front_left_speed_duty=SPEED_DUTY;
char front_right_speed_duty=SPEED_DUTY;
char behind_left_speed_duty=SPEED_DUTY;
char behind_right_speed_duty=SPEED_DUTY;
unsigned char tick_5ms = 0;//5ms计数器,作为主函数的基本周期
unsigned char tick_1ms = 0;//1ms计数器,作为电机的基本计数器
unsigned char tick_200ms = 0;//刷新显示
char ctrl_comm = COMM_STOP;//控制指令
char ctrl_comm_last = COMM_STOP;//上一次的指令
unsigned char continue_time=0;
volatile unsigned int target_mm=0;
unsigned int shift = 0;
volatile unsigned int height_mm = 0;
int i;
unsigned int avg_dis;
int flag;
unsigned int Avg_Distance()
{
unsigned int sum=0;
unsigned int max=0,min=10000;
sum=0;
Distance();
max = distance_cm;
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
Distance();
if(max<distance_cm)
max = distance_cm;
if(min>distance_cm)
min = distance_cm;
sum += distance_cm;
sum-=max;
sum-=min;
return sum/5;
}
void BarrierProc(void)
{
return;
}
void GoToTarget()
{
//停止注水
while(1)
{
if(height_mm -1 > target_mm)
{
//while(height_mm > target_mm)
{
//Distance();
avg_dis = Avg_Distance();
if( avg_dis> shift )
avg_dis = shift;
else if( avg_dis ==0 )//可能返回错误数据,跳过
continue;
height_mm = shift - avg_dis;
front_right_speed_duty = 30;//Stop motor
LEDToggle(LED_PIN);
LCD1602WriteDistance(height_mm);//更新距离
LCD1602WriteCommand(target_mm);
Delayms(200);
}
}
else if(height_mm+1 < target_mm) //水位不够,增加注水
{
while(height_mm < target_mm)
{
//Distance();
avg_dis = Avg_Distance();
if( avg_dis> shift )
avg_dis = shift;
else if( avg_dis ==0 )//可能返回错误数据,跳过
continue;
height_mm = shift - avg_dis;
front_right_speed_duty =50;//Stop motor
LEDToggle(LED_PIN);
LCD1602WriteDistance(height_mm);//更新距离
LCD1602WriteCommand(target_mm);
Delayms(200);
}
}
else if( height_mm<target_mm+1 && height_mm > target_mm-1 )
{
front_right_speed_duty = 0;
return;
}
}
}
void Keep3Min()
{
front_right_speed_duty = 30;//控制PWM与流出速度一致,保持3分钟
for(i=0;i<60*3;i++)
{
avg_dis = Avg_Distance();
if( avg_dis> shift )
avg_dis = shift;
else if( avg_dis ==0 )//可能返回错误数据,跳过
continue;
height_mm = shift - avg_dis;
if( height_mm +1 < target_mm )
front_right_speed_duty += 5;
else if( height_mm-1 > target_mm )
front_right_speed_duty -= 5;
LEDToggle(LED_PIN);
LCD1602WriteDistance(height_mm);//更新距离
LCD1602WriteCommand(target_mm);
Delayms(500);
avg_dis = Avg_Distance();
if( avg_dis> shift )
avg_dis = shift;
else if( avg_dis ==0 )//可能返回错误数据,跳过
continue;
height_mm = shift - avg_dis;
if( height_mm +1 < target_mm )
front_right_speed_duty += 5;
else if( height_mm-1 > target_mm )
front_right_speed_duty -= 5;
Delayms(500);
}
}
int main(void)
{
//功率最大,注水
distance_cm = 0;
shift = 276;
height_mm = 0;
avg_dis = 0;
delay_init();
GPIOCLKInit();
UserLEDInit();
LCD1602Init();
IRCtrolInit();
TIM2_Init();
MotorInit();
UltraSoundInit();
RedRayInit();
ServoInit();
while(1)
{
Distance();
if ( distance_cm < 10 )
{
CarGo();
Delayms(500);
CarStop();
Delayms(500);
}
else
{
CarBack();
Delayms(500);
CarStop();
Delayms(500);
}
}
target_mm = 100;
//基本要求,先注水到100mm
GoToTarget();
flag=0;
while(1)
{
if(tick_5ms >= 5)
{
tick_5ms = 0;
tick_200ms++;
if(tick_200ms >= 40)
{
tick_200ms = 0;
LEDToggle(LED_PIN);
LCD1602WriteDistance(height_mm);//更新距离
LCD1602WriteCommand(target_mm);
}
//do something
avg_dis = Avg_Distance();
if( avg_dis> shift )
avg_dis = shift;
else if( avg_dis ==0 )//可能返回错误数据,跳过
continue;
height_mm = shift - avg_dis;
}
if(ir_rec_flag == 1)//接收到红外信号
{
ir_rec_flag = 0;
switch(ctrl_comm)
{
case COMM_UP:
target_mm++;
break; //增加转速
case COMM_DOWN:
target_mm--;
break;//减少转速
case COMM_LEFT:
//front_right_speed_duty++;
//if(front_right_speed_duty>50)
// front_right_speed_duty=50;
flag = 2;
break;//停止
case COMM_RIGHT:
//front_right_speed_duty--;
//if(front_right_speed_duty<1)
// front_right_speed_duty=0;
flag=3;
break;//停止
case COMM_STOP:
flag=1;
break;
default :
break;
}
LEDToggle(LED_PIN);
LCD1602WriteDistance(height_mm);
LCD1602WriteCommand(target_mm);
}
if(flag!=0)
break;
}
if(flag==2 || flag==1 )//2 基本要求
{
//基本要求,先注水到100mm
GoToTarget();
Keep3Min();
//水位到110mm,并保持3分钟
target_mm = 110;
//注水到设定高度
GoToTarget();
Keep3Min();
//上述操作结束后,停止注水
front_right_speed_duty = 0;
LCD1602WriteCommand(888);
Delayms(1000);
LCD1602WriteCommand(888);
Delayms(1000);
LCD1602WriteCommand(888);
Delayms(1000);
LCD1602WriteCommand(888);
Delayms(1000);
}//基本部分结束
else if(flag==3 )//发挥部分
{
//注水到设定高度
GoToTarget();
Keep3Min();
target_mm = 100;
GoToTarget();
Keep3Min();
target_mm = 200;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
WaterLevel.zip
(22.87 KB, 下载次数: 60)
2018-4-17 14:33 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
a1234567
时间:
2021-6-7 08:48
有没有proteus的仿真图
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1