赞
踩
材料 | 数量 |
电机 | 2 |
万向轮 | 1 |
轮胎 | 2 |
循迹模块 | 2 |
超声波、舵机 | 1 |
STC12C5A60S2学习板或者最小系统 | 1 |
L298N | 1 |
12V可充电锂电池 | 1 |
如上图所示: 输出A和输出B接到电机。12V供电接到锂电池正极,5V接到单片机正极,GND单片机和锂电池共用。拔掉通道A使能和通道B使能,各接到单片机P1^3和P1^4口(具有PCA的单片机最好,不是的话用定时器弄个PWM也行,接法不变),IN1和IN2为一组( IN1 = P0^1; //左电机正转,IN2 = P0^2; //左电机反转),接到单片机P2对应OutA(输出A); IN3和IN4为一组(IN3 = P0^4; //右电机正转 ,IN4 = P0^3; //右电机反转),对应OutB(输出B)。
正反转逻辑(0为低电平,1为高电平)
IN1 | IN2 | IN3 | IN4 | 电机 |
1 | 0 | 0 | 1 | 向前 |
0 | 1 | 1 | 0 | 向后 |
0 | 0 | 0 | 1 | 左转 |
1 | 0 | 0 | 0 | 向后 |
1 | 1 | 1 | 1 | 停止 |
0 | 0 | 0 | 0 | 停止 |
PWM,STC12的I/O口P13和P14,PWM_Set(x,y),x=y=110可以驱动小车前进。
.PWM.C
- #include "pwm.h"
- /**********************************
- *函数名称:PCA_Init(void)
- *输入 :无
- *输出 :无
- *调用说明:外部调用
- *函数说明:PWM模块初始化
- ***********************************/
- void PCA_Init(void)
- {
- CCON = 0; //PCA初始化
- CMOD = 0x00; //空闲时不计数,不产生中断,时钟源为Sysclk/12,PWM频率大约为4KHz
- CL = 0x00; //PCA低8位清零
- CH = 0x00; //PCA高8位清零
-
- CCAPM0 = 0x42; //8位PWM模式,无中断
- CCAP0H = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)
- CCAP0L = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)
-
- CCAPM1 = 0x42; //8位PWM模式,无中断
- CCAP1H = 0x40; //PWM1占空比(调节此处值调节PWM占空比)
- CCAP1L = 0x40; //PWM1占空比(调节此处值调节PWM占空比)
-
- CR = 1; //启动PCA计数器
- }
-
- /**********************************
- *函数名称:PWM_Set(unsigned char x,unsigned char y)
- *输入 :占空比输入1 unsigned char x(0-255),占空比输入unsigned char y(0-255)
- *输出 :无
- *调用说明:外部调用
- *函数说明:占空比设置
- ***********************************/
- void PWM_Set(unsigned char x,unsigned char y)
- {
- x = ~x;
- y = ~y;
-
- CCAP0H = y; //设置比较值
- CCAP0L = y;
- CCAP1H = x; //设置比较值
- CCAP1L = x;
- }
motor.c
- #include "motor.h"
-
- //智能小车前进
- void SmartCarForward()
- {
- LeftMotorGo; //左电机正转
- RightMotorGo; //右电机正转
- }
-
- //智能小车后退
- void SmartCarBack()
- {
- LeftMotorBack; //左电机反转
- RightMotorBack; //右电机反转
- }
-
- //智能小车左转
- void SmartCarLeft()
- {
- LeftMotorBack; //左电机反转
- RightMotorGo; //右电机正转
- }
-
- //智能小车右转
- void SmartCarRight()
- {
- LeftMotorGo; //左电机正转
- RightMotorBack; //右电机反转
- }
-
- //智能小车停车
- void SmartCarStops()
- {
- LeftMotorStop; //左电机停转
- RightMotorStop; //右电机停转
- }
motor.h头文件
- #ifndef _MOTOR_H
- #define _MOTOR_H
-
- #include "config.h"
-
- //具体逻辑查看如下真值表
- //ENA IN1 IN2 直流电机状态
- //0 x x 停止
- //1 0 0 制动
- //1 0 1 正转
- //1 1 0 反转
- //1 1 1 制动
- #define LeftMotorStop IN1 = 0, IN2 = 0//左电机停止
- #define RightMotorStop IN3 = 0, IN4 = 0//右电机停止
- #define LeftMotorGo IN1 = 1, IN2 = 0//左电机正传
- #define LeftMotorBack IN1 = 0, IN2 =1//左电机反转
- #define RightMotorGo IN3 = 1, IN4 = 0//右电机正传
- #define RightMotorBack IN3 = 0, IN4 = 1//右电机反转
-
- //---------------------------------------------
- //L298N双H桥直流驱动硬件接口定义
- //---------------------------------------------
- sbit IN1 = P0^1; //左电机正转
- sbit IN2 = P0^2; //左电机反转
- sbit IN3 = P0^4; //右电机正转
- sbit IN4 = P0^3; //右电机反转
- sbit ENA = P1^3; //左使能
- sbit ENB = P1^4; //右使能
-
- void SmartCarForward(); //智能小车前进
- void SmartCarBack(); //智能小车后退
- void SmartCarLeft(); //智能小车左转
- void SmartCarRight(); //智能小车右转
- void SmartCarStops(); //智能小车停车
-
- #endif
信号线(黄色)、正极(红色)、负极(棕色)
信号线连接到P3^4,用定时器0,0.1ms中断一次,0.1*6(中断次数)=1ms(指向右边);0.1*15(中断次数)=1.5ms(舵机指向中间);0.1*20(中断次数)=2ms(舵机指向左边)
180度舵机控制参数 | |||
角度 | 脉冲周期 | 脉冲高电平时间 | 占空比 |
0 | 20ms | 0.5ms | 2.50% |
45 | 20ms | 1ms | 5.00% |
90 | 20ms | 1.5ms | 7.50% |
145 | 20ms | 2ms | 10.00% |
180 | 20ms | 2.5ms | 12.50% |
-
-
- unsigned char duoji_count=0;
- unsigned char zhuanjiao = 11;
-
- /*******************************************************************************
- * 函 数 名 :Delayms
- * 函数功能 :实现 ms级的延时
- * 输 入 :ms
- * 输 出 :无
- *******************************************************************************/
- void Delayms(unsigned int ms)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- for(j=0;j<114;j++);
- }
-
- /*******************************************************************************
- * 函 数 名 :Timer0Init
- * 函数功能 :定时器0初始化
-
-
- * 输 入 :无
- * 输 出 :无
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD|=0x01; //设置定时器0工作方式为1
- TH0=164;//100us,0.1ms
- TL0=164;
- ET0=1; //开启定时器0中断
- TR0=1; //开启定时器
- EA=1; //打开总中断
- }
- /*******************************************************************************
- * 函 数 名 :Timer0Int
- * 函数功能 :定时器0中断函数 , 每隔TIME_MS ms进入
- * 输 入 :无
- * 输 出 :无
- *******************************************************************************/
- void Timer0Int() interrupt 1
- {
- TH0=164;
- TL0=164;
-
-
- duoji_count++;
- if(duoji_count <= zhuanjiao)
- {
- DUOJI_IO = 0;
- }
- else
- {
- DUOJI_IO = 1;
- }
- if(duoji_count >= 200)//20ms
- {
- duoji_count = 0;
- }
-
- }
- void DuojiMid()
- {
- zhuanjiao = 11;//指向中间
- Delayms(1000);//延时1s
- }
-
- void DuojiRight()
- {
- zhuanjiao = 6;//右边
- Delayms(1000);//延时1s
- }
-
- void DuojiLeft()
- {
- zhuanjiao = 18; //左边
- Delayms(1000);//延时1s
- }
超声波和舵机是接在一起的,一般网上买都有连接材料,超声波可以随便连接I/O口,我这里接的是EchoPin = P3^6;//超声波模块Echo 接收端;TrigPin = P3^5;//超声波模块Trig 控制端。
下面是不用PCA作为电机PWM,PCA可以在CSDN上找小途或者其它文章,STC12C5A60S2独立PWM
PCA最高255,可以当作两个8位计数器来用,注意头文件,要有RCAP2H、RCAP2L、TH2、TR2和TL2,建议用reg52.h作为头文件。
- #include "UltrasonicCtrol.h"
- #include "interface.h"
-
- volatile unsigned char status = 0;//程序当前状态,0,空闲 1 发送触发信号,2 等待信号返回,3
- unsigned int dis_count = 0;//脉宽长计时
- volatile unsigned int distance_cm = 0;//当前距离
- unsigned char t2_full_count = 0;//计数器计满次数计数
- static unsigned int tick_5ms = 0;//5ms计数器
-
- void UltraSoundInit()
- {
- Trig = 0;
- TH2 = RCAP2H = 0;
- TL2 = RCAP2L = 0;
- TR2 = 0;//关闭定时器
- ET2=1; //允许T0中断
-
- EX1=0; //关闭外部中断1
- IT1=1; //由高电平变低电平,触发外部中断
- PX1 = 1;//优先级较高
- }
-
- //中断的方式读取距离值 每5ms执行一次
- void GetDistance()
- {
- if(status == 1)
- {
- //发送触发信号
- Trig = 1;
- status = 1;
- TH2 = 0;
- TL2 = 0;
- TR2 = 1;//打开定时器
- while(TL2 < 42);//延时超过10us
- status = 2;
- Trig = 0;
- TH2 = 0;
- TL2 = 0;
- TR2 = 0;
- while(Echo == 0);//等待回向信号起始位置
- EX1 = 1;//打开外部中断
- TR2 = 1;
- status = 3;//开始计算距离
- }
- if(status == 4)//成功接收到数据
- {
- distance_cm = (unsigned int)(((long)(dis_count) * 34)/8000);//声速340m/s
- status = 0;//准备下次发送
- }
- if(status == 5)//接收数据失败
- {
- status = 0;//准备下次发送
- }
- }
-
- //开始获取距离,每100ms执行一次
- void StartGetDistance()
- {
- status = 1;
- }
-
- void Distance()
- {
- tick_5ms++;
- if(tick_5ms >= 20)
- {
- tick_5ms = 0;
- // StartGetDistance();
- GetDistanceDelay();
- }
- //GetDistance();
- }
-
- //延时的方式读取距离值
- void GetDistanceDelay()
- {
- //发送触发信号
- Trig = 1;
- status = 1;
- TH2 = 0;
- TL2 = 0;
- TR2 = 1;//打开定时器
- while(TL2 < 42);//延时超过10us
- status = 2;
- Trig = 0;
- TH2 = 0;
- TL2 = 0;
- TR2 = 0;
- while(Echo == 0);//等待回向信号起始位置
- // EX1 = 1;//打开外部中断
- TR2 = 1;
- while(Echo == 1)//开始计算长度
- {
- if(status == 5)
- {
- status = 0;
- //distance_cm = 0;//失败后就后退
- return;//本次失败
- }
- }
- dis_count = TH2*256 + TL2;
- TR2 = 0;
- distance_cm = (unsigned int)(((long)(dis_count) * 34)/8000);//声速340m/s
- status = 0;//准备下次发送
- }
-
- /*******************************************************************************
- * 函 数 名 :
- * 函数功能 :外部中断1服务函数
- * 输 入 :无
- * 输 出 :无
- *******************************************************************************/
- void Exint1Int() interrupt 2 // 外部中断是2号
- {
- if(status == 3)
- {
- dis_count = TH2*256 + TL2;
- EX1=0; //关闭外部中断
- TR2 = 0;
- status = 4;
- }
- }
-
- /*******************************************************************************
- * 函 数 名 :Timer0Int
- * 函数功能 :定时器0中断服务函数
- * 输 入 :无
- * 输 出 :无
- *******************************************************************************/
- void Timer2Int() interrupt 5 // 定时器0中断是1号
- {
- TF2 = 0;
- EX1=0;
- status = 5;//超时
- }
-
下面是用定时器的
- #include "ultrasonic.h"
-
- static void Delay15us() //@11.0592MHz
- {
- unsigned char i;
-
- _nop_();
- _nop_();
- i = 38;
- while (--i);
- }
-
- /*超声波触发*/
- void TrigUltrasonic()
- {
- TrigPin = 0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TrigPin = 1; //超声波模块Trig 控制端
- Delay15us();
- TrigPin = 0; //超声波模块Trig 控制端
- }
-
- /*====================================
- 函数名 :GetDistance
- 参数 :无
- 返回值 :获取距离单位毫米
- 描述 :超声波测距
- 通过发射信号到收到回响信号的时间测试距离
- 单片机晶振11.0592Mhz
- 注意测距周期为60ms以上
- ====================================*/
- unsigned int GetDistance()
- {
- double Time=0; //用于存放定时器时间值
-
- TH1=0; //清空定时器
- TL1=0;
-
- TrigUltrasonic(); //超声波触发
-
- while(EchoPin == 0); //判断回响信号是否为低电平
- TR1 = 1; //启动定时器1
-
- while(EchoPin == 1); //等待收到回响信号
- TR1 = 0; //关闭定时器1
-
- Time = (TH1*256 + TL1) * 1.085; //微秒
-
- return(Time * 0.017);//返回距离
- }
-
先交作业。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。