[Graduation project] 3-Single-chip microcomputer-based bus intelligent broadcast arrival station operation position indication system (schematic diagram + source code + thesis)

[Graduation project] 3-Single-chip microcomputer-based bus intelligent broadcast arrival station operation position indication system (schematic diagram + source code + thesis)

mission statement

The main research content: bus GPS positioning system (principle and implementation method) and bus station; stop sign display system (hardware schematic diagram, PCB diagram, software process and program code displayed by single-chip microcomputer).

The requirements of this bus operation position indication system are summarized as follows:
more service terms and advertisement words can be stored;
the operation is required to be simple, and all station announcement content can be automatically broadcast at each stop;
LCD station information display is required;
voice broadcast is required It has two functions of automatic and manual;
it is required that the stop sign information and service information can be displayed through the LCD screen;
the time, calendar broadcast, display and adjustment functions.
Data link
Schematic project file
Source code project file
Paper low repetition rate, 21355 words
Schematic screenshot

design manual

Summary

In this paper, STC89C52 MCU is used as the main controller, GPS is used as the global positioning chip to ensure the real-time location of the bus, DS1302 is used as the clock chip of the system, and LCD12864 is used as the liquid crystal display of the system to display the clock information, platform information and prompts inside the bus etc. Realize the voice broadcast function through the voice chip. Through the circuit design and software system design of the system to ensure the realization of the system's functions and bring convenience to people's transportation. It solves the problems of inconvenient manual operation of the previous bus station reporting system, many false reporting stations, and no station reporting when there is a breakdown.

Design framework

Preface 1
Chapter 1 Introduction 2
Section 1 Research background 2
Section 2 Domestic and foreign development trends 2
1. Overseas development trends 2
2 Domestic development trends 3 Section
3 Main research content of this paper 3
Section 4 Summary of this chapter 4
Section Chapter 2 System Scheme Design 5
Section 1 System Needs Analysis 5
Section 2 System Design Function Analysis 5
Section 3 System Design Scheme 6 Section 4
Summary of This Chapter 7 Chapter
3 System Hardware Circuit Design 8 Section 1
Minimum System Circuit Design of Single Chip Microcomputer 8
1. Introduction to MCU 8
2. Minimum System Circuit Design of MCU 9
Section 2 Power Circuit Design 10
Section 3 Button Circuit Design 10
Section 4 LED Circuit Design 11
Section 5 Liquid Crystal Display Circuit Design 12
Section 6 GPS Circuit Design 14
Section 7 Voice Broadcast Circuit Design 15
Section 8 Clock Circuit Design 16
Section 9 System General Circuit Diagram 17
Section 10 System PCB Design 18
Section 11 Summary of This Chapter 18 Chapter 4
Software System Design 20
Section 1 Keil Software Introduction 20
Section 2 Software Design Process 20
Section 3 LCD Program Design 22
Section 4 GPS Program Design 23
Section 5 Clock Program Design 26
Section 6 Speech Broadcast Program Design 27
Section 7 Summary of This Chapter 28
Summary 30
Acknowledgments 32
References 33 Appendix 35 1. Original English 35
2. English Translation 38 3. Source Code 41


Design instructions and design documents

insert image description here
insert image description here
insert image description here
Paper with low repetition rate, 21355 wordsinsert image description here

Source code display

