单片机课程设计——《基于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 编 ...
随机推荐
- 从0移植uboot (二) _uboot启动流程分析
经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,同时,此时的uboot.bin也没有结合 ...
- 点击Robot Framework的桌面快捷图标后,没有反应(没有打开应用程序)
http://www.cnblogs.com/zhengyihan1216/p/6397478.html 这篇文章中介绍了如何安装Robot Framework以及如何在桌面上创建快捷方式. 但是有 ...
- i++与++i陷阱
对于++i与i++编程必不可少,它们的区别:一般人只知道++i是先将i加一再进行其他操作,i++是先将i进行其他操作,再将其加一. 但是对于i++其中的执行过程,语言环境很关键.先来两个程序,看结果是 ...
- centOS7 mini配置linux服务器(二) 配置IP
1.登录root用户,输入指令 #ip addr 可以看到除lo外的属于你的网卡配置. 2.输入 #cd /etc/sysconfig/network-scripts/ #vi if ...
- 基于fiddler的APP抓包及服务端模拟
在HTTP接口的测试过程中,一般我们会按照如下的步骤进行: 1)测试环境的准备 2)HTTP消息体的构造 3)HTTP消息的发送及断言 如果我们可以拿到项目组的接口文档,并且HTTP后台服务是可以工作 ...
- 转:关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
1. JSON.parse(jsonString): 在一个字符串中解析出JSON对象 ? 1 2 3 var str = '[{"href":"baidu.com&qu ...
- beauty
至你我最美的邂逅 年意渐渐消失,一转眼元宵的炮竹将要响起,今天是贰零一七年二月九号,即是元宵节前两天,在这里我写下我这几天的收获. 离元宵节还有四天,我好久都没跟朋友一起认真的玩过,几天我去了我发小的 ...
- ACM 整数划分(四)
整数划分(四) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...
- 2292: 【POJ Challenge 】永远挑战
2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 553 Solved: 230[Submit][ ...
- spring知识点全部复习
一. 专业术语 侵入式设计 引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类.如:Struts框架 非侵入式设计 引入框架,对现有的类结构没有影响.如:Hibernate.Spring 控 ...