单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》
引言
本设计以AT89S52单片机为控制核心,时钟芯片DS1302提供时钟源,配合LCD1602液晶显示模块,组成基本硬件系统,同时利用HC-05嵌入式蓝牙串口通讯模块,可在手机端进行日期、时间的校准。具有走时精确,功耗低,显示直观,调整简单方便等优点。
功能描述
基本显示:
第一行为日期,依次为:年-月-日-星期
第二行为时间,依次为:时:分:秒
说明:
每月的天数,闰年的天数可自动调整
蓝牙校准日期:
命令d+年月日星期+#,如设置2016年12月8日星期四,手机发送命令:d16120804
蓝牙校准时间:
命令t+时分秒+#,如设置15:11:46,手机发送命令:t151146#
硬件电路设计
硬件概述:
AT89S52单片机介绍:AT89S52_百度百科
DS1302时钟芯片介绍:DS1302_百度百科
LCD1602液晶模块介绍:LCD1602_百度百科
HC-05嵌入式蓝牙串口通讯模块介绍:HC-05
蓝牙通信原理:
硬件电路图:
程序设计:
主程序:main.c
#include <reg52.h>
#include <LCD1602.c>
#include <DS1302.c>
#include <bluetooth.c>
void serial_initial()
{
EA = ; //开总中断
ES = ; //开串口中断
TMOD = 0x20; //定时器1,方式2,8位自动重装,作波特率发生器
TH1 = 0xfa; //波特率9600
TL1 = 0xfa;
TR1 = ;
SCON = 0x50; //串口工作方式1,允许接收
PCON = 0x80; //SMOD=1,bps倍增9600
}
void clock_initial()
{
lcd_initial(); //1602初始化
serial_initial(); //中断初始化
Set_DS1302_Time(0x80); //先写入寄存器起始地址设置时钟日历初值
dis_string(0x80,"Date:11-11-11-11");
dis_string(0xc0,"Time: 11:11:11 ");
flag_date = ;
flag_time = ;
bt_flag = ;
} void main()
{
clock_initial();
while()
{
if(flag_date == &&cmd_end==)
date_set();
if(flag_time == &&cmd_end==)
time_set();
Read_DS1302_Time(0x81);
dis_twonum (, , TimeData[]); //年
dis_twonum (, , TimeData[]); //月
dis_twonum (, , TimeData[]); //日
dis_twonum (, , TimeData[]); //星期
dis_twonum (, , TimeData[]); //时
dis_twonum (, , TimeData[]); //分
dis_twonum (, , TimeData[]); //秒
Delay_Ms(); //延时
}
} void serial_int() interrupt
{
uchar temp; //定义串口接收数据变量 ES = ; //关串口中断
RI = ; //令接收中断标志位为0(软件清零)
temp = SBUF; //将接收到的数据送入变量 temp
data_deal(temp); //对收到数据进行处理
ES = ; //开串口中断
/*SBUF = temp; //将接收的数据发送回去
while(TI == 0);
TI = 0; */
}
DS1302时钟芯片驱动程序:DS1302.c
sbit TSCLK = P2 ^ ; //时钟
sbit TIO = P2 ^ ; //数据
sbit TRST = P2 ^ ; //使能 //时钟日历暂存数组,秒、分、时、日、月、周、年 初值为= 16年2月15日 周1 23:58:50
uchar TimeData[] = {, , , , , , };
void Delay_Ms(uint ms)
{
uint i;
do {
i = / ;
while(--i); //96T per loop
} while(--ms);
}
/*写一字节*/
void DS1302_W_Byte(uchar dat)
{
uchar i;
for(i = ; i < ; i++) //每次写1bit,写8次
{
TSCLK = ; //拉低时钟总线
TIO = dat & 0x01; //从一字节最低位开始写
TSCLK = ; //拉高时钟总线,DS1302把数据读走
dat >>= ; //数据右移一位
}
}
/*读一字节*/
uchar DS1302_R_Byte()
{
uchar i, dat;
for(i = ; i < ; i++)
{
TSCLK = ;
dat >>= ;
if(TIO) dat |= 0x80;//读取数据
TSCLK = ;
}
return dat; //返回读取的数据
}
/*写数据,命令*/
void DS1302_W_DAT(uchar cmd, uchar dat)
{
TRST = ;
TSCLK = ;
TRST = ;
DS1302_W_Byte(cmd);
DS1302_W_Byte(dat);
}
/*读数据*/
uchar DS1302_R_DAT(uchar cmd)
{
uchar dat;
TRST = ;
TSCLK = ;
TRST = ;
DS1302_W_Byte(cmd);
dat = DS1302_R_Byte();
return dat;
} /*清除写保护*/
void DS1302_Clear_WP()
{
DS1302_W_DAT(0x8e, 0x00);
}
/*设置写保护*/
void DS1302_Set_WP()
{
DS1302_W_DAT(0x8e, 0x80);
TRST = ;
TSCLK = ;
}
/*时间预设*/
void Set_DS1302_Time(uchar addr)
{
uchar i, j;
DS1302_Clear_WP(); //清除写保护
for(i = ; i < ; i++) //写入7个字节的时钟初始值
{
j = TimeData[i] / ; //BCD码转换
TimeData[i] %= ;
TimeData[i] += j * ;
DS1302_W_DAT(addr, TimeData[i]);
addr += ;
}
DS1302_Set_WP(); //开写保护
}
/*读取1302时间*/
void Read_DS1302_Time(uchar addr)
{
uchar i;
DS1302_Clear_WP();
for(i = ; i < ; i++) //从DS1302读取7个字节的时钟日历数据
{
TimeData[i] = DS1302_R_DAT(addr);
addr += ;
}
DS1302_Set_WP();
}
LCD1602液晶模块驱动程序:LCD1602.c
#define uint unsigned int
#define uchar unsigned char
sbit RS = P2 ^ ;
sbit RW = P2 ^ ;
sbit EN = P2 ^ ; void check_busy() //检测是否忙
{
uchar dat;
P0 = 0xff;
RS = ;
RW = ;
do
{
EN = ;
dat = P0;
EN = ;
} while(dat & 0x80);
} void write_cmd(uchar cmd) //写命令
{
check_busy();
RS = ;
RW = ;
P0 = cmd;
EN = ;
EN = ;
} void write_data(uchar dat) //写数据
{
check_busy();
RS = ;
RW = ;
P0 = dat;
EN = ;
EN = ;
}
/*显示一位数字*/
void dis_onenum (uchar X, uchar Y, uchar dat)
{
if(Y) X |= 0X40;
X |= 0X80;
write_cmd(X);
write_data(dat);
}
/*显示两位数字*/
void dis_twonum (uchar X, uchar Y, uchar dat)
{
dis_onenum (X, Y, dat / + '');
dis_onenum (X+, Y, dat % + '');
}
/*显示字符串*/
void dis_string(uchar location,uchar *p)
{
write_cmd(location);
while(*p)
{
write_data(*p);
p++;
}
} void lcd_initial()
{
write_cmd(0x38);
write_cmd(0x0c);
write_cmd(0x06);
write_cmd(0x01);
}
蓝牙控制程序:bluetooth.c
uchar date[],time[];
uchar cmd_index, cmd_start, cmd_end, bt_flag;
bit flag_time, flag_date; void time_set()
{
uchar a;
uchar i, j, addr = 0x80;
for(a = ; a < ; a++)
time[a] = time[a] - 0x30; //数据处理
TimeData[] = (time[] * + time[]) % ; //小时
TimeData[] = (time[] * + time[]) % ; //分钟
TimeData[] = (time[] * + time[]) % ; //秒 DS1302_Clear_WP(); //清除写保护
for(i = ; i < ; i++) //写入时间设置值
{
j = TimeData[i] / ; //BCD码转换
TimeData[i] %= ;
TimeData[i] += j * ;
DS1302_W_DAT(addr, TimeData[i]);
addr += ;
}
DS1302_Set_WP(); //开写保护
flag_time = ;
} void date_set()
{
uchar a;
uchar i, j, addr = 0x86;
for(a = ; a < ; a++)
date[a] = date[a] - 0x30; //对数据处理
TimeData[] = (date[] * + date[]) ; //日
TimeData[] = (date[] * + date[]) ; //月
TimeData[] = (date[] * + date[]) ; //年
TimeData[] = (date[] * + date[]) ; //周 DS1302_Clear_WP();
for(i = ; i < ; i++) //写入日期设置值
{
j = TimeData[i] / ; //BCD码转换
TimeData[i] %= ;
TimeData[i] += j * ;
DS1302_W_DAT(addr, TimeData[i]);
addr += ;
}
DS1302_Set_WP(); //开写保护
flag_date = ;
} void data_deal(uchar data_buf)
{
switch(data_buf)
{
case 'd':
cmd_start = ;
cmd_end = ;
flag_date = ;
cmd_index = ;
bt_flag = ;
break;
case 't':
cmd_start = ;
cmd_end = ;
flag_time = ;
cmd_index = ;
bt_flag = ;
break;
case '#':
cmd_start = ;
cmd_end = ;
break;
default:break;
}
if (cmd_start == )
{
switch (bt_flag)
{
case :
date[cmd_index] = data_buf;
cmd_index++;
break;
case :
time[cmd_index] = data_buf;
cmd_index++;
break;
default:break;
}
if (cmd_index >= )
cmd_index = ;
}
}
总结:
2016.12.05——2016.12.07三天的单片机课程设计结束了,我的课程设计是——《基于AT89S52单片机和DS1302时钟芯片的电子钟(可手机蓝牙校准)》,此次设计让我对AT89S52单片机有了更深的认识,为了完成设计,我又学习了DS1302时钟芯片时间写入,时间读取等基本的读写操作时序,对DS1302的操作方法有了一定了解。
当液晶时钟第一次被成功的校准时,我很激动和兴奋,也很有成就感。由于使用了蓝牙串口校准时间,所以又复习了串口通讯的原理,在调试的过程中,对串口数据的处理也有了一定的经验:由于串口是一个一个字符接收的,当接收到下一个字符时,上一个字符就会丢失,为了保存接收到的每个字符,先将接收到的数据存放到数组中,然后数组指针加一,这样串口接收的每一个数据就会按照接收的先后顺序有序的存放到数组中,然后数组中的元素就可以被我们拿来进行各种操作了,如本设计中的设置时间和日期。
由于课程设计的时间较短,所以此设计仅在时间显示的基础上,增加了蓝牙串口校准时间功能,此设计还有很多可以完善和改进的功能,如:
1.增加闹钟功能,增加按键校准时间日期、设置闹钟功能,
3.增加星期计算功能,调整时只需调整年月日,调整完毕后自动计算出星期几,
4.增加DS18B20温度传感器实时显示温度,手机可远程获取温度,
5.星期显示为英文缩写,如周一:Mon,
6.简单报警功能, 等其他功能,这些功能都是可以实现的。
虽然单片机课程设计结束了, 但我的学习之路还没有结束,我将继续学习51单片机的其他扩展功能,以及其他的通讯协议,如IIC通讯,SPI通讯,红外通信,WiFI无线通讯,为以后学习性能更强大的单片机做个准备,MCS-51系列单片机虽然是低功耗可编程处理器,但它也只是8位微处理器,它的指令执行速度、驱动能力、程序存储等其他片内资源都是非常有限的,已经不能满足当今科技发展的需要,所以为了更好的发展,还要学习其他性能更强大的单片机。课程设计结束了,还要感谢老师的的指导我才能完成课程设计,衷心的感谢老师的帮助和提出的建议。
今天开通了博客园的个人博客,因为之前是用的新浪博客,没有插入代码的功能,所以排版非常乱,现在有了这个博客就可以美美的插入代码了,哈哈,就把上学期做的课程设计作为新家的第一篇文章吧!
2017-03-12 18:24:01
欢迎大家关注我的个人博客 http://www.wangchaochao.top/
微信扫码关注我的公众号
不定期更新个人学习笔记和技术总结,欢迎大家互相学习交流!
单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》的更多相关文章
- 单片机课程设计-四位加法计算器设计参考程序(c语言)
#include<reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; sbit rw=P2^; sbit ...
- 课程设计- 基于ssm的捐赠物资分配管理系统 && 基于java的申请救援管理系统
课程设计- 基于ssm的捐赠物资分配管理系统 && 基于java的申请救援管理系统 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架: ...
- 单片机课程设计——课程设计之四位加法计算器(2)(C代码)
#include<reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; sbit rw=P2^5; sbit ...
- 嵌入式系统及应用课程设计——基于STM32的温湿度监测系统
大三上学期期末总结,嗯,没错上学期,写在新学期开始,hhh. 上学期学了一门嵌入式系统及应用的课程,期末的课程设计题目是基于STM32的温湿度监测系统. 记得刚开始做课程设计的时候,听说先设计画出原理 ...
- 单片机DIY制作-基于STM32单片机甲醛二氧化碳温度湿度采集系统
基于STM32单片机甲醛二氧化碳温度湿度采集系统 实践制作DIY-GC008-甲醛二氧化碳温度湿度采集系统 一.功能说明: 基于STM32单片机设计-甲醛二氧化碳温度湿度采集系统 二.功能介绍: 1. ...
- Java团队课程设计——基于学院的搜索引擎
团队名称.团队成员介绍.任务分配,团队成员课程设计博客链接 姓名 成员介绍 任务分配 课程设计博客地址 谢晓淞(组长) 团队输出主力 爬虫功能实现,Web前端设计及其后端衔接 爬虫:https://w ...
- 单片机课程设计>八音盒
2017—2018学年度第一学期 <单片机原理及应用>作品考试 八音盒 2017-2018-1<单片机原理及应用>作品设计提交文档 一.作品设计目的 1.利用51单片机的各个部 ...
- j2ee课程设计—基于activiti的请休假系统
前言 课设基于SSM框架,数据库采用mysql,主要业务交给activiti,版本控制利用github. 参考资料: Intellij 部署SSM框架 Activiti就是这么简单 方大师的教材 下文 ...
- 课程设计-基于SSM的在线课程教学系统代码-基于java的线上课程资源共享论坛系统
注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM 前端框架:vue 数据库:MySQL 设计模式:MVC 架构:B/S 源码类型: Web 编 ...
随机推荐
- MES工具机器列表功能操作
概述 在机器权限组.限制工序变更等其他情况下,有时候需要重启中间件才能起作用,这样会直接影响其他人员的加工情况.为了改善这种情况,现在MES工具中新加了一个功能,可以单独重启某一个机器,其它机器不受影 ...
- Android学习总结(十二)———— BaseAdapter优化
一.BaseAdapter的基本概念 对于Android程序员来说,BaseAdapter肯定不会陌生,灵活而优雅是BaseAdapter最大的特点.开发者可以通过构造BaseAdapter并搭载到L ...
- 使用java.util.Properties类读写配置文件
J2SE 1.5 以前的版本要求直接使用 XML 解析器来装载配置文件并存储设置,虽说也并非难事,相比 java.util.Properties却要做额外的解析工作.而java.util.Proper ...
- h5标签基础 table表格标签
一.表格的定义:用于有规范的显示数据. 二.基本组成: 行<tr>/列<td>/表头<caption>/表标题<th> eg: <table> ...
- 转换器3:手写PHP转Python编译器,词法部分
上周写了<ThinkPhp模板转Flask.Django模板> 一时技痒,自然而然地想搞个大家伙,把整个PHP程序转成Python.不比模板,可以用正则匹配偷懒,这次非写一个Php编译器不 ...
- 解决Gerrit的git unpack error问题和error Missing unknown ec867cebfd2be97c3603c45fac03c75dcf68d0ca
参考链接:http://www.cnblogs.com/yuxc/p/3508964.html 解决方法: 由于帖子里面用的是mysql数据库,而我用的是h2数据库,还特意自己去找了H2数据库的进入方 ...
- 腾讯云数据库团队:phpMyAdmin中sql-parser组件的使用
phpMyAdmin是一款基于Web端运行的开源数据库管理工具,支持管理MySQL和MariaDB两种数据库. phpMyAdmin的程序主要使用php和javascript开发,它的安装使用都比较简 ...
- (6)简单说说java中的线程
先甩出来两种创建线程的方法: private static int count = 100; public static void main(String[] args) { // 用继承Thread ...
- 前端学PHP之Session
前面的话 Session技术和Cookie相似,都是用来储存使用者的相关资料.但最大的不同之处在于Cookie是将数据存放在客户端的计算机之中,而Session则是将数据存放于服务器系统之下.Sess ...
- 为什么你应该抛弃Express的视图渲染引擎
Nodejs Express框架的一个被人们广为使用的特性是它的渲染引擎.Express视图渲染引擎允许Controller提供一个视图名称和视图模型对象给Express,然后返回由HTTP响应流输出 ...