#include <reg51.H>
#include "LCD12864.h"
#include "1302.h"
#include "60S2EEPROM.h"		
//站点   GPS				  
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
sbit key5=P1^4;
sbit key6=P1^5;
sbit key7=P1^6;
sbit key8=P1^7;		//定义按键IO
sbit led0=P3^4;
sbit led1=P3^5;
sbit led2=P3^6;
sbit led3=P3^7;	 	//定义指示灯IO
sbit Music_Busy=P3^2;	  //定义
bit key1_flag=0;
bit key2_flag=0;
bit key3_flag=0;
bit key4_flag=0;
bit key5_flag=0;
bit key6_flag=0;
bit key7_flag=0;
bit key8_flag=0;    //定义按键位变量
uchar Station_Count=1;	 
sbit Busy=P3^2;
bit position=0;
bit Display_Reversal=0;
uchar state=0;		//显示变量
bit s0=0;		    //数据闪烁变量
uchar ms=0;			//定时器用到的变量
//发现两个Bug一个是自动下,到终点站没有自动切换上行、下行
//一个是  自动下 上行站名和语音不照应
uchar sec=0;
uchar sec1=0;
bit memory_flag=0;
uchar Sound=25;			//音量大小变量
uchar Station=10;		//车站总数变量
bit Mode=0;			    //等于0代表固化    等于1代表自定义
bit A_M=0;
bit Upstream_Down=1;
uchar count=0;
uint JD_Difference=100;	 //34.800340,113.499447
uint WD_Difference=100;
//这里预存上行经纬度数据
ulong xdata shangxing_JD_dat[15]={113499052  ,113499041   ,113499048   ,113499059   ,113499064   ,113499064  ,113499096  ,113499091 ,113499080  ,113499085 ,0,0,0,0,0};
ulong xdata shangxing_WD_dat[15]={ 34807299  ,34806564    ,34805795    ,34804901    ,34804046    ,34803403   ,34802381   ,34801711   , 34800910  , 34800152  ,0,0,0,0,0};
//这里预存下行经纬度数据
ulong xdata xiaxing_JD_dat[15]={113499447  ,113499447 ,113499457,   1134994359,   113499451,   113499408,   113499418,   113499391,  113499380,  113499395,   0,0,0,0,0};
ulong xdata xiaxing_WD_dat[15]={347996375   ,34800340, 34800869,   34801600,       34802233,    34802969,    34803852,    34804724,   34805649,   34806550,    0,0,0,0,0};
bit Sound_flag=1;
uchar code xiaxing1[] ="  测试下行A站  ";
uchar code xiaxing2[] ="  测试下行B站 ";
uchar code xiaxing3[] ="  测试下行C站 ";
uchar code xiaxing4[] ="  测试下行D站 ";
uchar code xiaxing5[] ="  测试下行E站 ";
uchar code xiaxing6[] ="  测试下行F站 ";
uchar code xiaxing7[] ="  测试下行G站 ";
uchar code xiaxing8[] ="  测试下行H站 ";
uchar code xiaxing9[] ="  测试下行I站 ";
uchar code xiaxing10[]="  测试下行J站 ";
uchar code xiaxing11[]="    测试上行11  ";
uchar code xiaxing12[]="    测试上行12  ";
uchar code xiaxing13[]="    测试上行13  ";
uchar code xiaxing14[]="    测试上行14  ";
uchar code xiaxing15[]="    测试上行15  ";
uchar code shangxing1[] ="  测试下行J站 ";
uchar code shangxing2[] ="  测试下行I站 ";
uchar code shangxing3[] ="  测试下行H站 ";
uchar code shangxing4[] ="  测试下行G站 ";
uchar code shangxing5[] ="  测试下行F站 ";
uchar code shangxing6[] ="  测试下行E站 ";
uchar code shangxing7[] ="  测试下行D站 ";
uchar code shangxing8[] ="  测试下行C站 ";
uchar code shangxing9[] ="  测试下行B站 ";
uchar code shangxing10[]="  测试下行A站 ";
uchar code shangxing11[]="    测试下行11  ";
uchar code shangxing12[]="    测试下行12  ";
uchar code shangxing13[]="    测试下行13  ";
uchar code shangxing14[]="    测试下行14  ";
uchar code shangxing15[]="    测试下行15  ";
uchar xdata A_dat[20];	 //暂存从GPS提取的经纬度数据
uchar xdata B_dat[20];	 //暂存从GPS提取的经纬度数据
uchar xdata GPS_dat[100];//暂存GPS模块返回的数据
uchar subscript;		 //串口数据计数变量
uchar GPS_time=0;		    //检测GPS是否接收到有效数据变量
float latitude,longitude;   //latitude是暂存纬度, longitude是暂存经度数据,这两个数据,是上面的暂存数组计算得到
unsigned long WD_A,JD_B;  //这两个变量,是最终现实与进行比较的经纬度数据变量
bit GPS_Write=0;		    //是否开启GPS校时更新时间数据标志位
uchar xdata NowTime[7]=0;	//从GPS返回的数据里面提取出时间数据
bit memory_GPS_flag=1;
uchar Sec_set=0;
uchar Time_Calibration=0;   //校准时间标志位
void memory()
 {
   if(memory_flag) 
    {
	  memory_flag=0;
	  IapEraseSector(0x08000);
	  IapProgramByte(0x08000,Sound);		       //记录音量大小变量

	  IapProgramByte(0x08001,Station);	       //记录车站总数

	  if(GPS_Write)IapProgramByte(0x08002,1);   //记录自动校时标志  GPS_Write=1,就记录为1
      else IapProgramByte(0x08002,0);           //记录自动校时标志  GPS_Write=0,就记录为0
 	
	  if(Mode)IapProgramByte(0x08003,1);        //记录固化还是自定义  Mode=1,就记录为1
      else IapProgramByte(0x08003,0);           //记录固化还是自定义  Mode=0,就记录为0  

	  if(A_M)IapProgramByte(0x08004,1);         //记录手动自动模式  A_M=1,就记录为1
      else IapProgramByte(0x08004,0);           //记录手动自动模式  A_M=0,就记录为0  
 if(Upstream_Down) IapProgramByte(0x08005,1);  //记录上行下行  Station_Count=1,就记录为1
      else              IapProgramByte(0x08005,0);  //记录上行下行  Station_Count=0,就记录为0   
//	  IapProgramByte(0x08006,shangxing_JD_dat[0]/65536/256);
//	  IapProgramByte(0x08006,shangxing_JD_dat[0]/65536%256);
//	  IapProgramByte(0x08006,shangxing_JD_dat[0]%256);
	}
 }
