基于单片机、DS1302、DS1602的电子时钟

发布者:花钱123最新更新时间:2014-12-31 关键字:单片机  DS1302  DS1602  电子时钟 手机看文章 扫描二维码
随时随地手机看文章
这是DS1602+DS1302完整程序,其中P1口接独立键盘。
 
DS1602部分:
 
# include "SYSTEM.H"             
 
//#ifndef __LCD1602_8_H__
//#define __LCD1602_8_H__
 
 
 
//LCD接口定义     
sfr   io = 0x80;    //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;
sbit  rs = P2^6;    //LCD数据/命令选择端(H/L)
sbit  rw = P2^5;    //LCD读/写选择端(H/L)
sbit  ep = P2^7;    //LCD使能控制
sbit     bz = io^7;    //LCD忙标志位
 
 
//函数声明  
void lcd_busy(void);     //测试LCD忙碌状态程序
void lcd_wcmd(unsigned char cmd);  //写入指令到LCD程序
void lcd_wdat(unsigned char dat);  //写入数据到LCD程序
void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序
void lcd_sef_chr();
//void printc(unsigned char CHAR);  //显示字符
 
void lcd_init(void);     //LCD初始化设定程序
 
 
//测试LCD忙碌状态
void lcd_busy(void)
 do{
  ep = 0;
  rs = 0;  //指令
  rw = 1;  //读出
  io = 0xff;
  ep = 1;
  _nop_(); //高电平读出 1us 
 }while(bz);  //bz=1表示忙,bz=0表示空闲
 ep = 0;  
}
 
 
//写入指令到LCD
void lcd_wcmd(unsigned char cmd)
{       
 lcd_busy(); //检测忙
 rs = 0;  //指令
 rw = 0;  //写入
 ep = 1; 
 io = cmd; //指令
 ep = 0;  //下降沿有效 
}
 
 
//写入数据函数
void lcd_wdat(unsigned char Data)
{
 lcd_busy();  //检测忙
 rs = 1;   //数据
 rw = 0;   //写入
 ep = 1;
 io = Data;  //数据
 ep = 0;   //下降沿有效
}
 
 
//LCD数据指针位置程序
void lcd_pos(unsigned char x, bit y)
{      
 if(y)lcd_wcmd(x|0xc0); //y=1,第二行显示;y=0,第一行显示  0<=x<16
 else lcd_wcmd(x|0x80); //数据指针=80+地址码(00H~27H,40H~67H)
  
}
 
 
//显示字符
//
void printc(unsigned char CHAR)
{
 lcd_wdat(CHAR);
}
//
 
 
//显示字符串
void prints(unsigned char //string)
{
 //unsigned char i;
 //do{lcd_wdat(string[i]);i++;}while(string[i]!='\0');//生成代码比for循环大
 for(i=0;string[i]!='\0';i++)lcd_wdat(string[i]);  //有时用for循环也好哈//
 
 while(//string) {lcd_wdat(//string);string++;}
 
}
 
 
 
 
//LCD初始化设定
void lcd_init()
{      
 lcd_wcmd(0x38);  //设置LCD为16X2显示,5X7点阵,八位数据接口
 lcd_wcmd(0x06);  //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)
 lcd_wcmd(0x0c);  //LCD开显示及光标设置(光标不闪烁,不显示"_")
 lcd_wcmd(0x01);  //清除LCD的显示内容
 
}
 
 
DS1302部分:
 
# include "SYSTEM.H"
 
 
//#ifndef __DS1302_A_H__
//#define __DS1302_A_H__
 
 
 
//引脚及位的定义
sbit DS1302_CLK = P3^6;   //时钟引脚
sbit DS1302_IO  = P3^4;   //数据引脚
sbit DS1302_RST = P3^5;   //复位引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
 
 
//函数声明
void DS1302_InputByte(unchar Data);           //写入一个字节(内部函数)
unchar DS1302_OutputByte(void);               //读取一个字节(内部函数)
void Write1302(unchar Address, unchar Data);  //在指定地址写入指定的数据
unchar Read1302(unchar Address);              //读取DS1302指定地址中的数据
void DS1302_SetProtect(bit Flag);             //DS1302是否写入保护
void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数
void DS1302_GetTime(SYSTEMTIME *Time);        //读出时间
void DateToStr(SYSTEMTIME *Time);             //日期转化成字符
void TimeToStr(SYSTEMTIME *Time);             //时间转化成字符
void DS1302_Initial (void);                   //DS1302初始化
 
//写入一个字节(内部函数)
void DS1302_InputByte(unchar Data) 
{
 unchar i;
 ACC = Data;
 for(i=8; i>0; i--)
 { 
  DS1302_CLK = 0;  
  DS1302_IO = ACC0; //由低位到高位  
  DS1302_CLK = 1;  //上升沿写入数据
  ACC >>= 1;
 }
}
 
 
 
//读取一个字节(内部函数)
unchar DS1302_OutputByte(void)
{
 unchar i;
 for(i=8; i>0; i--)
 {   
  DS1302_CLK = 0;      //下降沿读出DS1302的数据
  ACC >>= 1;    //读出由低到高位,只能移7次有效位!!!
  ACC7 = DS1302_IO;  //第一个数据           
  DS1302_CLK = 1;         
 }      
 return (ACC);
}
 
 
//在指定地址写入指定的数据
void Write1302(unchar Address, unchar Data)
{
 DS1302_RST = 0;
 DS1302_CLK = 0;
 DS1302_RST = 1;
 DS1302_InputByte(Address);
 DS1302_InputByte(Data);
 DS1302_CLK = 1;
 DS1302_RST = 0;
}
 
 
//读取1302指定地址中的数据
unchar Read1302(unchar Address)
{
 unchar Data;
 DS1302_RST = 0;
 DS1302_CLK = 0;
 DS1302_RST = 1;       //RST拉高,启动数据传送
 DS1302_InputByte(Address|0x01);//读取指定地址数据指令
 Data = DS1302_OutputByte();
 DS1302_CLK = 1;
 DS1302_RST = 0;
 return (Data);
}
 
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
 if(Flag)
  Write1302(0x8E,0x80);  //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
 else
  Write1302(0x8E,0x00);  //WP=0 允许数据写入DS1302
}
 
 
//设置时间函数
void DS1302_SetTime(unchar Address, unchar Value)
{
 DS1302_SetProtect(0);
 Write1302(Address,((Value/10)<<4|(Value)));
 DS1302_SetProtect(1);
 
}
 
 
//读出时间
void DS1302_GetTime(SYSTEMTIME *Time)
{
 unchar ReadValue;
 ReadValue = Read1302(DS1302_SECOND);
 Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_MINUTE);
 Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_HOUR);
 Time->Hour   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_DAY);
 Time->Day    = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_WEEK);
 Time->Week   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_MONTH);
 Time->Month  = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
 ReadValue = Read1302(DS1302_YEAR);
 Time->Year   = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
 
 
