资讯详情

C51 小车PWM调速,超声波测距,灰度寻迹代码,实测可用。

@ C51 小车PWM可直接下载调速、超声波测距、灰度搜索代码

#include<reg52.h> #include <intrins.h>  #define uint unsigned int #define uchar unsigned char  float dis;   ///超声波距离缓存 uchar flag;  ///超声波中断标志  uchar Duty_left,Duty_right; //左右占空比标志,1-1000 uchar aa = 0,cc = 0,i = 0; uchar flag;                 ////用于判断跟踪方向  sbit Echo = P3^2;             //超声波模块的回响信号输出,P3^2也是51单片机外部中断0的输入端,利用下降沿触发中断 sbit Trig = P1^4;             ///触发信号脚 //驱动L298N----> //ENA,ENB为使能端; ENA,1,2和ENB,三、四分别控制电机; sbit IN1 = P1^0; sbit IN2 = P1^1; sbit IN3 = P1^2; sbit IN4 = P1^3; sbit Light = P1^5; sbit ENA = P1^6; sbit ENB = P1^7;  sbit left = P3^0;      ///左右两个灰度传感器 sbit right = P3^1;  /////小车直行速度赋值 void forward_move(); ///停车 void stop(); ///小车左转速度赋值(用于左传感器检测黑线) void 
      
       Left_turning
       (
       )
       ; 
       //小车右转速度赋值(用于右边传感器检测到黑线) 
       void 
       Right_turning
       (
       )
       ; 
       //PWM 定时器初始化 
       void 
       init_T1
       (
       void
       )
       ; 
       // 延时 
       void 
       delay__ms
       (uchar x
       )
       ; 
       //延时10.9us,每个机器周期约1.09us,在晶振为11.0592MHz时 
       void 
       nops
       (
       )
       ; 
       //计算距离的函数 
       void 
       distance
       (
       )
       ; 
       //超声波定时器 初始化函数 
       void 
       init
       (
       )
       ; 
       void 
       main
       (
       )
       //主函数 
       { 
         
       init
       (
       )
       ; 
       init_T1
       (
       )
       ; left 
       = 
       1
       ; right 
       = 
       1
       ; 
       while
       (
       1
       ) 
       { 
         
       distance
       (
       )
       ; 
       //获取超声波距离 
       if
       (dis 
       < 
       10
       ) 
       // 这里改超声波的距离 
       { 
         
       stop
       (
       )
       ; 
       //小车停止 Light 
       = 
       0
       ; 
       //灯亮 
       } 
       else 
       { 
         Light 
       = 
       1
       ; 
       //灯灭 
       if
       (
       (left
       ==
       0
       )
       &&
       (right
       ==
       1
       )
       ) 
       { 
         
       Right_turning
       (
       )
       ;
       //左边检测到黑线 
       } 
       else 
       if
       (
       (left
       ==
       1
       )
       &&
       (right
       ==
       0
       )
       ) 
       { 
         
       Left_turning
       (
       )
       ;
       //右边检测到黑线 
       } 
       else 
       if
       (
       (left
       ==
       1
       )
       &&
       (right
       ==
       1
       )
       ) 
       { 
         
       forward_move
       (
       )
       ; 
       //两边都没检测到黑线 
       } 
       else 
       { 
         
       forward_move
       (
       )
       ; 
       } 
       } 
       } 
       } 
       void 
       ex
       (
       ) interrupt 
       0
       //外部中断的中断函数 
       { 
         TR0
       =
       0
       ;
       //一旦受到下降沿,立马停止定时器计数 dis
       =
       (TH0
       *
       256
       +TL0
       )
       *
       1.09
       /
       58
       ;
       //先取出定时器里的时间值,之后再将定时器置0 flag
       =
       1
       ;
       //将标志位置0 TH0
       =
       0
       ; TL0
       =
       0
       ; 
       } 
       void 
       T1_ISR
       (
       void
       ) interrupt 
       3 using 
       1 
       { 
         TH1 
       = 
       0xff
       ; TL1 
       = 
       0x9c
       ; 
       //给TH1和TL1重新赋值 aa
       ++
       ; cc
       ++
       ; 
       if
       (aa 
       <= Duty_left
       )
       //设置左轮占空比,即左轮速度 ENA 
       = 
       1
       ; 
       else ENA 
       = 
       0
       ; 
       if
       (cc 
       <= Duty_right
       ) ENB 
       = 
       1
       ; 
       else ENB 
       = 
       0
       ; 
       if
       (aa 
       == 
       100
       ) 
       //设置pwm周期=0.1ms*100=10ms,这样开头定义的变量正好表示占空比数值 
       { 
         aa 
       = 
       0
       ;
       //加到100后变为0,重新计数 
       } 
       if
       (cc 
       == 
       100
       ) 
       { 
         cc 
       = 
       0
       ; 
       } 
       } 
       //小车直行速度赋值 
       void 
       forward_move
       (
       ) 
       { 
         Duty_left 
       = 
       18
       ; Duty_right 
       = 
       12
       ; IN1 
       = 
       1
       ; 
       //两个电机均正转 IN2 
       = 
       0
       ; IN3 
       = 
       1
       ; IN4 
       = 
       0
       ; 
       } 
       //小车停止 
       void 
       stop
       (
       ) 
       { 
         Duty_left 
       = 
       0
       ; Duty_right 
       = 
       0
       ; IN1 
       = 
       0
       ; IN2 
       = 
       0
       ; IN3 
       = 
       0
       ; IN4 
       = 
       0
       ; 
       } 
       //小车左转速度赋值(用于左边传感器检测到黑线) 
       void 
       Left_turning
       (
       ) 
       { 
         Duty_left 
       = 
       18
       ; Duty_right 
       = 
       20
       ; IN1 
       = 
       1
       ; 
       //两个电机一个正转一个反转(或者一个正转一个不转) IN2 
       = 
       0
       ; IN3 
       = 
       0
       ; IN4 
       = 
       1
       ; 
       } 
       //小车右转速度赋值(用于右边传感器检测到黑线) 
       void 
       Right_turning
       (
       ) 
       { 
         Duty_left 
       = 
       18
       ; Duty_right 
       = 
       20
       ; IN1 
       = 
       0
       ; IN2 
       = 
       1
       ; IN3 
       = 
       1
       ; IN4 
       = 
       0 
       ; 
       } 
       //PWM 定时器初始化 
       void 
       init_T1
       (
       void
       ) 
       { 
         TMOD
       |= 
       0x10
       ; 
       //使用方式1,16位定时器 TH1 
       = 
       0xff
       ; TL1 
       = 
       0x9c
       ; 
       //定时 ff 9c 0.1ms EA 
       = 
       1
       ; 
       //总中断打开 ET1 
       = 
       1
       ; 
       //定时器中断打开 TR1 
       = 
       1
       ; 
       //定时器开关打开 
       } 
       // ms延时 
       void 
       delay__ms
       (uchar x
       ) 
       { 
         uint i
       ,j
       ; 
       for
       (i
       =
       0
       ;i
       <x
       ;i
       ++
       ) 
       { 
         
       for
       (j
       =
       0
       ;j
       <
       110
       ;j
       ++
       )
       ; 
       } 
       } 
       //延时10.9us,每个机器周期约1.09us,在晶振为11.0592MHz时 
       void 
       nops
       (
       ) 
       { 
         
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       _nop_
       (
       )
       ; 
       } 
       //计算距离的函数 
       void 
       distance
       (
       ) 
       { 
         Trig 
       = 
       0
       ;
       //首先将触发拉低 
       nops
       (
       )
       ; Trig 
       = 
       1
       ;
       //给至少10us的高电平,启动模块 
       nops
       (
       )
       ; 
       nops
       (
       )
       ; Trig 
       = 
       0
       ;
       //此时已经触发了模块,接下来立刻开启定时器计数 TR0 
       = 
       1
       ;
       //打开定时器0 EX0 
       = 
       1
       ;
       //打开外部中断,外部中断输入为P3^2,下降沿有效,触发中断 
       delay__ms
       (
       1
       )
       ;
       //等待一下,一个机器周期约为1.09us,如果不等待,可能就错过计算dis,陷入死循环,永远无法得出值 
       if
       (flag 
       == 
       1
       )
       //如果标志位置1,表示Echo输出下降沿,即接收结束 
       { 
         flag 
       = 
       0
       ; 
       } 
       } 
       //超声波定时器 初始化函数 
       void 
       init
       (
       ) 
       { 
         TMOD 
       = 
       0x01
       ;
       //16位计数器,这里不用开启定时器中断,因为定时器中断无事可做,只要定时器里的值就行,因此无需将TF0置1 TH0 
       = 
       0
       ;
       //全部设为0 TL0 
       = 
       0
       ; IT0 
       = 
       1
       ;
       //设置外部中断下降沿有效 EA 
       = 
       1
       ;
       //开总中断 
       } 
      

标签: 11ea开关传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台