void read_memory()
 {
   	Sound=IapReadByte(0x08000);	   //读取的记录音量大小变量
//	Station=IapReadByte(0x08001);   //读取的记录车站总数

	if(Sound>30||Station>15) 	   //如果读取出来的数据不对,就进行初始化
	 {
	   Sound=25;
	   Station=5;
	 }
    if(IapReadByte(0x08002)!=0&&IapReadByte(0x08002)!=1) //读取GPS校时标志位
	 {
	   	GPS_Write=1;								   //如果读取不对,默认打开
	 } else  GPS_Write=IapReadByte(0x08002);			   //如果对,进行赋值
    if(IapReadByte(0x08003)!=0&&IapReadByte(0x08003)!=1) //读取存储的
	 {
	  	Mode=0;
	 }else  Mode=IapReadByte(0x08003);
    if(IapReadByte(0x08004)!=0&&IapReadByte(0x08004)!=1) 
	 {
	  	A_M=0;
	 }else  A_M=IapReadByte(0x08004);

    if(IapReadByte(0x08005)!=0&&IapReadByte(0x08005)!=1) 
	 {
	  	Upstream_Down=0;
	 }else  Upstream_Down=IapReadByte(0x08005);
     memory_flag=1;									   //将读取的数据再次存储
 }
void memory_GPS()
 {
   	  unsigned char i=0;
	  if(memory_GPS_flag)
	   {	
	        memory_GPS_flag=0;
			IapEraseSector(0x08200);
			for(i=0;i<60;i++)		    	   
			 {
				if(i<15) 
				 {
					IapProgramByte(0x08200+i*4,shangxing_JD_dat[i]/16777216%256);
					IapProgramByte(0x08200+i*4+1,shangxing_JD_dat[i]/65536%256);
					IapProgramByte(0x08200+i*4+2,shangxing_JD_dat[i]/256%256);
					IapProgramByte(0x08200+i*4+3,shangxing_JD_dat[i]%256);
				 }
				 else if(i<30) 
				  {
					IapProgramByte(0x08200+i*4,shangxing_WD_dat[i-15]/16777216%256);
					IapProgramByte(0x08200+i*4+1,shangxing_WD_dat[i-15]/65536%256);
					IapProgramByte(0x08200+i*4+2,shangxing_WD_dat[i-15]/256%256);
					IapProgramByte(0x08200+i*4+3,shangxing_WD_dat[i-15]%256);
				  }
				 else if(i<45) 
				  {
					IapProgramByte(0x08200+i*4,xiaxing_JD_dat[i-30]/16777216%256);
					IapProgramByte(0x08200+i*4+1,xiaxing_JD_dat[i-30]/65536%256);
					IapProgramByte(0x08200+i*4+2,xiaxing_JD_dat[i-30]/256%256);
					IapProgramByte(0x08200+i*4+3,xiaxing_JD_dat[i-30]%256);
				  }
				 else if(i<60) 
				  {
					IapProgramByte(0x08200+i*4,xiaxing_WD_dat[i-45]/16777216%256);
					IapProgramByte(0x08200+i*4+1,xiaxing_WD_dat[i-45]/65536%256);
					IapProgramByte(0x08200+i*4+2,xiaxing_WD_dat[i-45]/256%256);
					IapProgramByte(0x08200+i*4+3,xiaxing_WD_dat[i-45]%256);
				  }
			 }
	   }
 }
