#include <reg52.h>
sbit TestPin =P1^0;
//循迹,四路循迹
//LS1 LS0 MS RS0 RS1
//sbit LS1 = P2^4;
sbit LSe0 = P2^3;
sbit RSe0 = P2^1;
//sbit RS1 = P2^0;
sbit LPWM0 = P1^2;
sbit LPWM1 = P1^3;
sbit RPWM0 = P1^4;
sbit RPWM1 = P1^6;
//全局变量
unsigned int Timer0Delay_cnt=0;
unsigned char LineStatus =0;//传感器状态,没有线,左,右,中,十字,T字,0,1,2,3,4,
unsigned char TrackLineTask =0 ;//循迹的任务标记,由按键设置=1,开始巡线
//蓝牙接收到字符,左,右,前进,后退,停止,调头,开始循迹
bit cmdflag_REC=0; //接收数据的标记位
bit cmdflag=0;
unsigned char cmdnum=0; //接收数据的个数
unsigned char cmddat=0; //接收的数据
unsigned char cmdbuff[5]=0; //接收缓冲字
char cmdlist =0; //1 ,停止,2,前进,3左,4右,5后退,串口命令表
//蓝牙
char LPWM0Set=0;
char LPWM1Set=0;
char RPWM0Set=0;
char RPWM1Set=0;
void delay(int tms) //20ms
{
int i,j;
for(i=0;i<tms;i++)
{
for(j=0;j<110;j++);
}
}
void main()
{
TMOD=0x11; //定时器 0 工作在模式 1,16 位定时模式
TH0 = 0xFF; //100us
TL0 = 0x0B;
TH1=(65535-10)/256; //定时 10us
TL1=(65535-10)%256;
ET0=1;//打开定时器0中断开关
ET1=1;//打开定时器0中断开关
//***********定时器2作为波特率9600
TL2 = RCAP2L=(65536-(11059200L /32/9600));
//9600 波特率对应 FFD9,低位为 D9(65536-26)%256
TH2 = RCAP2H=(65536-(11059200L /32/9600)) >> 8;
// 高 位 为FF(65536-26)/256
T2CON=0x34;//RCLK、TCLK、TR2 置 1
SCON=0x50;//串口工作模式 1,接收使能
TI=1;
ES=1;
EA=1;//打开总中断开关
TR0=1;//打开定时器
TR1=1;//打开定时器
while(1)
{ //正转
if(cmdlist ==1)
{
LPWM0Set =10;
LPWM1Set =10;
RPWM0Set =10;
RPWM1Set =10;
}
else if(cmdlist ==2)
{
LPWM0Set =0;
LPWM1Set =0;
RPWM0Set =0;
RPWM1Set =0;
}
}
}
/* 定时器0中断函数,定时器0的中断优先级,默认比定时器1的要高,除非额外设置 */
void tm0_isr() interrupt 1 using 1
{
static unsigned int cnt_tim0=0; //静态变量,只定义一次。
TH0 = 0xF8; //65535-2000===3.3ms
TL0 = 0x2F;
cnt_tim0++; //
Timer0Delay_cnt++;
if(cnt_tim0%2==0)//3.3ms*2=6.6ms,读取一次IO口状态,循迹
{
if(LSe0 ==1 )
{
LineStatus =0;
}
else if(LSe0 ==0 )
{
LineStatus =1;
}
}
if(cnt_tim0%4==0)//3.3ms*4=13.2ms,做一次循迹,读取一次串口数据,
{
if(TrackLineTask ==1) //如果是巡线任务,进行判断
{
switch( LineStatus)
{
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:break;
}
}
if(cmdflag_REC==1) //
{
cmdflag_REC=0;
if(cmdbuff[0]=='0'&&cmdbuff[1]=='n')
//第一个字节为 0,第二个字节为 n,第三个字节为控制码,手机端发送的应该是 0nb 等
switch(cmdbuff[2])
{
case 'f' :
//小车前进
cmdlist=1;
break;
case 'b':
// 后退 backxxx
break;
case 'l':
// 左转 leftxxx
break;
case 'r':
// 右转 rightxx
break;
case 's':
// 停止 stopxxx
cmdlist=2;
break;
default:break;
}
}
//**********************20ms刷新LCD1602的数据,速度和行程
if(cnt_tim0%6==0)
{
}
if(cnt_tim0 >1000)cnt_tim0=0;
}
}
//定时器1中断函数,产生4路的PWM,最大是20个toc
void tm1_isr() interrupt 3
{
static char cnt00=0;
TH1=0xFF;
TL1=0x50;
cnt00++;
//决定PWM的周期,也就是频率,
if(cnt00>=20)
{
cnt00=0;
}
//输出PWM
if(cnt00<LPWM0Set)//1s=1000ms 20ms
{
LPWM0=1;
}
else
{
LPWM0=0;
}
//输出PWM
if(cnt00<LPWM1Set)//1s=1000ms 20ms
{
LPWM1=1;
}
else
{
LPWM1=0;
}
//输出PWM
if(cnt00<RPWM0Set)//
{
RPWM0=1;
}
else
{
RPWM0=0;
}
//输出PWM
if(cnt00<RPWM1Set)//
{
RPWM1=1;
}
else
{
RPWM1=0;
}
}
//串口1中断函数,
void UartIsr() interrupt 4 using 1
{
if(RI) //是否接收中断
{
RI=0;
cmddat=SBUF;
if(cmddat=='0'&&(cmdnum==0)) //接收数据第一帧
{
cmdbuff[cmdnum]=cmddat;
cmdflag=1; //开始接收数据
}
else
if(cmdflag==1) //如果不是第一个数据,说明帧头校验通过,就继续接收,
{
cmdnum++;
cmdbuff[cmdnum]=cmddat;//0---1--2--0
if(cmdnum>=2)
{
cmdnum=0;
cmdflag=0;
cmdflag_REC=1;// 停止接收
}
}
}
}
51单片机 蓝牙 循迹 ,定时器产生4个PWM
最新推荐文章于 2024-05-22 10:00:00 发布