目录
一、主要功能
二、硬件资源
三、程序编程
四、实现现象
一、主要功能
基于51单片机的公交报站系统,可以手动报站,站名十个。
在lcd12864上显示时间(年月日时分秒)和站名,时间可以设置,
仿真中可以语音播报。加一个用串口模拟语音播报。
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
三、程序编程
#include <reg52.h>
#include <intrins.h>
#include<stdio.h>
#include "DS1302.h"
#include < character.h >
#include < lcd.h >
#define uchar unsigned char
#define uint unsigned intunsigned char KEY_NUM = 0;
unsigned char KEY2_Count = 0;
bit Flag_KEY_Set = 0;
sbit key1=P1^3;
sbit key2=P1^4;
sbit key3=P1^5;
sbit key4=P1^6;
sbit key5=P1^7;
sbit key6=P0^0;
sbit key7=P0^1;
sbit key8=P0^2;
sbit key9=P0^3;
sbit key10=P0^4;sbit KEY1 = P0^5;
sbit KEY2 = P0^6;
sbit KEY3 = P0^7;
sbit KEY4 = P3^5;void ajpd();void jiemian1(void) //站台一
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[2]); //printf("站台一\r\n");
}void jiemian2(void) //站台2
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[3]); //printf("站台二\r\n");
}void jiemian3(void) //站台3
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[4]); //printf("站台三\r\n");
}void jiemian4(void) //站台4
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[5]); //printf("站台四\r\n");
}void jiemian5(void) //站台5
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[6]); //printf("站台五\r\n");
}void jiemian6(void) //站台6
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[7]); //printf("站台六\r\n");
}void jiemian7(void) //站台7
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[8]); //printf("站台七\r\n");
}void jiemian8(void) //站台8
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[9]); //printf("站台八\r\n");
}void jiemian9(void) //站台9
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[10]); //printf("站台九\r\n");
}void jiemian10(void) //站台10
{Lcd_Character_16X16( 1, 4, 0 , function_logo[0]); //Lcd_Character_16X16( 1, 4, 16 , function_logo[1]); //Lcd_Character_16X16( 1, 4, 32 , function_logo[11]); //printf("站台十\r\n");
}
//按键扫描程序
//****************************************************
void Scan_Key()
{if( KEY1 == 0 ) //按键1扫描{Delay(10); //延时去抖if( KEY1 == 0 ){while(KEY1 == 0); //等待松手KEY_NUM = 1;}}if( KEY2 == 0 ) //按键2扫描{Delay(10); //延时去抖if( KEY2 == 0 ){while(KEY2 == 0); //等待松手KEY_NUM = 2;}}if( KEY3 == 0 ) //按键2扫描{Delay(10); //延时去抖if( KEY3 == 0 ){while(KEY3 == 0); //等待松手KEY_NUM = 3;}}if( KEY4 == 0 ) //按键2扫描{Delay(10); //延时去抖if( KEY4 == 0 ){while(KEY4 == 0); //等待松手KEY_NUM = 4;}}
}void Display_RTCC(void)
{Lcd_Character_16X8(1,0,0,letter_logo[DS1302Buffer.Year/10]);Lcd_Character_16X8(1,0,8,letter_logo[0]);Lcd_Character_16X8(1,0,16,letter_logo[2]);Lcd_Character_16X8(1,0,24,letter_logo[DS1302Buffer.Year%10]);Lcd_Character_16X8(1,0,32,letter_logo[11]);Lcd_Character_16X8(1,0,40,letter_logo[DS1302Buffer.Month/10]);Lcd_Character_16X8(1,0,48,letter_logo[DS1302Buffer.Month%10]);Lcd_Character_16X8(1,0,56,letter_logo[11]);Lcd_Character_16X8(1,0,64,letter_logo[DS1302Buffer.Day/10]); Lcd_Character_16X8(1,0,72,letter_logo[DS1302Buffer.Day%10]); Lcd_Character_16X8(1,2,0,letter_logo[DS1302Buffer.Hour/10]);Lcd_Character_16X8(1,2,8,letter_logo[DS1302Buffer.Hour%10]);Lcd_Character_16X8(1,2,16,letter_logo[10]);Lcd_Character_16X8(1,2,24,letter_logo[DS1302Buffer.Minute/10]);Lcd_Character_16X8(1,2,32,letter_logo[DS1302Buffer.Minute%10]);Lcd_Character_16X8(1,2,40,letter_logo[10]);Lcd_Character_16X8(1,2,48,letter_logo[DS1302Buffer.Second/10]);Lcd_Character_16X8(1,2,56,letter_logo[DS1302Buffer.Second%10]);
}//串口初始化
void init_com(void)
{TMOD =0x20; //设T0为方式1,GATE=1;SCON=0x50; //开启串口TH1=0xFD; //波特率是9600bpsTL1=0xFD;TR1=1; //开启定时器TI=1;EA=1;
}void main()
{init_com();Lcd_Initial(); //LCD初始化Lcd_Display_On(); //启动屏幕DS1302_Init(); //初始化DS1302while(1){DS1302_GetTime(&DS1302Buffer); //获取当前RTCC值if(Flag_Time_Refresh==1&& Flag_KEY_Set == 0) //数据更新时才刷新LCD{Flag_Time_Refresh = 0;Display_RTCC(); //显示实时时钟 }ajpd(); Scan_Key(); //按键扫描switch( KEY_NUM ){case 1: //按键1执行程序KEY_NUM = 0; //清空按键标志Flag_KEY_Set = ~Flag_KEY_Set; //设置按键标志位翻转break;case 2: //按键2执行程序KEY_NUM = 0; //清空按键标志if(Flag_KEY_Set) //在设置状态时运行{KEY2_Count++;if(KEY2_Count == 6)KEY2_Count = 0;switch(KEY2_Count){case 0:Lcd_Set_X_Y(0,0); //指针指向年,闪烁break;case 1:Lcd_Set_X_Y(0,40); //指针指向月,闪烁break;case 2:Lcd_Set_X_Y(0,64); //指针指向日,闪烁break;case 3:Lcd_Set_X_Y(2,0); //指针指向小时,闪烁break;case 4:Lcd_Set_X_Y(2,24); //指针指向分钟,闪烁break;case 5:Lcd_Set_X_Y(2,48); //指针指向秒钟,闪烁break;default : break;} } break;case 3: //按键3执行程序KEY_NUM = 0; //清空按键标志if(Flag_KEY_Set) //在设置状态时运行{switch(KEY2_Count){case 0:DS1302Buffer.Year++;if(DS1302Buffer.Year >= 100){DS1302Buffer.Year = 0;}DS1302_SetTime( DS1302_YEAR , DS1302Buffer.Year );Display_RTCC();break;case 1:DS1302Buffer.Month++;if(DS1302Buffer.Month >= 13){DS1302Buffer.Month = 1;}DS1302_SetTime( DS1302_MONTH , DS1302Buffer.Month );Display_RTCC();break;case 2:DS1302Buffer.Day++;if(DS1302Buffer.Day >= 32){DS1302Buffer.Day = 1;}DS1302_SetTime( DS1302_DAY , DS1302Buffer.Day );Display_RTCC();break;case 3:DS1302Buffer.Hour++;if(DS1302Buffer.Hour >= 24){DS1302Buffer.Hour = 0;}DS1302_SetTime( DS1302_HOUR , DS1302Buffer.Hour );Display_RTCC();break;case 4:DS1302Buffer.Minute++;if(DS1302Buffer.Minute >= 60){DS1302Buffer.Minute = 0;}DS1302_SetTime( DS1302_MINUTE , DS1302Buffer.Minute );Display_RTCC();break;case 5:DS1302Buffer.Second++;if(DS1302Buffer.Second >= 60){DS1302Buffer.Second = 0;}DS1302_SetTime( DS1302_SECOND , DS1302Buffer.Second);Display_RTCC();break;default : break;}}break;case 4: //按键4执行程序KEY_NUM = 0; //清空按键标志if(Flag_KEY_Set) //在设置状态时运行{switch(KEY2_Count){case 0:DS1302Buffer.Year--;if(DS1302Buffer.Year == 255){DS1302Buffer.Year = 99;}DS1302_SetTime( DS1302_YEAR , DS1302Buffer.Year );Display_RTCC();break;case 1:DS1302Buffer.Month--;if(DS1302Buffer.Month == 0){DS1302Buffer.Month = 12;}DS1302_SetTime( DS1302_MONTH , DS1302Buffer.Month );Display_RTCC();break;case 2:DS1302Buffer.Day--;if(DS1302Buffer.Day == 0){DS1302Buffer.Day = 31;}DS1302_SetTime( DS1302_DAY , DS1302Buffer.Day );Display_RTCC();break;case 3:DS1302Buffer.Hour--;if(DS1302Buffer.Hour == 255){DS1302Buffer.Hour = 23;}DS1302_SetTime( DS1302_HOUR , DS1302Buffer.Hour );Display_RTCC();break;case 4:DS1302Buffer.Minute--;if(DS1302Buffer.Minute == 255){DS1302Buffer.Minute = 59;}DS1302_SetTime( DS1302_MINUTE , DS1302Buffer.Minute );Display_RTCC();break;case 5:DS1302Buffer.Second--;if(DS1302Buffer.Second == 255){DS1302Buffer.Second = 59;}DS1302_SetTime( DS1302_SECOND , DS1302Buffer.Second);Display_RTCC();break;default : break;}}break;default : break;} }
}void ajpd()
{if(!key1){jiemian1();while(!key1);}if(!key2){jiemian2();while(!key2);}if(!key3){jiemian3();while(!key3);}if(!key4){jiemian4();while(!key4);}if(!key5){jiemian5();while(!key5);}if(!key6){jiemian6();while(!key6);}if(!key7){jiemian7();while(!key7);}if(!key8){jiemian8();while(!key8);}if(!key9){jiemian9();while(!key9);}if(!key10){jiemian10();while(!key10);}
}
四、实现现象
具体动态效果看B站演示视频:
48-基于单片机的LCD12864时间调控和串口抱站_哔哩哔哩_bilibili
全部资料(源程序、仿真文件、安装包、演示视频):
点击下载百度网盘资料