void read_GPS()
 {
   unsigned char i=0;
   unsigned long flsh1=0,flsh2=0,flsh3=0,flsh4=0;
   for(i=0;i<60;i++)
    {
	  if(i<15) 			
	   {
		 flsh1=IapReadByte(0x08200+i*4);
		 flsh2=IapReadByte(0x08200+i*4+1);
		 flsh3=IapReadByte(0x08200+i*4+2);
    	 flsh4=IapReadByte(0x08200+i*4+3);
	   	 shangxing_JD_dat[i]=flsh1*16777216+flsh2*65536+flsh3*256+flsh4;
	   }
	   else if(i<30) 
	   {
		 flsh1=IapReadByte(0x08200+i*4);
		 flsh2=IapReadByte(0x08200+i*4+1);
		 flsh3=IapReadByte(0x08200+i*4+2);
    	 flsh4=IapReadByte(0x08200+i*4+3);
	   	 shangxing_WD_dat[i-15]=flsh1*16777216+flsh2*65536+flsh3*256+flsh4;
	   }
	   else if(i<45) 
	   {
		 flsh1=IapReadByte(0x08200+i*4);
		 flsh2=IapReadByte(0x08200+i*4+1);
		 flsh3=IapReadByte(0x08200+i*4+2);
    	 flsh4=IapReadByte(0x08200+i*4+3);
		 xiaxing_JD_dat[i-30]=flsh1*16777216+flsh2*65536+flsh3*256+flsh4;
	   } 
	   else if(i<60) 
	   {
		 flsh1=IapReadByte(0x08200+i*4);
		 flsh2=IapReadByte(0x08200+i*4+1);
		 flsh3=IapReadByte(0x08200+i*4+2);
    	 flsh4=IapReadByte(0x08200+i*4+3);
		 xiaxing_WD_dat[i-45]=flsh1*16777216+flsh2*65536+flsh3*256+flsh4;
	   } 
	}
 }
void Uart1Data(uchar dat) 	// 串口发送一个字节数据
{
	SBUF=dat;
	while(!TI);
	TI=0;	
}
void UartData_Byte(uchar *byte)	//串口发送一串数据
{
	while(*byte != '\0')
	{
	  Uart1Data(*byte++);
	}
}
void delay(uint dat) 
 {
   while(dat--);
 }
uchar verify_GPSdat(uchar *dat)//读取服务器返回的数据
{
  uchar i=0;
  while(*dat != 0){
    if(*dat != GPS_dat[i]){
      return 0;
    }
    i++;
    dat++;
  }
  GPS_dat[0]=0;
  return 1;
}
void Send_Hex(unsigned char *p,unsigned char num)
{
   	while(num--)   //剩余发送的字符数
	{
        SBUF = *p; //将要发送的数据赋给串口缓冲寄存器
		while(!TI);//等待发送结束
		TI = 0;    //软件清零
		p++;       //指针加一
	}	
}
void DoSum(unsigned char *Str,unsigned char len)//校验位计算
{
	unsigned int xorsum = 0;
	unsigned char i;
	for(i=1;i<len;i++)
	{
		xorsum = xorsum + Str[i];
	}
	xorsum = 0 - xorsum;
	*(Str+i)     = (unsigned char)(xorsum >> 8);
	*(Str+i+1)   = (unsigned char)(xorsum & 0x00ff);
}
void Send_Appoint_Music(unsigned char dat )
 {	 //7E FF 06 03 00 00 01 FE F7 EF
		unsigned char Table[10];
		Table[0] = 0x7E;
		Table[1] = 0xFF;
		Table[2] = 0x06;	
		Table[3] = 0x03; //指令
		Table[4] = 0x00;
		Table[5] = 0x00;
		Table[6] = dat; 
		DoSum(Table,7);//计算校验码	
		Table[9] = 0xEF;//结束码		
		Send_Hex(Table,10);//发送指令数据
 }
