目录
1.串口控制小车
2.循迹小车
3.避障小车
1.串口控制小车
L9110s概述
接通VCC,GND 模块电源指示灯亮, 以下资料来源官方,但是不对,根据下节课实际调试
IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转;
IA1输入低电平,IA1输入高电平,【OA1 OB1】电机反转;
IA2输入高电平,IA2输入低电平,【OA2 OB2】电机正转;
IA2输入低电平,IA2输入高电平,【OA2 OB2】电机反转;
共6个文件
main.c
#include "reg52.h"
#include "intrins.h"
#include "motor.h"
#include "delay.h"
#include "timer.h"
#include "uart.h"
#include "Vehicle_steering.h"
extern char v_left; //设置左轮的速度,最小10最大40
extern char v_right; //设置右轮的速度,最小10最大40
void main(void)
{
Timer0_Init(); //不能重复初始化定时器,定时器的中断又先后会错误
Timer1_Init();
init_usb(); //串口初始化
while(1){
stop();
}
}
motor.c
#include "reg52.h"
sbit rightcon1A=P3^2;
sbit rightcon1B=P3^3;
sbit leftcon1A=P3^5;
sbit leftcon1B=P3^4;
void leftmotor_forward()
{
leftcon1A=0;
leftcon1B=1;
}
void leftmotor_backward()
{
leftcon1A=1;
leftcon1B=0;
}
void leftmotor_stop()
{
leftcon1A=1;
leftcon1B=1;
}
// 右轮的
void rightmotor_forward()
{
rightcon1A=0;
rightcon1B=1;
}
void rightmotor_backward()
{
rightcon1A=1;
rightcon1B=0;
}
void rightmotor_stop()
{
rightcon1A=0;
rightcon1B=0;
}
delay.c
#include "intrins.h"
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
timer.c
#include "reg52.h"
#include "motor.h"
char left_num=0; //计次
char v_left;
char right_num=0; //计次
char v_right;
void Timer0_Init(void) //500微秒@11.0592MHz 的定时器0
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式 16位计数
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //打开总中断
ET0=1; //打开定时器0的中断
}
void Timer0_rountinr(void) interrupt 1 //每0.5ms进入一次中断1
{
left_num++;
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
if(left_num<=v_left){ //
leftmotor_forward();
}else{ //
leftmotor_stop();
}
if(left_num==40){ //满
left_num=0;
}
}
void Timer1_Init(void) //500微秒@11.0592MHz 的定时器1
{
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式 16位计数
TL1 = 0x33; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA=1; //打开总中断
ET1=1; //打开定时器1的中断
}
void Timer1_rountinr(void) interrupt 3 //每0.5ms进入一次中断1
{
right_num++;
TL1 = 0x33; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
if(right_num<=v_right){ // 小于脉冲宽度时设置为高电平
rightmotor_forward();
}else{ //大于脉冲宽度时设置为低电平
rightmotor_stop();
}
if(right_num==40){ //满足一个总脉冲宽度重置
right_num=0;
}
}
uart.c
#include "reg52.h" //超声波控制LED
#include "string.h"
#include "Vehicle_steering.h"
#include "delay.h"
sfr AUXR=0x8e;
sbit led1=P3^6;
sbit led2=P3^7; //蓝色
char cmd[7];
void UART_Rountine(void) interrupt 4
{
static int i=0;
char tmp;
/*if(TI){ //发送了数据
}*/
if(RI){ //接受外部数据后产生中断 进入interrupt 4
RI=0;
tmp=SBUF;
if(tmp=='M'){ //M始终放置在第0位
i=0;
}
cmd[i++]=tmp;
if(cmd[0]=='M' && cmd[1]=='1'){
led2=~led2; //蓝色的灯
goforward();
Delay500ms();
//memset(cmd,'\0',7);
}
if(cmd[0]=='M' && cmd[1]=='2'){
backward();
Delay500ms();
//memset(cmd,'\0',7);
}
if(cmd[0]=='M' && cmd[1]=='3'){
turnleft();
Delay500ms();
//memset(cmd,'\0',7);
}
if(cmd[0]=='M' && cmd[1]=='4'){
turnright();
Delay500ms();
//memset(cmd,'\0',7);
}
if(cmd[0]=='M' && cmd[1]=='5'){
stop();
Delay500ms();
//memset(cmd,'\0',7);
}
if(i==7){
i=0;
led1=~led1; //黄色的灯 按7下倒是进入了这里
}
}
}
void init_usb(void)
{
SCON=0x50;//采用工作方式1进行通讯 不用改
//PCON &= 0x7F; //要清0就 &上0 不用改
ET2=0;//串口用的定时器2,关闭中断。配置相同的波特率 已改
//TCON 定时器控制寄存器 T2con=0x34
//TR2=1; //打开定时器2 已改
T2CON=0x34; //设置了定时器2作为串行口波特率配置器
//TMOD? 定时器0和1模式寄存器 要多少位的定时器
//TMOD &=0x0F; //&0就清0
//TMOD |=0x20; // |1就变1
TL2=RCAP2L=0xFFDC; //高位? ? ? 自动重装时TH2将自动装入TL2 已改
TH2=RCAP2H=0xFFDC>>8; //低位 已改
//TI 中断请求标志位 RI中断请求标志位
EA=1;ES=1; //总中断允许位 串口中断允许位
}
Vehicle_steering.c
#include "motor.h"
extern char v_left; //设置左轮的速度,最小10最大40
extern char v_right; //设置右轮的速度,最小10最大40
void goforward(void)
{
v_left=30;
v_right=30;
}
void turnleft(void)
{
v_left=20;
v_right=40;
}
void turnright(void)
{
v_left=40;
v_right=20;
}
void backward(void)
{
leftmotor_backward();
rightmotor_backward();
}
void stop(void)
{
v_left=0;
v_right=0;
}
2.循迹小车
循迹模块使用
TCRT5000传感器的红外发射二极管不断发射红外线
当发射出的红外线没有被反射回来或被反射回来但强度不够大时,
红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态
被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,
此时模块的输出端为低电平,指示二极管被点亮
总结就是一句话,没反射回来,D0输出高电平,灭灯
接线方式
VCC:接电源正极(3-5V)
GND:接电源负极
DO:TTL开关信号输出0、1
AO:模拟信号输出(不同距离输出不同的电压,此脚一般可以不接)
只用更改main.c的代码
main.c
#include "reg52.h"
#include "intrins.h"
#include "motor.h"
#include "delay.h"
#include "timer.h"
#include "uart.h"
#include "Vehicle_steering.h"
sbit left_infrared_ray=P2^6;
sbit right_infrared_ray=P2^7;
extern char v_left; //设置左轮的速度,最小10最大40
extern char v_right; //设置右轮的速度,最小10最大40
void main(void)
{
Timer0_Init(); //不能重复初始化定时器,定时器的中断又先后会错误
Timer1_Init();
init_usb(); //串口初始化
while(1){
if(left_infrared_ray==0 && right_infrared_ray==0){
//红外能返回,IO口输出低电平,灯亮,直走
goforward();
}
if(left_infrared_ray==1 && right_infrared_ray==0){
turnright();
}
if(left_infrared_ray==0 && right_infrared_ray==1){
turnleft();
}
if(left_infrared_ray==1 && right_infrared_ray==1){
stop();
}
}
}
3.避障小车
前方距离很小时,舵机上的测距模块测量左、右的距离,判断那边距离大,则左转或者右转。
main.c
#include "reg52.h" //超声波控制LED
#include "vehicle_steering.h"
#include "intrins.h"
#define left_sg 4
#define middle_sg 3
#define right_sg 2
sbit trig=P1^5; //超声波控制信号
sbit eoch=P1^6;
sbit sim_pmw=P1^1; //舵机PWM 黄色PWM信号 红色VCC 灰色GND
sbit led1=P3^6;
sbit led2=P3^7;
double time,distance,left_distance,right_distance;
//int num; //计数
int plus_width;
int num=0;
void Delay10us(); //延时10us
void Delay500ms(); //延时500ms
void Delay150ms(); //延时150ms
void Delay2000ms(); //延时2s
void Timer1_Init(void); //给一个定时器1@11.0592MHz
void Timer0_Init(void);
double distance_measure(void); //用超声波检测是否开盖
void main()
{
//1,给trig一个触发信号
//2.当eoch变为1的时候开始计时
//3,当eoch变为0的时候结束计时
//4. 计算距离=时间X速度
Timer1_Init(); //配置定时器1 //计算距离
Timer0_Init(); //配置定时器0 //模拟PWM
while(1){
plus_width=middle_sg; //舵机保持在中间位置
distance=distance_measure(); //用超声波检测是否到达某个距离 distance <10
if(distance>35 ){ //距离大于35cm
goforward();
}else if(distance<10){ //距离小于10cm
backward();
}else{ //中等距离 测距转向
stop();
plus_width=left_sg; //舵机左转
Delay500ms();
left_distance=distance_measure();
plus_width=right_sg; //舵机右转
Delay500ms();
right_distance=distance_measure();
if(left_distance<=right_distance){
turnright();
Delay150ms();
stop();
}
if(left_distance>right_distance){
turnleft();
Delay150ms();
stop();
}
}
}
}
double distance_measure(void)
{
trig=0; //1,给trig一个触发信号
trig=1;
Delay10us();
trig=0;
while(eoch==0); //2.当eoch变为1的时候开始计时
TR1=1;
while(eoch==1); //3,当eoch变为0的时候结束计时
TR1=0;
TF1 =0; //清除TF0标志
time=(TH1*256+TL1)*1.085; //单位是s
distance=time*0.017; //单位是cm
TL1 = 0; //设置定时初始值
TH1 = 0; //设置定时初始值
return distance;
}
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay150ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 2;
j = 13;
k = 237;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Timer1_Init(void) //@11.0592MHz 计算距离
{
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式
TL1 = 0; //设置定时初始值
TH1 = 0; //设置定时初始值
//TF1 = 0; //清除TF0标志
}
void Timer0_Init(void) //0.5ms@11.0592MHz //模拟PWM
{
//定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //打开总中断
ET0=1; //定时器0中断
}
void Timer0_rountinr(void) interrupt 1 //每0.5ms进入一次定时器0的中断
{
num++;
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE; //设置定时初始值
if(num<=plus_width){ // 小于脉冲宽度时设置为高电平
//plus_width就是角度1是0度,2是45度 3是90度 4是135度 5是180°
sim_pmw=1;
}else{ //大于脉冲宽度时设置为低电平
sim_pmw=0;
}
if(num==40){ //满足一个总脉冲宽度重置
num=0;
}
}
motor.c
#include "reg52.h"
sbit rightcon1A=P3^2;
sbit rightcon1B=P3^3;
sbit leftcon1A=P3^5;
sbit leftcon1B=P3^4;
void leftmotor_forward()
{
leftcon1A=0;
leftcon1B=1;
}
void leftmotor_backward()
{
leftcon1A=1;
leftcon1B=0;
}
void leftmotor_stop()
{
leftcon1A=1;
leftcon1B=1;
}
// 右轮的
void rightmotor_forward()
{
rightcon1A=0;
rightcon1B=1;
}
void rightmotor_backward()
{
rightcon1A=1;
rightcon1B=0;
}
void rightmotor_stop()
{
rightcon1A=0;
rightcon1B=0;
}
vehicle_steering.c
#include "motor.h"
void goforward(void)
{
leftmotor_forward();
rightmotor_forward();
}
void turnleft(void)
{
leftmotor_stop();
rightmotor_forward();
}
void turnright(void)
{
leftmotor_forward();
rightmotor_stop();
}
void backward(void)
{
leftmotor_backward();
rightmotor_backward();
}
void stop(void)
{
leftmotor_stop();
rightmotor_stop();
}