51单片机 蓝牙 循迹 ,定时器产生4个PWM

#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;// 停止接收
					}
			}
		
		}
	}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值