//日期转化成字符
void DateToStr(SYSTEMTIME *Time)
{
 Time->DateString[0] = Time->Year/10 + '0';
 Time->DateString[1] = Time->Year + '0';
 Time->DateString[2] = '-';
 Time->DateString[3] = Time->Month/10 + '0';
 Time->DateString[4] = Time->Month + '0';
 Time->DateString[5] = '-';
 Time->DateString[6] = Time->Day/10 + '0';
 Time->DateString[7] = Time->Day + '0';
 Time->DateString[8] = '\0';
}
 
 
//时间转化成字符
void TimeToStr(SYSTEMTIME *Time)
{
 Time->TimeString[0] = Time->Hour/10 + '0';
 Time->TimeString[1] = Time->Hour + '0';
 Time->TimeString[2] = ':';
 Time->TimeString[3] = Time->Minute/10 + '0';
 Time->TimeString[4] = Time->Minute + '0';
 Time->TimeString[5] = ':';
 Time->TimeString[6] = Time->Second/10 + '0';
 Time->TimeString[7] = Time->Second + '0';
 Time->TimeString[8] = '\0';
}
 
 
//初始化DS1302
void DS1302_Initial (void)
{
 unchar Second=Read1302(DS1302_SECOND);
 if(Second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
 DS1302_SetTime(DS1302_SECOND,0);
 
}
 
函数声明SYSTEM.H:
 
 
//包含头文件
#include
#include
//#include"LCD1602_8.H"
//#include"DS1302_A.H"
 
//P0 Bit Registers
 
sbit P0_0 = 0x80;
sbit P0_1 = 0x81;
sbit P0_2 = 0x82;
sbit P0_3 = 0x83;
sbit P0_4 = 0x84;
sbit P0_5 = 0x85;
sbit P0_6 = 0x86;
sbit P0_7 = 0x87;
 
 
//P1 Bit Registers
 
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit P1_3 = 0x93;
sbit P1_4 = 0x94;
sbit P1_5 = 0x95;
sbit P1_6 = 0x96;
sbit P1_7 = 0x97;
 
//P2 Bit Registers
sbit P2_0 = 0xA0;
sbit P2_1 = 0xA1;
sbit P2_2 = 0xA2;
sbit P2_3 = 0xA3;
sbit P2_4 = 0xA4;
sbit P2_5 = 0xA5;
sbit P2_6 = 0xA6;
sbit P2_7 = 0xA7;
 
 
//P3 Bit Registers (Mnemonics & Ports)
sbit P3_0 = 0xB0;
sbit P3_1 = 0xB1;
sbit P3_2 = 0xB2;
sbit P3_3 = 0xB3;
sbit P3_4 = 0xB4;
sbit P3_5 = 0xB5;
sbit P3_6 = 0xB6;
sbit P3_7 = 0xB7;
 
 
//宏定义便于理解
#define unchar unsigned char
#define unint  unsigned int
#define DS1302_SECOND      0x80
#define DS1302_MINUTE      0x82
#define DS1302_HOUR        0x84
#define DS1302_WEEK        0x8A
#define DS1302_DAY         0x86
#define DS1302_MONTH       0x88
#define DS1302_YEAR        0x8C
#define DS1302_RAM(X)      (0xC0+(X)*2) 
//用于计算RAM地址的宏运算
 
//定义时间类型
typedef struct _SYSTEMTIME_
{
 unchar Second;
 unchar Minute;
 unchar Hour;
 unchar Week;
 unchar Day;
 unchar Month;
 unchar Year;
 unchar DateString[9];
 unchar TimeString[9];
}SYSTEMTIME;   
 
 
 
//LCD1602外部引用函数
extern void lcd_init(void);  //LCD初始化设定程序
extern void prints(unsigned char *string); //显示字符串
extern void lcd_pos (unsigned char x, bit y); //LCD数据指针位置程序
extern void lcd_sef_chr() ;
extern void lcd_wcmd(unsigned char cmd);//写入指令到LCD程序
 
 
//*DS1302外部引用函数
extern void DS1302_SetTime(unchar Address, unchar Value);  //设置时间函数
extern void DS1302_Initial (void);                         //DS1302初始化
extern void DS1302_GetTime(SYSTEMTIME *Time);              //读出时间
extern void DateToStr(SYSTEMTIME *Time);                   //日期转化成字符
extern void TimeToStr(SYSTEMTIME *Time);                   //时间转化成字符
 
 
 
 
MAIN函数部分:
 
#include "SYSTEM.H"
SYSTEMTIME CurrentTime;
 
unsigned char k = 0; //键值
unsigned char K1,K2,K3,M1,M2,M3,K1J,K2J,K3J,K4J; //键值
unsigned char Set; //调整值
char Set_Mode = 0;
 
void Keysan(void);
void delay200ms(void);
//主函数
void main(void)
 lcd_init();
 //lcd_sef_chr(); //写入自定义字符号
 DS1302_Initial();
 
  lcd_pos(0,0);
  prints("Date:");
  lcd_pos(0,1);
     prints("Time:");
 k = 6;  //不改变时间 
    while(1)
 {
   Keysan();
     DS1302_GetTime(&CurrentTime);
  DateToStr(&CurrentTime);
  TimeToStr(&CurrentTime);  
  lcd_pos(6,0);
  prints(CurrentTime.DateString);
  lcd_pos(6,1);
  prints(CurrentTime.TimeString);
 
  //lcd_pos(7,0);
     //lcd_wcmd(0x0E);
 
  delay200ms();
  
 }
}
 
