基于51的小车制作 pwm+蓝牙+lcd+ds1302+外部中断

基于51的小车制作 pwm+蓝牙+lcd+ds1302+外部中断

#include<reg51.h>
#include<intrins.h>
/*
按K3为蓝牙控制 01直行 01后退 03左转 04右转 05停止 06LCD计时开启 07计时停止 08计时清零 09调速
按K4为寻迹模式
按键时蜂鸣器发音提示
*/
typedef unsigned char u8;
typedef unsigned int u16;
#define lcd P0
sbit IN1=P1^1;
sbit IN2=P1^2;
sbit IN3=P1^3;
sbit IN4=P1^4;

sbit beep=P1^5;
sbit en1=P2^0;
sbit en2=P2^1;

sbit xunji1=P2^2;
sbit xunji2=P2^3;///右
sbit rw=P2^5;
sbit rs=P2^6;
sbit e=P2^7;
//P3^0,P3^1蓝牙
sbit key3=P3^2;
sbit key4=P3^3;
sbit io=P3^4; 
sbit ce=P3^5;   
sbit sclk=P3^6;  
u8 code read[3]={0x81,0x83,0x85}; //读的地址
u8 code write[3]={0x80,0x82,0x84};//秒分时日月周年,写的地址
u8 time[3]={0,0,0};//存读的数据
u8 qingling[3]={0,0,0};

u8 x=0,y=0,b,receive,c;

void yvchuli();//定时器,串口	t1 bps ;t0 pwm ;外部中断0,1

void zhixing();
void zuozhuan();
void youzhuan();
void houtui();
void tingzhi();

void lanya();//0x01直行 0x02后退 0x03左转 0x04右转

void Ds1302Init();
void Ds1302Write(u8 address, u8 date);
u8 Ds1302Read(u8 address);
void Ds1302ReadTime();

void lcdstart();
void busy();
void lcdwrite_command(u8 command);
void lcdwrite_date(u8 date);
void lcddisplay(u8 x,u8 y,u8 date);

void DS1302_LCD();//时钟显示

void delay(u16 t)        
{u8 a=120;
	while (t--)
	while(a--);
}

///***************************
//1302
//**************************/
void Ds1302Write(u8 address,u8 date)
{
	u8 n;
	ce=0;
	sclk=0;//
	ce=1; 
	for(n=0;n<8;n++)			//写地址
	{
		io=address & 0x01	;	//只保留1位
		address>>=1;				//右移一位
		sclk=1;						//写
		sclk=0;
	}
	for (n=0; n<8; n++)//写数据
	{
		io=date & 0x01;
		date>>=1;
		sclk=1;
		sclk=0;
	}	 
	ce=0;
}
u8 Ds1302Read(u8 address)
{
			u8 n,date,date1;
			ce=0;
			sclk=0;
			ce=1;
			for(n=0;n<8;n++)		//发地址
			{
				io=address & 0x01;
				address>>= 1;
				sclk= 1;
				sclk= 0;
			}
			for(n=0;n<8;n++)		//收数据
			{
				date1=io;
				date=(date>>1)|(date1<<7);//存入date中
				sclk=1;
				sclk=0;
			}
			ce=0;
			sclk=1;//保证1302稳定,必须的
			io=0;
			io=1;
			return date;	
}
void Ds1302ReadTime()//读时间
{
	u8 n;
	for(n=0;n<3;n++)//读取3个字节的时钟信号:分秒时
	{
		time[n]=Ds1302Read(read[n]);
	}
}
void Ds1302Init()
{
	u8 n;
	Ds1302Write(0x8E,0x00);		 //8E为写保护寄存器地址,00为不写保护
	for(n=0;n<3;n++)					 //
	{
		Ds1302Write(write[n],time[n]);	//地址加数据
	}
	Ds1302Write(0x8E,0x80);		 //开写保护
}
/****************1602**************/
void busy() 
{   u8 a;
    lcd=0xff;//引脚全接高电平
    do 
    {
        rs=0;
        rw=1;
        e=1;
        a=lcd;//硬件反应的数值赋给a
        a&=0x80;//判断第一位是否为1,不忙为0
    }
		while(a);
    e=0;  
}
void lcdwrite_command(u8 command)
{
	lcd=command;
	rs=0;
	rw=0;
	e=1;
	_nop_();
	e=0;
	busy();
}
void lcdstart()
{
	lcdwrite_command(0x38);//功能设定,8位数,双行,5*8
	lcdwrite_command(0x38);
	lcdwrite_command(0x0c);//显示开关控制,整体显示,无游标,不反白
	lcdwrite_command(0x06);//模式设置,在右边加数,整体不移动
	lcdwrite_command(0x01);//清除显示
	busy();
}
void lcdwrite_date(u8 date)
{
	lcd=date;
	rs=1;
	rw=0;
	e=1;
	_nop_();
	e=0;
	busy();
}
void lcddisplay(u8 x,u8 y,u8 date)
{
	u8 address;
	if(y==1)
    address=0x80+x;
  if(y==2)
		address=0xc0+x;
		lcdwrite_command(address);
    lcdwrite_date(date);
}

