找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4535|回复: 1
打印 上一主题 下一主题
收起左侧

stm32单片机控制水位源程序

[复制链接]
跳转到指定楼层
楼主
这是一个利用stm32单片机控制水位的程序


单片机源程序如下:
  1. /********************************* 深圳市航太电子 *******************************
  2. * 实 验 名 :小车超声波+红外跟踪实验
  3. * 实验说明 :使用超声波判断前方引导物的距离,使用红外来判断引导物的移动方向
  4. * 实验平台 :航太ARM单片机开发板
  5. * 连接方式 :请参考interface.h文件
  6. * 注    意 :1.因地面和轮子的差异,左右转向时需要根据实际需要调节差速的差值
  7. *            2.需要耐心调节红外避障的感应距离以及超声波控制距离
  8. *            3.建议使用不反光的书本作为引导物
  9. * 作    者 :航太电子产品研发部
  10. ****************************************************************************************/
  11. #include "stm32f10x.h"
  12. #include "interface.h"
  13. #include "LCD1602.h"
  14. #include "IRCtrol.h"
  15. #include "motor.h"
  16. #include "UltrasonicCtrol.h"

  17. //全局变量定义
  18. volatile unsigned int speed_count=0;//占空比计数器 50次一周期
  19. char front_left_speed_duty=SPEED_DUTY;
  20. char front_right_speed_duty=SPEED_DUTY;
  21. char behind_left_speed_duty=SPEED_DUTY;
  22. char behind_right_speed_duty=SPEED_DUTY;

  23. unsigned char tick_5ms = 0;//5ms计数器,作为主函数的基本周期
  24. unsigned char tick_1ms = 0;//1ms计数器,作为电机的基本计数器
  25. unsigned char tick_200ms = 0;//刷新显示

  26. char ctrl_comm = COMM_STOP;//控制指令
  27. char ctrl_comm_last = COMM_STOP;//上一次的指令
  28. unsigned char continue_time=0;

  29. volatile unsigned int target_mm=0;
  30. unsigned int shift        =        0;
  31. volatile unsigned int height_mm        =        0;

  32. int i;
  33. unsigned int avg_dis;
  34. int flag;

  35. unsigned int Avg_Distance()
  36. {
  37.         unsigned int sum=0;
  38.         unsigned int max=0,min=10000;

  39.         sum=0;
  40.         Distance();
  41.         max        =         distance_cm;
  42.         min        =        distance_cm;
  43.         sum +=  distance_cm;
  44.         Distance();
  45.         if(max<distance_cm)
  46.                 max        =         distance_cm;
  47.         if(min>distance_cm)
  48.                 min        =        distance_cm;
  49.         sum +=  distance_cm;
  50.         Distance();
  51.         if(max<distance_cm)
  52.                 max        =         distance_cm;
  53.         if(min>distance_cm)
  54.                 min        =        distance_cm;
  55.         sum +=  distance_cm;
  56.         Distance();
  57.         if(max<distance_cm)
  58.                 max        =         distance_cm;
  59.         if(min>distance_cm)
  60.                 min        =        distance_cm;
  61.         sum +=  distance_cm;
  62.         Distance();
  63.         if(max<distance_cm)
  64.                 max        =         distance_cm;
  65.         if(min>distance_cm)
  66.                 min        =        distance_cm;
  67.         sum +=  distance_cm;
  68.         Distance();
  69.         if(max<distance_cm)
  70.                 max        =         distance_cm;
  71.         if(min>distance_cm)
  72.                 min        =        distance_cm;
  73.         sum +=  distance_cm;
  74.         Distance();
  75.         if(max<distance_cm)
  76.                 max        =         distance_cm;
  77.         if(min>distance_cm)
  78.                 min        =        distance_cm;
  79.         sum +=  distance_cm;

  80.         sum-=max;
  81.         sum-=min;
  82.         return sum/5;
  83. }

  84. void BarrierProc(void)
  85. {
  86.         return;
  87. }

  88. void GoToTarget()
  89. {
  90.         //停止注水
  91.         while(1)
  92.         {
  93.                 if(height_mm -1 >         target_mm)
  94.                 {
  95.                         //while(height_mm > target_mm)
  96.                         {       
  97.                                 //Distance();
  98.                                 avg_dis = Avg_Distance();
  99.                                 if(        avg_dis> shift )
  100.                                         avg_dis = shift;
  101.                                 else if( avg_dis ==0 )//可能返回错误数据,跳过
  102.                                         continue;               
  103.                                 height_mm        =        shift - avg_dis;
  104.                
  105.                                 front_right_speed_duty = 30;//Stop motor
  106.                
  107.                                 LEDToggle(LED_PIN);
  108.                                 LCD1602WriteDistance(height_mm);//更新距离
  109.                                 LCD1602WriteCommand(target_mm);
  110.                
  111.                                 Delayms(200);                          
  112.                         }
  113.                 }
  114.                 else if(height_mm+1 < target_mm) //水位不够,增加注水
  115.                 {
  116.                         while(height_mm < target_mm)
  117.                         {       
  118.                                 //Distance();
  119.                                 avg_dis = Avg_Distance();
  120.                                 if(        avg_dis> shift )
  121.                                         avg_dis = shift;
  122.                                 else if( avg_dis ==0 )//可能返回错误数据,跳过
  123.                                         continue;               
  124.                                 height_mm        =        shift - avg_dis;
  125.                
  126.                                 front_right_speed_duty =50;//Stop motor
  127.                
  128.                                 LEDToggle(LED_PIN);
  129.                                 LCD1602WriteDistance(height_mm);//更新距离
  130.                                 LCD1602WriteCommand(target_mm);
  131.                
  132.                                 Delayms(200);                          
  133.                         }
  134.                 }
  135.                 else  if( height_mm<target_mm+1 && height_mm > target_mm-1 )
  136.                 {       
  137.                         front_right_speed_duty = 0;
  138.                         return;
  139.                 }
  140.         }

  141. }

  142. void Keep3Min()
  143. {
  144.         front_right_speed_duty = 30;//控制PWM与流出速度一致,保持3分钟
  145.         for(i=0;i<60*3;i++)
  146.         {
  147.                 avg_dis = Avg_Distance();
  148.                 if(        avg_dis> shift )
  149.                         avg_dis = shift;
  150.                 else if( avg_dis ==0 )//可能返回错误数据,跳过
  151.                         continue;
  152.                 height_mm        =        shift - avg_dis;

  153.                 if(        height_mm +1 < target_mm )
  154.                         front_right_speed_duty += 5;
  155.                 else if( height_mm-1 > target_mm )
  156.                         front_right_speed_duty -= 5;

  157.                 LEDToggle(LED_PIN);
  158.                 LCD1602WriteDistance(height_mm);//更新距离
  159.                 LCD1602WriteCommand(target_mm);

  160.                 Delayms(500);

  161.                 avg_dis = Avg_Distance();
  162.                 if(        avg_dis> shift )
  163.                         avg_dis = shift;
  164.                 else if( avg_dis ==0 )//可能返回错误数据,跳过
  165.                         continue;
  166.                 height_mm        =        shift - avg_dis;

  167.                 if(        height_mm +1 < target_mm )
  168.                         front_right_speed_duty += 5;
  169.                 else if( height_mm-1 > target_mm )
  170.                         front_right_speed_duty -= 5;

  171.                 Delayms(500);
  172.         }
  173. }


  174. int main(void)
  175. {
  176.         //功率最大,注水
  177.         distance_cm =         0;
  178.         shift                =        276;       
  179.         height_mm        =        0;
  180.         avg_dis                =        0;

  181.         delay_init();
  182.         GPIOCLKInit();
  183.         UserLEDInit();
  184.         LCD1602Init();
  185.         IRCtrolInit();
  186.         TIM2_Init();
  187.         MotorInit();
  188.         UltraSoundInit();
  189.         RedRayInit();
  190.         ServoInit();

  191.        
  192.         while(1)
  193.         {
  194.                 Distance();
  195.                 if (  distance_cm < 10 )
  196.                 {
  197.                         CarGo();       
  198.                         Delayms(500);
  199.                         CarStop();
  200.                         Delayms(500);
  201.                 }
  202.                 else
  203.                 {
  204.                         CarBack();
  205.                         Delayms(500);
  206.                         CarStop();
  207.                         Delayms(500);
  208.                 }
  209.         }

  210.         target_mm        =         100;
  211.            //基本要求,先注水到100mm
  212.         GoToTarget();

  213.         flag=0;
  214.         while(1)
  215.         {       
  216.                  if(tick_5ms >= 5)
  217.                 {
  218.                         tick_5ms = 0;
  219.                         tick_200ms++;
  220.                         if(tick_200ms >= 40)
  221.                         {
  222.                                 tick_200ms = 0;
  223.                                 LEDToggle(LED_PIN);
  224.                                 LCD1602WriteDistance(height_mm);//更新距离
  225.                                 LCD1602WriteCommand(target_mm);       
  226.                         }
  227.                         //do something
  228.                         avg_dis = Avg_Distance();
  229.                         if(        avg_dis> shift )
  230.                                 avg_dis = shift;
  231.                         else if( avg_dis ==0 )//可能返回错误数据,跳过
  232.                                 continue;               
  233.                         height_mm        =        shift - avg_dis;                                 
  234.                 }
  235.                
  236.                 if(ir_rec_flag == 1)//接收到红外信号
  237.                 {
  238.                                 ir_rec_flag = 0;
  239.                                 switch(ctrl_comm)
  240.                                 {
  241.                                         case COMM_UP:     
  242.                                                                 target_mm++;
  243.                                                                 break;         //增加转速
  244.                                         case COMM_DOWN:   
  245.                                                                 target_mm--;
  246.                                                                 break;//减少转速
  247.                                         case COMM_LEFT:  
  248.                                                                 //front_right_speed_duty++;
  249.                                                                 //if(front_right_speed_duty>50)
  250.                                                                 //        front_right_speed_duty=50;
  251.                                                                 flag = 2;
  252.                                                                 break;//停止
  253.                                         case COMM_RIGHT:
  254.                                                                 //front_right_speed_duty--;
  255.                                                                 //if(front_right_speed_duty<1)
  256.                                                                 //        front_right_speed_duty=0;
  257.                                                                 flag=3;
  258.                                                                 break;//停止
  259.                                         case COMM_STOP:
  260.                                                                 flag=1;  
  261.                                                                 break;
  262.                                         default :
  263.                                         break;
  264.                                 }
  265.                                 LEDToggle(LED_PIN);
  266.                                 LCD1602WriteDistance(height_mm);
  267.                                 LCD1602WriteCommand(target_mm);
  268.                 }

  269.                 if(flag!=0)
  270.                         break;               
  271.         }

  272.         if(flag==2 || flag==1 )//2 基本要求
  273.         {
  274.                 //基本要求,先注水到100mm
  275.                 GoToTarget();
  276.                 Keep3Min();
  277.        
  278.                 //水位到110mm,并保持3分钟
  279.                 target_mm = 110;
  280.                 //注水到设定高度
  281.                 GoToTarget();
  282.                 Keep3Min();
  283.        
  284.                 //上述操作结束后,停止注水
  285.                 front_right_speed_duty = 0;
  286.                 LCD1602WriteCommand(888);
  287.                 Delayms(1000);
  288.                 LCD1602WriteCommand(888);
  289.                 Delayms(1000);
  290.                 LCD1602WriteCommand(888);
  291.                 Delayms(1000);
  292.                 LCD1602WriteCommand(888);
  293.                 Delayms(1000);

  294.         }//基本部分结束
  295.         else if(flag==3 )//发挥部分
  296.         {
  297.                 //注水到设定高度
  298.                 GoToTarget();
  299.                 Keep3Min();
  300.        
  301.                 target_mm = 100;
  302.                 GoToTarget();
  303.                 Keep3Min();
  304.        
  305.                 target_mm = 200;
  306. ……………………

  307. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
WaterLevel.zip (22.87 KB, 下载次数: 60)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩1
回复

使用道具 举报

沙发
ID:933682 发表于 2021-6-7 08:48 | 只看该作者
有没有proteus的仿真图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表