//键盘扫描
void Keysan(void)
{
 
    if(~P1_2&K1J)   { k++;  }
   K1J=~(~P1_2);
 
    if(~P1_3&K2J)    { Set++; }
    K2J=~(~P1_3);
 
 if(~P1_4&K3J)    { Set--; }
   K3J=~(~P1_4);
 
    if(k == 7) {k = 0; }
 
 switch(k)
 {
   case 0: DS1302_SetTime(DS1302_SECOND, Set&0x3f); break;
   case 1: DS1302_SetTime(DS1302_MINUTE, Set&0x3f); break;
   case 2: DS1302_SetTime(DS1302_HOUR  , Set&0x1f); break;
   case 3: DS1302_SetTime(DS1302_DAY   , Set&0x0f); break;
   case 4: DS1302_SetTime(DS1302_MONTH , Set&0x0f); break;
   case 5: DS1302_SetTime(DS1302_YEAR  , Set&0x7f); break;
   default: break;
 }
}
//延时200000+0us 函数定义
void delay200ms(void)
{
   unsigned char i,j,k;
   for(i=201;i>0;i--)
   for(j=32;j>0;j--)
   for(k=14;k>0;k--);
}
 
关键字:单片机  DS1302  DS1602  电子时钟 引用地址:基于单片机、DS1302、DS1602的电子时钟