void DS1302_LCD()//时钟显示
{
		Ds1302ReadTime();//读出来时间放在time[]里
		lcdwrite_command(0x80);
		lcdwrite_date((time[2]>>4)|0x30);		
		lcdwrite_date((time[2]&0x0f)|0x30);//时
		lcdwrite_date('-');
		lcdwrite_date((time[1]>>4)|0x30);		//0x30是'0'的ASCII码
		lcdwrite_date((time[1]&0x0f)|0x30);//分
		lcdwrite_date('-');
		lcdwrite_date((time[0]>>4)|0x30);		//0x30是'0'的ASCII码
		lcdwrite_date((time[0]&0x0f)|0x30);//秒
}

void zhixing()
{
	IN1=1;
	IN2=0;
	IN3=1;
	IN4=0;
}
void zuozhuan()
{
	IN1=0;
	IN2=0;
	IN3=1;
	IN4=0;
}
void youzhuan()
{
	IN1=1;
	IN2=0;
	IN3=0;
	IN4=0;
}
void houtui()
{
	IN1=0;
	IN2=1;
	IN3=0;
	IN4=1;
}
void tingzhi()
{
	IN1=0;
	IN2=0;
	IN3=0;
	IN4=0;
}

void yvchuli()
{	
	TMOD|=0x01;//定时器0用来调速
	TH0=0xfc;
  TL0=0x18;
	ET0=1;
	TR0=1;
	
	IP=0x05;
	TMOD|=0x20;//定时器1调bps
	TL1=0xf3;
	TH1=0xf3;//波特率4800
	PCON=0x80;//SMOD=1,即使用倍频,原来为2400
	TR1=1;
	//ET1=0;
	SCON=0x50;//0101
	ES=1;//打开串口中断
	
	IT1=1;
	EX1=1;
	IT0=1;
	EX0=1;
	EA=1;
}

void lanya()
{
	switch(receive)
	{
		case(0x01):zhixing();break;
		case(0x02):houtui();break;
		case(0x03):zuozhuan();break;
		case(0x04):youzhuan();break;
		case(0x05):tingzhi();break;
		case(0x06):DS1302_LCD();break;
		case(0x07):Ds1302Init();break;
		case(0x08):time[0]=0;time[1]=0;time[2]=0;Ds1302Init();DS1302_LCD();break;
		case(0x09):x++;if(x==20)x=1;break;
		case(0x0a):y++;if(y==20)x=1;break;
		default:tingzhi();break;
	}
}
void xunji()
{
	if(xunji1==0)
		zhixing();
	if(xunji2==0)
		zhixing();
	if(xunji2==1)
		youzhuan();
	if(xunji1==1)
		zuozhuan();
}
void main()
{
	Ds1302Init();//1302写数据在初始化里
	lcdstart();
	yvchuli();
	while(1)
	{	
		if(c==1)
		{
			lanya();
		}
		if(c==2)
		{
			xunji();
		}
	}
}
void chuankou()interrupt 4
{
			receive=SBUF;//接收的数据在SBUF中存储
			RI=0;//软件清零,接收数据后硬件置1
			SBUF=receive;//两个SBUF不一样,这个是发送,上面是接受
			while(TI==0);//发送完后TI会硬件置1
			TI=0;//软件清零,为下次发数据做准备
}
void time0() interrupt 1
{
			b++;  
			if(b<20)			//共100*100=10ms
			{  
				if(b>=x)
				{en1=0;}	
				if(b<x)			//x越小越慢
				{en1=1;}		 //高电平时间x,低电平时间100-x
			}
			if(b<20)			//共100*100=10ms
			{  
				if(b>=y)
				{en2=0;}	
				if(b<y)			
				{en2=1;}		 
			}
			else
			{b=0;}	
			TH0=0xfc;
			TL0=0x18;
}
void waiduan0() interrupt 0
{		  u8 a=100;
			delay(10);
			if(key3==0)
			{	c=1;
				while(a--)
				{
					beep=~beep;
					delay(1);
				}
			}
			while(key3==0);
}
void waiduan1()interrupt 2
{	u8 a=100;
	delay(10);
	if(key4==0)
	{	c=2;
		while(a--)
		{
			beep=~beep;
			delay(1);
		}
	}
	while(key4==0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

静安书以沫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值