void Send_Appoint_Sound(unsigned char dat)
 {
   if(Music_Busy==0&&s0) 
    {
		unsigned char Table[10];
		Table[0] = 0x7E;
		Table[1] = 0xFF;
		Table[2] = 0x06;
	
		Table[3] = 0x06; //指令
		Table[4] = 0x00;
		Table[5] = 0x00;
		Table[6] = dat;//音量
		DoSum(Table,7);//计算校验码	
		Table[9] = 0xEF;//结束码
		
		Send_Hex(Table,10);//发送指令数据
	}
 }
void read_time1() //实时读取DS1302中的时间数据
{
 uchar i;
	
		 if(state==0)
		  {
			    time_data[0]=ds1302read(0x81);
				time_data[1]=ds1302read(0x83);
				time_data[2]=ds1302read(0x85);
				time_data[3]=ds1302read(0x87);
				time_data[4]=ds1302read(0x89);
				time_data[5]=ds1302read(0x8D);  		
			 	time_data_1[0]=time_data[0]/16*10+time_data[0]%16;
				time_data_1[1]=time_data[1]/16*10+time_data[1]%16;
				time_data_1[2]=time_data[2]/16*10+time_data[2]%16;
				time_data_1[3]=time_data[3]/16*10+time_data[3]%16;
				time_data_1[4]=time_data[4]/16*10+time_data[4]%16;
				time_data_1[5]=time_data[5]/16*10+time_data[5]%16;
				 if(time_data_1[0]>59)
				   {
				 	ds1302write(0x8e,0x00); 
					ds1302write(0x80,0x80);
					ds1302write(0x80,0);
					ds1302write(0x8e,0x80);     
				   }
			    ds1302write(0x8e,0x80);				  
		  }	
		  else 
		   {
				ds1302write(0x8e,0x00); 
				ds1302write(0x80,0x80);
				
				for(i=0;i<7;i++)
				{
					time_data_2[i]=time_data_1[i]/10;
					time_data_3[i]=time_data_1[i]%10;	  
				}
				for(i=0;i<7;i++)
				{
					time_data_4[i]=time_data_2[i]*16+time_data_3[i];
				  
				}
				ds1302write(0x80,time_data_4[0]);
				ds1302write(0x82,time_data_4[1]);
				ds1302write(0x84,time_data_4[2]);
				ds1302write(0x86,time_data_4[3]);
				ds1302write(0x88,time_data_4[4]);
				ds1302write(0x8C,time_data_4[5]);
		   }     
}
//显示函数
void Display()
 {
    uchar dat=0;
	if(state<=6) 
	 {
		   	LCD12864_pos(0,0);
			if(state==1&&s0)   LCD12864_writebyte("    ");
			 else  {
					 LCD12864_writebyte("20");	
					 LCD12864_write(1,0x30+time_data_1[5]/10);		   
					 LCD12864_write(1,0x30+time_data_1[5]%10);
			       }
			LCD12864_writebyte("-");
			if(state==2&&s0)   LCD12864_writebyte("  ");
			 else  {
					 LCD12864_write(1,0x30+time_data_1[4]/10);		   
					 LCD12864_write(1,0x30+time_data_1[4]%10);
			       }
			LCD12864_writebyte("-");
			if(state==3&&s0)   LCD12864_writebyte("  ");
			 else  {
					 LCD12864_write(1,0x30+time_data_1[3]/10);		   
					 LCD12864_write(1,0x30+time_data_1[3]%10);
			       }
//配置定时0用作常规定时,使用定时器1用作串口1波特率发生器,9600
void TimeInt(void)		 //系统定时器初始化配置
{
	TMOD=0x21;	   //定义两个定时器
	TH1=0xFD;
	TL1=0xFD;	   //定时器1用于产生波特率  晶振11.0592
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x4C;		//设置定时初值	
	SCON=0x50;
	PCON=0;
	EA=1;          //开总中断
	ES=1;          //ES-串行中断允许控制位   ES = 1   允许串行中断。
	TR1=1;         //启动定时器开始工作
	ET0=1;
	TR0=1; 	
}

Guess you like

Origin blog.csdn.net/qq_22592979/article/details/128125818