上一篇:红外遥控器单片机编码程序加详解
下一篇:Cortex-M3 .s文启动文件分析

推荐阅读最新更新时间:2024-03-16 13:50

基于STM32单片机的DMD投影仪的驱动电路的设计
DLP投影技术是应用美国德州仪器公司开发的数字微镜元件——DMD(Digital Micromirror Device)作为主要关键处理元件以实现数字光学处理过程的技术。DLP显示的色彩清晰度高、艳丽、细腻、逼真,且为全数字显示即可靠性极高,能在各类产品(如大屏幕数字电视、公司/家庭/专业会议投影机和数码相机(DLP Cinema))中提供最佳图像效果。目前,大部分的家用或商用DLP投影机都采用了单片结构,使得其便于移动携带,因而得到越来越广泛的应用。在目前应用发展的基础上,又对其结构的精简性、携带的方便性提出了更高的要求。传统的DLP投影仪是通过DVI接口接收外部信号,并且经过信号转换传送给DLP控制器来控制DLP的显示,占用的
[单片机]
基于STM32<font color='red'>单片机</font>的DMD投影仪的驱动电路的设计
基于51单片机的CAN总线系统设计
0 引言 随着20世纪80年代初期德国Bosch公司提出CAN(Controller Area Network)总线,即控制器局域网方案以解决汽车控制装置问的通信问题。经过20多年的发展,CAN总线现在广泛的应用在汽车领域,在汽车控制系统中应用CAN总线可以使硬件方案的软件化实现,大大地简化了设计,减小了硬件成本和设计生产成本,数据共享减少了数据的重复处理,节省了成本,可以将信号线减到最少,减少布线,使成本进一步降低等优点。由于CAN总线通信的高性能、高可靠性、及独特的设计和适宜的价格可以广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域,所以被公认为是几种最有前途的现场总线之一。 1 系统总体设计 CAN
[单片机]
基于51<font color='red'>单片机</font>的CAN总线系统设计
冰箱压缩机设计使用数字信号控制器实现高能效等级
冰箱和其他厨房电器由于对能源的高需求,对离网能源系统提出了严峻挑战。现在,改进的冰箱压缩机由无刷直流电动机或永磁同步电动机(PMSM)驱动,以满足高能效等级。通过为无刷电机使用基于逆变器的变速驱动器,可以实现这种高能效。 老一代冰箱使用的是单相感应电动机,这种电动机不能自启动。通过添加辅助绕组或极点阴影来解决此问题。但是,这两种方法在启动后都浪费了能量,因为它们没有其他用途。 ACIM电动机的另一个挑战是转矩输出在达到目标速度之前非常低。 另一方面,基于PMSM的压缩机非常高效且运行安静得多。当您确实需要时,它们还可以在启动和低速时提供更大的扭矩。由于这些原因,PMSM或内置永磁体(IPM)电动机正成为新冰箱的首选解决方案
[家用电子]
冰箱压缩机设计使用数字信号控制器实现高能效等级
单片机上电复位时间
单片机及其应用电路每次上电的过程中,由于电源回路中通常存在一些容量大小不等的滤波电容,使得单片机芯片在其电源引脚VCC和VSS之间所感受到的电源电压值VDD,是从低到高逐渐上升的。该过程所持续的时间一般为1~100 ms(记作taddrise)。上电延时taddrise的定义是电源电压从10% VDD上升到90% VDD所需的时间.在单片机电源电压上升到适合内部振荡电路运行的范围并且稳定下来之后,时钟振荡器开始了启动过程(具体包括偏置、起振、锁定和稳定几个过程)。该过程所持续的时间一般为1~50 ms(记作tosc)。起振延时tosc的定义是时钟振荡器输出信号的高电平达到Vih1所需的时间。从图1所示的实际测量图中也可以看得很清楚
[单片机]
<font color='red'>单片机</font>上电复位时间
基于51单片机的智能灯光控制系统设计
一.系统概述 系统使用的模块有AT89C51单片机+LCD1602显示屏+光敏电阻模块+ADC0832+小灯。 本设计采用51单片机为核心控制,使用LCD1602显示采集到的关照强度,光照强度以模拟电压信号的形式进行展现,通过ADC将模拟信号转换为数字电压信号,单片机会根据光强的电压信号值进行判定,如果光强电压值小于设置阈值则小灯就会被点亮。 二.仿真概述 1.通过LCD1602将数模转换后的光照强度电压信号值和阈值进行显示。 2.通过调节电位器来模拟光照强度的变化,光强的变化会在显示屏上表现出来。 3.当 检测 到光照强度低于设定阈值小灯就会亮起。 三.程序设计 使用 Keil 51进行程序设计,打开 Prot
[单片机]
基于51<font color='red'>单片机</font>的智能灯光控制系统设计
基于 SPCE061A单片机采集语音信号的设计与实现
随着单片机集成化程度的不断提高,现代单片机已经具备了数字信号处理功能,使语音信号处理用单片机实现成为可能。台湾凌阳科技公司(SunPlus)推出的一款SPCE061A就是这样的产品。SPCE061A是以μ nSP TM16位微控制器及信号处理器芯片为内核的16位单片机,采用模块式集成结构,片内集成了2KB RAM、32KB Flash、ADC、DAC、并行I/O等,特别适合语音信号处理。本文介绍如何实现用SPCE061A单片机采集语音信号,并传送到PC机中的方法。 1 硬件系统结构 1.1 SPCE061A结构 SPCE061A的内部结构如图1,其特点如下: *16位μ nSP TM微控制器; *工作电
[单片机]
基于单片机的心肺听诊技能训练系统设计方案
  随着社会的发展, 医疗体制的改革, 媒体的宣传, 民众的法律意识大大加强, 一系列医疗法规的出台, 进一步明确了病人的各项权益。病人, 这一以往传统医学教学的主体更多的选择拒绝配合教学工作。   而近年来医疗纠纷的增多与医患关系的紧张, 出于自身利益的考虑, 医院的教学性能不断削弱。医学院校在临床医学教育中的常规模式是: 理论教学+ 单项技能训练-- 见习--临床实习。但由于种种原因, 见习不能有效开展, 从而导致“理论教学+ 单项技能训练”这一教学模式的形成。基于以上现实情况, 医学院校内教学的尴尬局面迫切需要改变。将“ 模拟教学”引入校内教学流程, 形成“理论教学+ 单项技能训练——模拟教学——临床实习”新型的临床医学教
[单片机]
基于<font color='red'>单片机</font>的心肺听诊技能训练系统设计方案
51单片机-分钟秒表
数码管的基础知识已经讲解的差不多了,我们做道题目来结束本章的学习内容。 1.题目要求 开发板上电瞬间需要做到如下图的“0.00”所示 右边两个数码管用来做60秒计时,带小数点显示的数码管用来做一分钟过后的累加,当还没到达10分钟时,最左端的数码管(也就是数码管3)不允许亮,计时到“59.59”之后再过一秒就要变为“0.00”。 2.程序分析 同样我们需要定义Second用来做秒数自增的变量,分钟的累加也需要一个Minute变量。 当Second等于60的瞬间,需要“Second=0; Minute++;” 同理当Minute等于60的瞬间,需要“Minute=0;” 我们也知道开发板一上电就需要三个数码管一起点亮,所以
[单片机]
51<font color='red'>单片机</font>-分钟秒表
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved