#include<stc8a8k.h>
#include<oled.h>
#include<delay.h>
#include<stdio.h>
#include "hpwm.h"
//***************************************************************************下面是接线定义
//左电机
sbit LPWM=P2^0;//电机调节速度的信号
sbit LA2=P0^4;
sbit LA1=P0^5;
//右电机
sbit RPWM=P2^1;
sbit RA2=P0^6;
sbit RA1=P0^7;
//接传感器
sbit L1S=P1^0;
sbit L0S=P1^1;
sbit MS=P1^2;
sbit R0S=P1^3;
sbit R1S=P1^4;
//*************************************
sbit key=P3^4;//接按键
sbit beep=P0^3;//接蜂鸣器
sbit led=P0^0;//接LED报警灯
//****************************************************************************下面是全局变量的定义,每个函数都能使用
//定义黑白线的信号,根据实际模块定义,1是高电平,0是低电平,后面如果换模块,
//不同模块的情况不一样,有些是碰到黑线是1,有些是0,就很容易修改
unsigned char blackline=1;
unsigned char whiteline=0;
unsigned char startflag=0;
//这里定义变量,后面如果小车需要调节速度,比较方便修改,直接改这里就好了。
float vleftmove=0.4;
float vrightmove=0.4;//直线行走的速度
float vturnbig=0.55;
float vturnsmall=0.25;//转弯的速度差速度,一个是大,一个小,小转弯差速度
float vturnbigM=0.75;
float vturnsmallM=0.1;//转弯的速度差速度,大转弯差速度
unsigned int maichongnum=0;//脉冲个数
float zhouchang=2.04;//小车直径65mm,3.14*65=204.2mm=2.04cm
float distance=0.1;
unsigned int miao=0,fen=0,countT0num=0;
unsigned char disbuf[9];//给显示用
//**************************************************************************************************下面是子函数的定义、或者声明
//循迹函数声明,先声明后定义,不然main都不知道有这个函数,在main函数后面定义具体程序代码
//****************************************************************子函数0:函数声明;void trackline0();
void trackline0();
//****************************************************************子函数1:qianjin(float vleft,float vright)
//这个是定义,不声明,后面main函数可以直接用,
//小车前进,根据速度两个轮子速度差,进行前进,转弯等
void qianjin(float vleft,float vright)
{
HPWM_Set(0,8000,vleft);
LA2=1;
LA1=0;
HPWM_Set(1,8000,vright);
RA2=1;
RA1=0;
}
//****************************************************************子函数2:void back(float vleft,float vright)
//小车后退程序,一个轮子正转,一个反转
void back(float vleft,float vright)
{
HPWM_Set(0,8000,vleft);
LA2=0;
LA1=1;
HPWM_Set(1,8000,vright);
RA2=1;
RA1=0;
}
//****************************************************************子函数3:void stop()
//小车停止
void stop()
{
LA2=0;
LA1=0;
RA2=0;
RA1=0;
}
//*****************************************************************************************************下面是主函数
//*******************************************主函数
void main()
{
//每个外设,比如按键,屏幕,PWM等内部资源的初始化,配置一下环境
OLED_Init();
HPWM_Init();
OLED_ShowString(0,0,"Start,Please...");
//外部脉冲计算走过的距离,初始化
//使能INT1中断
//定时器0初始化,计算启动的之后运行的时间//5毫秒@11.0592MHz
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
ET0 = 1;
EA=1;
//*****************************************************************
//*********************************************正式执行程序
while(1)
{
OLED_ShowNum(0,4,miao,5,12);
distance=maichongnum*0.05*zhouchang;
sprintf(disbuf,"%0.2f",distance);
OLED_ShowString(0,2, disbuf);
//*****************************
//检测按键是不是按下,开始启动
if(key==0)
{
delay_tms(10);//延时去抖动
if(key==0)
{
startflag=1;
OLED_ShowString(0,0,"running,GO,GO...");
stop();
delay_tms(2000);//延时,按下两秒之后,小车开始启动进行循迹
OLED_Clear();
IT1 = 1; //使能INT1下降沿中断
EX1 = 1;
TR0 = 1; //定时器0开始计时
}
}
//**********************如果开始标记等于1,说明按下启动键,这时候小车才开始跑
if(startflag==1)
{
//开始循迹,请看这部分代码,太长了,单独拉出来写,方便看主程序逻辑
trackline0();
}
}
}
//***********************************下面是前面声明的函数的定义
//**************************************************************//函数定义trackline0();
//**************************************************************功能:按键循迹;
void trackline0()
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第1种情况
if(L1S==blackline &&L0S==whiteline && MS==whiteline && R0S==whiteline&& R1S==whiteline)//1 0 0 0 0
{
qianjin(vturnsmallM,vturnbigM);//左da转弯,转到碰到中线停止
while(1)
{
if(MS==blackline)break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第2种情况
else if(L1S==whiteline &&L0S==blackline && MS==whiteline && R0S==whiteline&& R1S==whiteline)//0 1 0 0 0
{
qianjin(vturnsmall,vturnbig);//左xiao转弯
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第3种情况
else if(L1S==whiteline &&L0S==whiteline && MS==blackline && R0S==whiteline&& R1S==whiteline)//00 1 0 0
{
qianjin(vleftmove,vleftmove);//直走
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第4种情况
else if(L1S==whiteline &&L0S==whiteline && MS==whiteline && R0S==blackline&& R1S==whiteline)//0 0 0 1 0
{
qianjin(vturnbig,vturnsmall);//左xiao转弯vturnbig vturnsmall
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第5种情况
else if(L1S==whiteline &&L0S==whiteline && MS==whiteline && R0S==whiteline&& R1S==blackline)//0 0 0 0 1
{
qianjin(vturnbigM ,vturnsmallM);//左da转弯vturnbigM vturnsmallM,碰到黑线,不然一直大转弯
while(1)
{
if(MS==blackline)break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第6种情况
else if(L1S==blackline && L0S==blackline && R1S==whiteline )//11xx0 判断是左转90度
{
stop();
delay_tms(500);
qianjin(vturnsmall,vturnbig);//左转弯
delay_tms(100);
while(1)
{
if(R0S==blackline)break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第7种情况
else if( L1S==whiteline &&R0S==blackline && R1S==blackline)//0xx11 判断是右转90度
{
stop();
delay_tms(1000);
qianjin(vturnbig,vturnsmall);//
delay_tms(10);
while(1)
{
if(L0S==blackline)break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第8种情况
else if(L1S==blackline &&L0S==blackline&& MS==blackline && R0S==blackline)//1111x 判断是终点,调头
{
qianjin(vleftmove,vleftmove);
delay_tms(500);
stop();
delay_tms(1000);
back(vleftmove,vleftmove);
delay_tms(500);
while(1)//如果中间的传感器碰到黑线,就跳出循环
{
if(MS==blackline)break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++第9种情况 这是极端情况,放在最后面判断
else if(L1S==whiteline &&L0S==whiteline && MS==whiteline && R0S==whiteline && R1S==whiteline)//000找不到直线,如如果前面是直走,就转360度,如果是之前右边,就左转,之前左偏,就右转
{
qianjin(vturnbig,vturnsmall);//
}
}
//****************************************************************************外部中断,测量脉冲
void INT1_Isr() interrupt 2 using 1
{
maichongnum++; //测试端口
}
//**************************************************************************定时1s,更新刷新屏幕数据
void TM0_Isr() interrupt 1 using 1
{
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
countT0num++;//50ms加一次
if(countT0num==20)//1秒时间到
{
countT0num=0;
miao++;
if(miao==600)
miao=0;
}
}
循迹+计时+测速+显示
最新推荐文章于 2023-11-02 00:00:00 发布
该博客详细介绍了基于STM32的循迹机器人控制系统设计,包括电机控制、传感器信号处理和循迹算法。通过设置不同的传感器状态,实现小车的转弯、直行和避障功能。同时,利用外部中断计算行驶距离,并通过定时器更新显示屏数据。代码中还实现了按键启动和停止功能,以及小车的动态调整速度。
摘要由CSDN通过智能技术生成